package tech.easyflow.agent.service.impl;

import com.mybatisflex.core.query.QueryWrapper;
import org.springframework.stereotype.Component;
import tech.easyflow.agent.entity.Agent;
import tech.easyflow.agent.entity.AgentSkillBinding;
import tech.easyflow.agent.service.AgentService;
import tech.easyflow.agent.service.AgentSkillBindingService;
import tech.easyflow.skill.service.SkillReferenceProvider;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Agent 草稿和有效发布快照中的 Skill 引用提供者。
 */
@Component
public class AgentSkillReferenceProvider implements SkillReferenceProvider {

    private final AgentService agentService;
    private final AgentSkillBindingService bindingService;

    /**
     * 创建引用提供者。
     *
     * @param agentService Agent 服务
     * @param bindingService Agent Skill 绑定服务
     */
    public AgentSkillReferenceProvider(AgentService agentService,
                                       AgentSkillBindingService bindingService) {
        this.agentService = agentService;
        this.bindingService = bindingService;
    }

    /** {@inheritDoc} */
    @Override
    public List<String> listReferences(BigInteger skillId) {
        Set<BigInteger> ids = new LinkedHashSet<>();
        for (AgentSkillBinding binding : bindingService.list(QueryWrapper.create()
                .eq(AgentSkillBinding::getSkillId, skillId))) {
            ids.add(binding.getAgentId());
        }
        for (Agent agent : agentService.list(QueryWrapper.create()
                .select(Agent::getId, Agent::getPublishedSnapshotJson)
                .isNotNull(Agent::getPublishedSnapshotJson))) {
            if (containsSkill(agent.getPublishedSnapshotJson(), skillId)) {
                ids.add(agent.getId());
            }
        }
        List<String> result = new ArrayList<>();
        for (Agent agent : agentService.listByIds(ids)) {
            result.add("智能体“" + (agent.getName() == null ? "未命名智能体" : agent.getName()) + "”");
        }
        return result;
    }

    private boolean containsSkill(Map<String, Object> snapshot, BigInteger skillId) {
        Object raw = snapshot == null ? null : snapshot.get("skillBindings");
        if (!(raw instanceof List<?> bindings)) {
            return false;
        }
        return bindings.stream().anyMatch(item -> item instanceof Map<?, ?> binding
                && skillId.toString().equals(String.valueOf(binding.get("skillId"))));
    }
}
