package tech.easyflow.ai.chattime.availability;

import org.springframework.stereotype.Service;
import tech.easyflow.common.web.exceptions.BusinessException;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 聊天时工具可用性编排服务实现。
 */
@Service
public class ChatTimeToolAvailabilityServiceImpl implements ChatTimeToolAvailabilityService {

    private final List<ChatTimeToolAvailabilityResolver> resolvers;

    public ChatTimeToolAvailabilityServiceImpl(List<ChatTimeToolAvailabilityResolver> resolvers) {
        this.resolvers = resolvers == null ? Collections.emptyList() : resolvers;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ChatTimeToolAvailabilityDecision evaluate(ChatTimeToolAvailabilityContext context, Object candidate) {
        if (candidate == null) {
            return ChatTimeToolAvailabilityDecision.unavailable("TOOL_CANDIDATE_MISSING", "聊天工具候选项不存在");
        }
        for (ChatTimeToolAvailabilityResolver resolver : resolvers) {
            if (resolver.supports(candidate)) {
                return resolver.resolve(context, candidate);
            }
        }
        return ChatTimeToolAvailabilityDecision.unavailable("TOOL_RESOLVER_MISSING", "当前聊天工具缺少可用性判定器");
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public <T> List<T> filterAvailable(ChatTimeToolAvailabilityContext context, List<T> candidates) {
        if (candidates == null || candidates.isEmpty()) {
            return Collections.emptyList();
        }
        return candidates.stream()
                .filter(Objects::nonNull)
                .filter(candidate -> evaluate(context, candidate).isAvailable())
                .collect(Collectors.toList());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void assertAvailable(ChatTimeToolAvailabilityContext context, Object candidate, String fallbackMessage) {
        ChatTimeToolAvailabilityDecision decision = evaluate(context, candidate);
        if (decision.isAvailable()) {
            return;
        }
        String message = decision.getReasonMessage();
        if (message == null || message.isBlank()) {
            message = fallbackMessage;
        }
        throw new BusinessException(message == null || message.isBlank() ? "当前聊天工具不可用" : message);
    }
}
