package com.agent.management.service.impl;

import com.agent.management.common.exception.BusinessException;
import com.agent.management.model.entity.AgentTemplate;
import com.agent.management.repository.AgentTemplateRepository;
import com.agent.management.service.AgentTemplateService;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

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

@Slf4j
@Service
@RequiredArgsConstructor
public class AgentTemplateServiceImpl implements AgentTemplateService {

    private final AgentTemplateRepository templateRepo;

    @Override
    public List<AgentTemplate> listAll() {
        return templateRepo.findAllOrderBySort();
    }

    @Override
    public List<AgentTemplate> listEnabled() {
        return templateRepo.findAllOrderBySort().stream()
                .filter(t -> t.getEnabled() == null || t.getEnabled())
                .collect(Collectors.toList());
    }

    @Override
    public AgentTemplate getById(Long id) {
        return templateRepo.findById(id)
                .orElseThrow(() -> new BusinessException("模板不存在"));
    }

    @Override
    public AgentTemplate create(AgentTemplate template) {
        if (template.getName() == null || template.getName().trim().isEmpty()) {
            throw new BusinessException("模板名称不能为空");
        }
        if (template.getMode() == null || template.getMode().trim().isEmpty()) {
            template.setMode("custom");
        }
        if (template.getGraphData() == null || template.getGraphData().trim().isEmpty()) {
            template.setGraphData("{\"nodes\":[],\"edges\":[]}");
        }
        if (template.getSortOrder() == null) {
            // 新模板默认排在最后
            int maxOrder = templateRepo.findAllOrderBySort().stream()
                    .mapToInt(t -> t.getSortOrder() == null ? 0 : t.getSortOrder())
                    .max().orElse(0);
            template.setSortOrder(maxOrder + 10);
        }
        if (template.getEnabled() == null) template.setEnabled(true);
        if (template.getIsSystem() == null) template.setIsSystem(false);
        template.onCreate();
        return templateRepo.save(template);
    }

    @Override
    public AgentTemplate update(Long id, AgentTemplate req) {
        AgentTemplate tpl = getById(id);
        if (req.getName() != null) tpl.setName(req.getName());
        if (req.getDescription() != null) tpl.setDescription(req.getDescription());
        if (req.getMode() != null) tpl.setMode(req.getMode());
        if (req.getGraphData() != null) tpl.setGraphData(req.getGraphData());
        if (req.getIcon() != null) tpl.setIcon(req.getIcon());
        if (req.getSortOrder() != null) tpl.setSortOrder(req.getSortOrder());
        if (req.getEnabled() != null) tpl.setEnabled(req.getEnabled());
        // isSystem 不允许通过 update 改变
        tpl.onUpdate();
        return templateRepo.save(tpl);
    }

    @Override
    public void delete(Long id) {
        AgentTemplate tpl = getById(id);
        if (Boolean.TRUE.equals(tpl.getIsSystem())) {
            throw new BusinessException("系统内置模板不可删除，可禁用");
        }
        templateRepo.deleteById(id);
    }

    /**
     * 启动时若 agent-templates.json 不存在或为空，写入 3 个内置模板。
     * 幂等：仅在 count()==0 时执行。
     */
    @PostConstruct
    public void initSystemTemplates() {
        if (templateRepo.count() > 0) {
            return;
        }
        log.info("[AgentTemplate] 初始化内置模板...");
        create(blankTemplate());
        create(workflowTemplate());
        create(naturalLanguageTemplate());
        log.info("[AgentTemplate] 内置模板初始化完成，共 {} 个", templateRepo.count());
    }

    private AgentTemplate blankTemplate() {
        AgentTemplate t = new AgentTemplate();
        t.setName("空白模式");
        t.setDescription("从零开始自由编排工作流");
        t.setMode("blank");
        t.setIcon("📂");
        t.setSortOrder(10);
        t.setEnabled(true);
        t.setIsSystem(true);
        t.setGraphData("{\"nodes\":[],\"edges\":[]}");
        return t;
    }

    private AgentTemplate workflowTemplate() {
        AgentTemplate t = new AgentTemplate();
        t.setName("工作流编辑模式");
        t.setDescription("用户输入 → 大模型处理 → 输出 的基础工作流示例");
        t.setMode("workflow");
        t.setIcon("🔗");
        t.setSortOrder(20);
        t.setEnabled(true);
        t.setIsSystem(true);
        t.setGraphData(WORKFLOW_TEMPLATE_GRAPH);
        return t;
    }

    private AgentTemplate naturalLanguageTemplate() {
        AgentTemplate t = new AgentTemplate();
        t.setName("自然语言编辑模式");
        t.setDescription("通过自然语言描述需求，由 LLM 设计工作流方案");
        t.setMode("naturalLanguage");
        t.setIcon("💬");
        t.setSortOrder(30);
        t.setEnabled(true);
        t.setIsSystem(true);
        t.setGraphData(NATURAL_LANGUAGE_TEMPLATE_GRAPH);
        return t;
    }

    private static final String WORKFLOW_TEMPLATE_GRAPH = """
            {"nodes":[
              {"id":"n1","type":"userInput","position":{"x":50,"y":200},"data":{"label":"用户输入","variables":[]}},
              {"id":"n2","type":"llm","position":{"x":350,"y":200},"data":{"label":"大模型处理","modelId":null,"systemPrompt":"你是一个有帮助的助手。","userPrompt":"请处理用户输入：{{userInput}}","inputs":[],"outputs":[{"name":"result","label":"LLM 输出","type":"string","description":""}],"failStrategy":"abort"}},
              {"id":"n3","type":"output","position":{"x":650,"y":200},"data":{"label":"输出","fields":[{"name":"result","label":"输出结果","type":"string","description":""}]}}
            ],"edges":[
              {"id":"e1","source":"n1","target":"n2","type":"bezier","animated":true},
              {"id":"e2","source":"n2","target":"n3","type":"bezier","animated":true}
            ]}""";

    private static final String NATURAL_LANGUAGE_TEMPLATE_GRAPH = """
            {"nodes":[
              {"id":"n1","type":"userInput","position":{"x":50,"y":200},"data":{"label":"需求描述","variables":[]}},
              {"id":"n2","type":"llm","position":{"x":400,"y":200},"data":{"label":"工作流设计师","modelId":null,"systemPrompt":"你是一个工作流设计师。根据用户的自然语言描述，设计一个完整的工作流方案。请详细规划每个步骤、需要调用的技能和大模型、以及它们之间的依赖关系，输出结构化的设计方案。","userPrompt":"用户需求：{{userInput}}","inputs":[],"outputs":[{"name":"plan","label":"工作流方案","type":"string","description":"节点规划方案"}],"failStrategy":"abort"}},
              {"id":"n3","type":"output","position":{"x":750,"y":200},"data":{"label":"方案输出","fields":[{"name":"plan","label":"工作流方案","type":"string","description":""}]}}
            ],"edges":[
              {"id":"e1","source":"n1","target":"n2","type":"bezier","animated":true},
              {"id":"e2","source":"n2","target":"n3","type":"bezier","animated":true}
            ]}""";
}
