package com.pavis.admin.aigc.service.impl;

import com.pavis.admin.aigc.core.agent.planner.PlanContext;
import com.pavis.admin.aigc.core.agent.tool.PlanningTool;
import com.pavis.admin.aigc.core.llm.LlmService;
import com.pavis.admin.aigc.mapper.AgentPlanMapper;
import com.pavis.admin.aigc.model.entity.AgentPlanDO;
import com.pavis.admin.aigc.model.query.AgentPlanQuery;
import com.pavis.admin.aigc.model.query.AgentQuery;
import com.pavis.admin.aigc.model.req.AgentPlanReq;
import com.pavis.admin.aigc.model.resp.AgentPlanDetailResp;
import com.pavis.admin.aigc.model.resp.AgentPlanResp;
import com.pavis.admin.aigc.model.resp.AgentResp;
import com.pavis.admin.aigc.service.AgentPlanService;
import com.pavis.admin.aigc.service.AgentService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.stereotype.Service;
import top.continew.starter.extension.crud.model.query.SortQuery;
import top.continew.starter.extension.crud.service.BaseServiceImpl;

import java.util.List;

/**
 * 智能体规划记录业务实现
 *
 * @author semi
 * @since 2025/05/28 16:59
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AgentPlanServiceImpl extends BaseServiceImpl<AgentPlanMapper, AgentPlanDO, AgentPlanResp, AgentPlanDetailResp, AgentPlanQuery, AgentPlanReq> implements AgentPlanService {

    private final LlmService llmService;

    private final AgentService agentService;

    @Override
    public PlanContext createPlan(PlanContext context) {
        Long planId = context.getPlanId();
        if (planId == null) {
            throw new IllegalArgumentException("Plan ID cannot be null or empty");
        }
        try {
            // 构建所有智能体信息
            String agentsInfo = buildAgentsInfo();
            AgentPlanResp currentPlan = null;
            // 生成计划提示
            String planPrompt = generatePlanPrompt(context.getUserMessage(), agentsInfo, planId);
            // 使用 LLM 生成计划
            PromptTemplate promptTemplate = new PromptTemplate(planPrompt);
            Prompt prompt = promptTemplate.create();

            // 创建 规划工具 PlanningTool
            PlanningTool planningTool = new PlanningTool();

            ChatClient.CallResponseSpec response = llmService.getPlanningChatClient()
                    .prompt(prompt)
                    .toolCallbacks(List.of(planningTool.getFunctionToolCallback()))
                    .advisors(memoryAdvisor -> memoryAdvisor.param("chat_memory_conversation_id", context.getConversationId())
                            .param("chat_memory_retrieve_size", 100))
                    .call();
            String outputText = response.chatResponse().getResult().getOutput().getText();
            // 检查计划是否创建成功
            if (planId.equals(planningTool.getCurrentPlanId())) {
                currentPlan = planningTool.getCurrentPlan();
                log.info("Plan created successfully: {}", currentPlan);
                currentPlan.setThink_input(planPrompt);
                currentPlan.setThink_output(outputText);
            }
            context.setPlan(currentPlan);

        } catch (Exception e) {
            log.error("Error creating plan for request: {}", context.getUserMessage(), e);
            // 处理异常情况
            throw new RuntimeException("Failed to create plan", e);
        }
        return context;
    }

    @Override
    public PlanContext executePlan(PlanContext context) {
        return null;
    }

    /**
     * 构建智能体信息，用于生成提示词
     *
     * @return 智能体信息描述
     */
    public String buildAgentsInfo() {
        AgentQuery query = new AgentQuery();
        query.setStatus(1);
        SortQuery sortQuery = new SortQuery();
        List<AgentResp> agents = agentService.list(query, sortQuery);
        StringBuilder agentsInfo = new StringBuilder("Available Agents:\n");
        if (agents != null && !agents.isEmpty()) {
            for (AgentResp agent : agents) {
                agentsInfo.append("- Agent Name: ")
                        .append(agent.getName())
                        .append("\n  Description: ")
                        .append(agent.getDescription())
                        .append("\n");
            }
        }
        return agentsInfo.toString();
    }

    /**
     * 生成计划提示
     *
     * @param userMessage 用户请求
     * @param agentsInfo  代理信息
     * @param planId      计划ID
     * @return 格式化的提示字符串
     */
    private String generatePlanPrompt(String userMessage, String agentsInfo, Long planId) {
        return """
                ## 介绍
                我是一个AI助手，旨在帮助用户完成各种任务。我的设计目标是提供帮助、信息和多方面的支持。
                
                ## 目标
                我的主要目标是通过提供信息、执行任务和提供指导来帮助用户实现他们的目标。我致力于成为问题解决和任务完成的可靠伙伴。
                
                ## 我的任务处理方法
                当面对任务时，我通常会：
                1. 分析请求以理解需求
                2. 将复杂问题分解为可管理的步骤
                3. 为每个步骤使用适当的AGENT
                4. 以有帮助和有组织的方式交付结果
                
                ## 当前主要目标：
                创建一个合理的计划，包含清晰的步骤来完成任务。
                
                ## 可用代理信息：
                %s
                
                # 需要完成的任务：
                %s
                
                你可以使用规划工具来帮助创建计划，使用 %s 作为计划ID。
                
                重要提示：计划中的每个步骤都必须以[AGENT]开头，代理名称必须是上述列出的可用代理之一。
                例如："[BROWSER_AGENT] 搜索相关信息" 或 "[DEFAULT_AGENT] 处理搜索结果"
                """.formatted(agentsInfo, userMessage, planId);
    }
}