package cn.com.poc.thirdparty.resource.demand.ai.function.chart_data_convert;

import cn.com.poc.agent_application.entity.KnowledgeContentResult;
import cn.com.poc.agent_application.entity.Variable;
import cn.com.poc.common.utils.JsonUtils;
import cn.com.poc.common.utils.StringUtils;
import cn.com.poc.thirdparty.resource.demand.ai.entity.dbchain.DBChainResult;
import cn.com.poc.thirdparty.resource.demand.ai.entity.dialogue.Message;
import cn.com.poc.thirdparty.resource.demand.ai.entity.largemodel.LargeModelDemandResult;
import cn.com.poc.thirdparty.resource.demand.ai.entity.largemodel.LargeModelResponse;
import cn.com.poc.thirdparty.resource.demand.ai.function.AbstractFunctionResult;
import cn.com.poc.thirdparty.resource.demand.ai.function.AbstractLargeModelFunction;
import cn.com.poc.thirdparty.resource.demand.ai.function.entity.FunctionLLMConfig;
import cn.com.poc.thirdparty.resource.demand.ai.function.entity.Parameters;
import cn.com.poc.thirdparty.resource.demand.ai.function.entity.Properties;
import cn.com.poc.thirdparty.service.LLMService;
import cn.com.yict.framemax.core.exception.BusinessException;
import cn.hutool.core.collection.ListUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;

/**
 * Chart数据转成
 *
 * @author alex.yao
 * @date 2025/9/2
 */
@Component
public class ChartDataConvertFunction extends AbstractLargeModelFunction {

    private final Logger logger = LoggerFactory.getLogger(ChartDataConvertFunction.class);

    private final String MODEL = "deepseek-v3";

    private final String PROMPT = "## 任务\n" +
            "将现有数据转化成可供 EChart 使用的数据，仅需要处理X轴与Y轴。\n" +
            "\n" +
            "## 输出\n" +
            "1. 字段 xData 用于放入x轴的数据,并且数据应为字符串类型，如 xData:[\"1月\",\"2月\",\"3月\"]\n" +
            "2. 字段 yData 用于放入y轴的数据,并且数据应为字符串类型，如 yData:[\"12\",\"34\",\"47\"]\n" +
            "3. 字段 title 用于存放该图表的标题\n" +
            "4. 若现有数据无法生成图表，则输出 {\"skip\":true} , 表示跳过，无法生成图表数据\n" +
            "\n" +
            "## 例子\n" +
            "{\"xData\":[\"1月\",\"2月\",\"3月\"],  yData:[\"12\",\"34\",\"47\"],\"title\":\"第一季度销售额\"}\n" +
            "\n" +
            "## 用户问题\n" +
            "{question}\n" +
            "\n" +
            "## 数据\n" +
            "{data}";

    private final String DESC = "根据用户问题和现有数据生成图表可用数据";

    private final FunctionLLMConfig functionLLMConfig = new FunctionLLMConfig.FunctionLLMConfigBuilder()
            .name("chart_data_generate")
            .description(DESC)
            .parameters(new Parameters("object")
                    .addProperties("data", new Properties("string", "参考数据"))
                    .addProperties("question", new Properties("string", "用户问题优化后的问题")))
            .build();

    @Resource
    private LLMService llmService;

    @Override
    public AbstractFunctionResult<ChartData> doFunction(String content, String identifier, List<DBChainResult> dbChainResults, List<KnowledgeContentResult> knowledgeContentResults) {
        AbstractFunctionResult<ChartData> result = new AbstractFunctionResult<>();
        result.setFunctionResult(null);
        result.setPromptContent(StringUtils.EMPTY);
        if (StringUtils.isBlank(content)) {
            return result;
        }
        JSONObject jsonObject = JSON.parseObject(content);
        if (!jsonObject.containsKey("question") || !jsonObject.containsKey("data")) {
            logger.warn("缺少必要参数,无法生成图表数据,content:{}", content);
            return result;
        }
        Message systemMessage = new Message();
        systemMessage.setRole("system");
        systemMessage.setContent(buildPrompt(jsonObject));

        Message userMessage = new Message();
        userMessage.setContent("invoke");
        userMessage.setRole("user");
        Message[] messages = new Message[]{systemMessage, userMessage};
        LargeModelResponse largeModelResponse = new LargeModelResponse();
        largeModelResponse.setMessages(messages);
        largeModelResponse.setModel(MODEL);
        LargeModelDemandResult largeModelDemandResult = llmService.chat(largeModelResponse);
        if (largeModelDemandResult == null || StringUtils.isBlank(largeModelDemandResult.getMessage())) {
            logger.error("-----------------LLM 执行失败----------------");
            return result;
        }

        String message = largeModelDemandResult.getMessage();
        int startEnd = message.indexOf("{");
        int endIndex = message.lastIndexOf("}");
        if (startEnd == -1 || endIndex == -1) {
            logger.error("---------------解析内容失败, message:{}--------------", message);
            throw new BusinessException("解析内容失败");
        }
        ChartData chartData = JsonUtils.deSerialize(message.substring(startEnd, endIndex + 1), ChartData.class);
        result.setFunctionResult(chartData);
        result.setPromptContent(JsonUtils.serialize(chartData));
        return result;
    }

    @Override
    public String getDesc() {
        return DESC;
    }

    @Override
    public List<String> getLLMConfig() {
        return ListUtil.toList(JsonUtils.serialize(functionLLMConfig));
    }

    @Override
    public List<String> getLLMConfig(List<Variable> variableStructure) {
        return getLLMConfig();
    }

    private String buildPrompt(JSONObject jsonObject) {

        String data = StringUtils.EMPTY;
        String question = StringUtils.EMPTY;

        if (jsonObject.containsKey("data")) {
            data = jsonObject.getString("data");
        }
        if (jsonObject.containsKey("question")) {
            question = jsonObject.getString("question");
        }

        return PROMPT.replace("${question}", question)
                .replace("{data}", data);
    }
}
