package cn.com.poc.agent_application.utils;

import cn.com.poc.agent_application.entity.BizAgentApplicationDialoguesRecordEntity;
import cn.com.poc.agent_application.entity.CheckPluginUseEntity;
import cn.com.poc.agent_application.entity.Variable;
import cn.com.poc.agent_application.service.BizAgentApplicationDialoguesRecordService;
import cn.com.poc.common.constant.CommonConstant;
import cn.com.poc.common.utils.DocumentLoad;
import cn.com.poc.common.utils.JsonUtils;
import cn.com.poc.common.utils.SpringUtils;
import cn.com.poc.thirdparty.resource.demand.ai.constants.LLMRoleEnum;
import cn.com.poc.thirdparty.resource.demand.ai.entity.dialogue.Message;
import cn.com.poc.thirdparty.resource.demand.ai.entity.dialogue.Tool;
import cn.com.poc.thirdparty.resource.demand.ai.entity.function.FunctionCallResult;
import cn.com.poc.thirdparty.resource.demand.ai.function.LargeModelFunctionEnum;
import cn.com.poc.thirdparty.resource.demand.ai.function.memory_variable_writer.MemoryVariableWriter;
import cn.com.poc.thirdparty.service.LLMService;
import cn.com.yict.framemax.core.i18n.I18nMessageException;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author alex.yao
 * @description agent应用配置工具类
 */
public class AgentApplicationTools {

    /**
     * 构造Agent应用 函数配置
     *
     * @param variableStructures 记忆变量
     * @param isLongMemory       是否开启长期记忆
     * @param identifier         标识符
     * @param agentId            应用id
     * @param unitIds            插件id
     * @param isDocumentParsing  是否开启文档解析
     * @return
     */
    public static List<Tool> buildFunctionConfig(List<Variable> variableStructures, String isLongMemory, String identifier, String agentId, String[] unitIds, String isDocumentParsing) {
        List<Tool> tools = new ArrayList<>();
        //开启对话变量
        if (CollectionUtils.isNotEmpty(variableStructures)) {
            String functionName = LargeModelFunctionEnum.memory_variable_writer.name();
            String llmConfig = LargeModelFunctionEnum.valueOf(functionName).getFunction().getLLMConfig(variableStructures).get(0);
            Tool tool = JsonUtils.deSerialize(llmConfig, Tool.class);
            tools.add(tool);

            //初始化变量函数
            Map<Object, Object> map = MemoryVariableWriter.get(identifier(identifier, agentId));
            if (MapUtils.isEmpty(map)) {
                List<Variable> variableStructure = variableStructures;
                for (Variable variable : variableStructure) {
                    String key = variable.getKey();
                    String variableDefault = variable.getVariableDefault();
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("key", key);
                    jsonObject.put("value", variableDefault);
                    LargeModelFunctionEnum.valueOf(functionName).getFunction().doFunction(jsonObject.toJSONString(), identifier(identifier, agentId), null, null);
                }
            }
        }
        //开启长期记忆
        if (CommonConstant.YOrN.Y.equals(isLongMemory)) {
            String functionName = LargeModelFunctionEnum.set_long_memory.name();
            String llmConfig = LargeModelFunctionEnum.valueOf(functionName).getFunction().getLLMConfig().get(0);
            Tool tool = JsonUtils.deSerialize(llmConfig, Tool.class);
            tools.add(tool);
        }

        //开启文档解析-文档理解
        if (CommonConstant.YOrN.Y.equals(isDocumentParsing)) {
//            String functionName = LargeModelFunctionEnum.document_understanding.name();
//            String llmConfig = LargeModelFunctionEnum.valueOf(functionName).getFunction().getLLMConfig().get(0);
//            Tool tool = JsonUtils.deSerialize(llmConfig, Tool.class);
//            tools.add(tool);
        }

        //初始化插件函数
        if (ArrayUtils.isNotEmpty(unitIds)) {
            for (String unitId : unitIds) {
                LargeModelFunctionEnum modelFunctionEnum = LargeModelFunctionEnum.getFunction(unitId);
                if (modelFunctionEnum == null) {
                    continue;
                }
                String llmConfig = modelFunctionEnum.getFunction().getLLMConfig().get(0);
                Tool tool = JsonUtils.deSerialize(llmConfig, Tool.class);
                tools.add(tool);
            }
        }
        return tools;
    }

