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.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.List;

/**
 * @Author：Roger Wu
 * @name：oa_form
 * @Date：2025-05-06 20:36
 */
@Component
public class TraveReimbursementlFormFunction extends AbstractLargeModelFunction {

    @Resource
    private LLMService llmService;

    private final String MODEL = "ERNIE-3.5-8K-0205";

    private final String DESC = "该方法执行出差的报销表单申请";

    private final FunctionLLMConfig functionLLMConfig = new FunctionLLMConfig.FunctionLLMConfigBuilder()
            .name("completion_of_travel_reimbursement_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）、出发日期（departureDate）、返回日期（returnDate）、交通工具（vehicle）、预计交通费用（transportationFee）、住宿地点（accommodation）、预计住宿费用\n" +
            "（accommodationCost）、预支金额（advancePaymentAmount）、总预算（totalBudget）\n" +
            "②查询系统今天的日期，今天日期是：[2025-4-30]\n" +
            "③遍历我给你的数据，从数据中提取关键词，将与字段匹配的关键词填充到字段名称后，例如：我要到香港出差，则将“香港”提取出来填充到出差地点里。\n" +
            "注意：\n" +
            "（1）用户有提到如“今天、明天、后天、昨天”这类，你要把它们提取出来根据给的今天日期转换为具体日期。例如：我今天要去香港出差五天，则你要提取出今天和五天，把今天和五天转换为具体日期，填充到出发日期和返回日期里\n" +
            "（2）匹配要使用英文字段，不能用中文\n" +
            "（3）数据中有明确与字段匹配的关键词再输出字段，否则不要输出多余字段，不要按照自己想法输出，尤其是出差目的\n" +
            "（4）若数据中有出差目的匹配的关键词，要从三个选择中选择一个\n" +
            "③使用JSON格式将有内容的字段名称输出\n" +
            "\n" +
            "3.输出示例：\n" +
            "数据：我今天要到香港出差\n" +
            "正确输出：\n" +
            "{\"place\":\"香港\",\n" +
            "\"departureDate\":\"2025-4-30\"}\n" +
            "\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) {
        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));

        LargeModelResponse largeModelResponse = new LargeModelResponse();
        largeModelResponse.setModel(MODEL);
        largeModelResponse.setMessages(new Message[]{message});
        largeModelResponse.setStream(false);
        largeModelResponse.setUser("traveReimbursementlFormFunction");
        LargeModelDemandResult largeModelDemandResult = llmService.chat(largeModelResponse);
        if (largeModelDemandResult == null) {
            result.setFunctionResult(StringUtils.EMPTY);
            result.setPromptContent(StringUtils.EMPTY);
            return result;
        }

        result.setFunctionResult(largeModelDemandResult.getMessage());
        result.setPromptContent(largeModelDemandResult.getMessage());
        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();
    }
}
