package com.infoepoch.pms.agent.platform.agent.application;

import com.infoepoch.pms.agent.platform.agent.domain.Agent;
import com.infoepoch.pms.agent.platform.agent.domain.irepository.IAgentRepository;
import com.infoepoch.pms.agent.platform.model.application.ModelQueryService;
import com.infoepoch.pms.agent.platform.shared.exception.BusinessException;
import com.infoepoch.pms.agent.platform.shared.response.ResultCode;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 智能体查询服务。
 */
@Service
@RequiredArgsConstructor
public class AgentQueryService {

    private final IAgentRepository agentRepository;
    private final ModelQueryService modelQueryService;

    /**
     * 按 ID 集合查询所有已启用的智能体。
     *
     * @param ids 智能体 ID 集合
     * @return 已启用的智能体列表
     * @throws BusinessException PARAM_ERROR 若包含空 ID；AGENT_NOT_FOUND 若存在不存在或已禁用的智能体
     */
    @Transactional(readOnly = true)
    public List<Agent> findEnabledByIds(Set<String> ids) {
        if (ids == null || ids.isEmpty()) {
            return Collections.emptyList();
        }
        if (ids.stream().anyMatch(Objects::isNull)) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "子智能体 ID 不能为空");
        }
        LinkedHashSet<String> uniqueIds = new LinkedHashSet<>(ids);
        List<Agent> agents = agentRepository.findByIdInAndEnabledTrue(uniqueIds);
        if (agents.size() != uniqueIds.size()) {
            throw new BusinessException(ResultCode.AGENT_NOT_FOUND, "存在不存在或已禁用的子智能体");
        }
        return agents.stream()
                .map(this::attachRelations)
                .toList();
    }

    @Transactional(readOnly = true)
    public Optional<Agent> findById(String id) {
        return agentRepository.findById(id).map(this::attachRelations);
    }

    private Agent attachRelations(Agent agent) {
        if (agent == null) {
            return null;
        }
        agent.setModelConfig(modelQueryService.getModelConfigOrNull(agent.getModelConfigId()));
        return agent;
    }
}