    /**
     * 创建会话唯一标识符
     *
     * @param dialogueId 对话ID
     * @param agentId    应用ID
     * @return
     */
    public static String identifier(String dialogueId, String agentId) {
        return dialogueId + ":" + agentId;
    }

    /**
     * 检查对话文件内容是否为空
     *
     * @throws I18nMessageException 文件内容为空时抛出异常
     */
    public static void checkDialogueContentIsEmpty(List<String> fileUrls) {
        // 判断文件是否为空，如果不为空
        if (CollectionUtils.isNotEmpty(fileUrls)) {
            for (String fileUrl : fileUrls) {
                File file = DocumentLoad.downloadURLDocument(fileUrl);
                String documentContent = DocumentLoad.documentToText(file);
                if (StringUtils.isBlank(documentContent)) {
                    throw new I18nMessageException("exception/file.content.empty");
                }
            }
        }
    }

    /**
     * 判断将会调用的插件-用于扣减积分
     */
    public static CheckPluginUseEntity checkPluginUse(List<Message> messages, List<Tool> tools, List<String> fileUrls) {
        CheckPluginUseEntity checkPluginUseEntity = new CheckPluginUseEntity();
        if (CollectionUtils.isEmpty(messages) || CollectionUtils.isEmpty(tools)) {
            return checkPluginUseEntity;
        }
        LLMService llmService = SpringUtils.getBean(LLMService.class);
        Object content = messages.get(messages.size() - 1).getContent();
        String query;
        if (content instanceof List) {
            query = ((List<HashMap>) content).get(0).get("text").toString();
        } else {
            query = content.toString();
        }
        query = "用户输入:" + query + "\n";
        if (CollectionUtils.isNotEmpty(fileUrls)) {
            query = query + "用户上传文件地址:" + JsonUtils.serialize(fileUrls) + "\n" + "文件格式:" + fileUrls.get(0).substring(fileUrls.get(0).lastIndexOf(".")) + "\n";
        } else {
            query = query + "用户上传文件地址:无\n" + "文件格式:无\n";
        }

        List<Tool> deductionTools = new ArrayList<>();
        FunctionCallResult functionCallResult = llmService.functionCall(query, tools.toArray(new Tool[0]));
        if (functionCallResult != null && functionCallResult.isNeed()) {
            for (Tool tool : tools) {
                if (tool.getFunction().getName().equals(functionCallResult.getFunctionCall().getName())) {
                    deductionTools.add(tool);
                    break;
                }
            }
        }
        checkPluginUseEntity.setDeductionTools(deductionTools);
        checkPluginUseEntity.setFunctionCallResult(functionCallResult);
        return checkPluginUseEntity;
    }


    public static List<Message> buildMessage(String dialogsId, String agentId, Long userId, String input) throws Exception {
        BizAgentApplicationDialoguesRecordService bizAgentApplicationDialoguesRecordService = SpringUtils.getBean(BizAgentApplicationDialoguesRecordService.class);
        List<Message> messages = new ArrayList<>();
        BizAgentApplicationDialoguesRecordEntity recordEntity = new BizAgentApplicationDialoguesRecordEntity();
        recordEntity.setDialogsId(dialogsId);
        recordEntity.setMemberId(userId);
        recordEntity.setAgentId(agentId);
        List<BizAgentApplicationDialoguesRecordEntity> recordEntities = bizAgentApplicationDialoguesRecordService.findByExample(recordEntity, null);
        if (CollectionUtils.isNotEmpty(recordEntities)) {
            for (BizAgentApplicationDialoguesRecordEntity entity : recordEntities) {
                Message message = new Message();
                message.setContent(entity.getContent());
                message.setRole(entity.getRole());
                messages.add(message);
            }
        }

        //判断最后是否为User，若是则删除。
        if (CollectionUtils.isNotEmpty(messages)) {
            if (LLMRoleEnum.USER.getRole().equals(messages.get(messages.size() - 1).getRole())) {
                Long recordId = recordEntities.get(recordEntities.size() - 1).getId();
                bizAgentApplicationDialoguesRecordService.deletedById(recordId);
                messages.remove(messages.size() - 1);
            }
        }

        // 用户输入
        Message message = new Message();
        message.setContent(input);
        message.setRole(LLMRoleEnum.USER.getRole());
        messages.add(message);
        return messages;
    }
}
