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

import cn.com.poc.agent_application.entity.KnowledgeContentResult;
import cn.com.poc.agent_application.entity.Variable;
import cn.com.poc.common.utils.DateUtils;
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.hutool.core.collection.ListUtil;
import org.springframework.stereotype.Component;

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

/**
 * @author alex.yao
 * @date 2025/6/24
 */
@Component
public class TravelFormV2Function extends AbstractLargeModelFunction {

    @Resource
    private LLMService llmService;

    private final String DESC = "该方法执行差旅表单申请";

    //    private final String MODEL = "ERNIE-3.5-8K-0205";
    private final String MODEL = "qwen-long";
    private final FunctionLLMConfig functionLLMConfig = new FunctionLLMConfig.FunctionLLMConfigBuilder()
            .name("completion_of_travel_v2_form")
            .parameters(new Parameters("object")
                    .addProperties("query", new Properties("string", "获取用户输入")))
            .description(DESC)
            .build();

    private final String TEMPLATE = "# 角色：\n" +
            "关键词提取助手\n" +
            "\n" +
            "## 工作规范：\n" +
            "1.严格遵守提取规则：\n" +
            "-仅从我给你的数据中提取关键词，不要添加任何外部信息\n" +
            "\n" +
            "2.精准匹配流程：\n" +
            "①熟知以下字段名称：出差目的（purpose）（选择：客户拜访、会议、培训）、出差地点（place）、回程地点（returnDestination）、出发日期和时间（departureDate）、返回日期和时间（returnDate）、" +
            "去路交通工具（vehicle）、去路预计交通费用（transportationFee）、回程交通工具（returnVehicle）、去路预计交通费用（returnTransportationFee）、" +
            "住宿地点（accommodation）、预计住宿费用（accommodationCost）、预支金额（advancePaymentAmount）、总预算（totalBudget）\n" +
            "②查询系统今天的日期，今天日期是：${nowday}" +
            "③遍历我给你的数据，从数据中提取关键词，将与字段匹配的关键词填充到字段名称后，例如：我要到香港出差，则将“香港”提取出来填充到出差地点里。\n" +
            "注意：\n" +
            "（1）用户有提到如“今天、明天、后天、昨天”这类，你要把它们提取出来根据给的今天日期转换为具体日期和时间。例如：我今天要去香港出差五天，则你要提取出今天和五天，把今天和五天转换为具体日期，填充到出发日期和返回日期里\n" +
            "（2）匹配要使用英文字段，不能用中文\n" +
            "（3）数据中有明确与字段匹配的关键词再输出字段，否则不要输出多余字段，不要按照自己想法输出，尤其是出差目的\n" +
            "（4）若数据中有出差目的匹配的关键词，要从三个选择中选择一个\n" +
            "③使用JSON格式将有内容的字段名称输出\n" +
            "\n" +
            "3.输出示例：\n" +
            "数据：我今天要到香港出差\n" +
            "正确输出：\n" +
            "{\"place\":\"香港\",\n" +
            "\"departureDate\":\"2025-4-30 12:00:00\"}\n" +
            "## 限制：\n" +
            "-数据中有与字段匹配的关键词再输出字段，否则不要输出\n" +
            "-输出必须用JSON格式，不能用其他格式输出\n" +
            "-全程只能做关键词提取工作，不做其他工作\n" +
            "-输出里不能有提示语任何相关内容\n" +
            "\n" +
            "## 输入数据：\n" +
            "数据：【${content}】";

    /**
     * 执行函数
     *
     * @param content                 入参
     * @param identifier              唯一标识
     * @param dbChainResults
     * @param knowledgeContentResults
     * @return
     */
    @Override
    public AbstractFunctionResult<String> doFunction(String content, String identifier, List<DBChainResult> dbChainResults, List<KnowledgeContentResult> knowledgeContentResults) {
//        content = "我今天要去北京出差，主要是去客户那边交流一下";
        AbstractFunctionResult<String> result = new AbstractFunctionResult<>();
        if (StringUtils.isBlank(content)) {
            result.setFunctionResult(StringUtils.EMPTY);
            result.setPromptContent(StringUtils.EMPTY);
            return result;
        }
        Message message = new Message();
        message.setRole("user");
        message.setContent(TEMPLATE.replace("${content}", content).replace("${nowday}", DateUtils.dateToString(new Date())));

        LargeModelResponse largeModelResponse = new LargeModelResponse();
        largeModelResponse.setModel(MODEL);
        largeModelResponse.setMessages(new Message[]{message});
        largeModelResponse.setStream(false);
        largeModelResponse.setUser("travelFormFunction");
        LargeModelDemandResult largeModelDemandResult = llmService.chat(largeModelResponse);
        if (largeModelDemandResult == null) {
            result.setFunctionResult(StringUtils.EMPTY);
            result.setPromptContent(StringUtils.EMPTY);
            return result;
        }
        String functionResult = largeModelDemandResult.getMessage().replace("`", "").replace("json", "").replace("\n", "");
        functionResult = functionResult.replace("客户拜访", "CustomerVisits").replace("会议", " Meetings").replace("培训", "Training");
        result.setFunctionResult(functionResult);
        result.setPromptContent(functionResult);
        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();
    }
}
