package cn.com.poc.portal.aggregate.impl;

import cn.com.poc.agent_application.aggregate.AgentApplicationService;
import cn.com.poc.agent_application.constant.AgentApplicationDialoguesRecordConstants;
import cn.com.poc.agent_application.entity.*;
import cn.com.poc.agent_application.service.BizAgentApplicationDialoguesRecordService;
import cn.com.poc.agent_application.service.BizAgentApplicationPublishService;
import cn.com.poc.agent_application.utils.AgentApplicationTools;
import cn.com.poc.ai_dialogues.entity.BizAiDialoguesEntity;
import cn.com.poc.ai_dialogues.service.BizAiDialoguesService;
import cn.com.poc.common.constant.CommonConstant;
import cn.com.poc.common.constant.FmxParamConfigConstant;
import cn.com.poc.common.utils.SSEUtil;
import cn.com.poc.common.utils.StringUtils;
import cn.com.poc.common.utils.UUIDTool;
import cn.com.poc.knowledge.aggregate.KnowledgeService;
import cn.com.poc.portal.aggregate.PortalService;
import cn.com.poc.portal.entity.BizPortalDialoguesEntity;
import cn.com.poc.portal.entity.PortalDialoguesCallEntity;
import cn.com.poc.portal.service.BizPortalDialoguesService;
import cn.com.poc.thirdparty.resource.demand.ai.constants.KnowledgeSearchTypeEnum;
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.yict.framemax.core.exception.BusinessException;
import cn.com.yict.framemax.frame.service.FmxParamConfigService;
import cn.hutool.core.collection.CollectionUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

/**
 * @author alex.yao
 * @date 2025/6/19
 */
@Service
public class PortalServiceImpl implements PortalService {

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

    private final String FMX_PARAM_AGENT_ID_CODE = "portal.agent_id";

    @Resource
    private FmxParamConfigService fmxParamConfigService;

    @Resource
    private BizAiDialoguesService bizAiDialoguesService;

    @Resource
    private AgentApplicationService agentApplicationService;

    @Resource
    private KnowledgeService knowledgeService;

    @Resource
    private BizAgentApplicationPublishService bizAgentApplicationPublishService;

    @Resource
    private BizAgentApplicationDialoguesRecordService bizAgentApplicationDialoguesRecordService;

    @Override
    public void call(PortalDialoguesCallEntity callEntity, Long userId) throws Exception {

        String agentId = fmxParamConfigService.getParam(FMX_PARAM_AGENT_ID_CODE);
        if (StringUtils.isBlank(agentId)) {
            logger.error("获取门户首页对话agentId失败");
            throw new BusinessException("对话异常");
        }

        // 获取Agent基本信息
        BizAgentApplicationPublishEntity infoEntity = bizAgentApplicationPublishService.getByAgentId(agentId);
        if (infoEntity == null) {
            logger.error("获取门户首页对话agent信息失败");
            throw new BusinessException("对话异常");
        }

        // 保存对话基础信息
        BizAiDialoguesEntity bizAiDialoguesEntity = new BizAiDialoguesEntity();
        bizAiDialoguesEntity.setMemberId(userId);
        bizAiDialoguesEntity.setDialoguesId(callEntity.getDialoguesId());
        bizAiDialoguesEntity.setIsDeleted(CommonConstant.IsDeleted.N);
        List<BizAiDialoguesEntity> bizAiDialoguesEntities = bizAiDialoguesService.findByExample(bizAiDialoguesEntity, null);
        if (CollectionUtils.isEmpty(bizAiDialoguesEntities)) {
            logger.error("dialogues id 不存在，请重新创建");
            throw new BusinessException("对话异常");
        }

        // 保存标题信息
        if (StringUtils.isBlank(bizAiDialoguesEntities.get(0).getTitle())) {
            BizAiDialoguesEntity portalDialoguesEntity = bizAiDialoguesEntities.get(0);
            portalDialoguesEntity.setTitle(callEntity.getInput());
            bizAiDialoguesService.update(portalDialoguesEntity);
        }

        // 获取对话配置
        String largeModel = callEntity.getEnableDeepThinking() ? "DeepSeek" : "DeepSeek-v3";//获取模型
        String agentSystem = infoEntity.getAgentSystem();//获取Agent角色词
        List<Integer> kdIds = knowledgeService.getKdIdsByKnowledgeInfoIds(callEntity.getKnowledgeIds());//获取知识库ids
        List<Message> messages = buildMessages(callEntity.getDialoguesId(), agentId, userId, callEntity.getInput());//构建消息
        List<Tool> tools;
        if (callEntity.getEnableSearchEngine()) {
            tools = AgentApplicationTools.buildFunctionConfig(infoEntity.getVariableStructure(), infoEntity.getIsLongMemory(), callEntity.getDialoguesId(), agentId, infoEntity.getUnitIds(), infoEntity.getIsDocumentParsing());//构建函数配置
        } else {
            tools = new ArrayList<>();
        }
        List<String> fileUrls = new ArrayList<>();//构建文件链接
        if (StringUtils.isNotBlank(callEntity.getFileUrl())) {
            fileUrls.add(callEntity.getFileUrl());
        }
        CheckPluginUseEntity checkPluginUseEntity = AgentApplicationTools.checkPluginUse(messages, tools, fileUrls);//检查插件使用
        FunctionCallResult functionCallResult = checkPluginUseEntity.getFunctionCallResult();//函数调用结果
        boolean stream = true;//是否流式输出
        KnowledgeSearchTypeEnum knowledgeSearchTypeEnum = KnowledgeSearchTypeEnum.valueOf(infoEntity.getKnowledgeSearchType());//知识库检索方式
        KnowledgeSuperclassProblemConfig knowledgeSuperclassProblemConfig = new KnowledgeSuperclassProblemConfig();//知识库超纲配置
        knowledgeSuperclassProblemConfig.setKnowledgeResponseType(infoEntity.getKnowledgeResponseType());
        knowledgeSuperclassProblemConfig.setKnowledgeCustomResponse(infoEntity.getKnowledgeCustomResponse());

        // 保存用户输入记录
        Long inputTimestamp = System.currentTimeMillis();

        // 调用对话Agent
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletResponse response = servletRequestAttributes.getResponse();
        AgentResultEntity agentResultEntity = agentApplicationService.callAgentApplication(agentId,
                callEntity.getDialoguesId(),
                largeModel,
                agentSystem,
                kdIds.toArray(new Integer[0]),
                null,
                infoEntity.getCommunicationTurn(),
                infoEntity.getTopP(),
                infoEntity.getTemperature(),
                messages,
                tools,
                functionCallResult,
                stream,
                infoEntity.getKnowledgeSimilarity(),
                infoEntity.getKnowledgeNResult(),
                knowledgeSearchTypeEnum,
                knowledgeSuperclassProblemConfig,
                response
        );

        //保存对话记录
        BizAgentApplicationDialoguesRecordEntity inputRecord = new BizAgentApplicationDialoguesRecordEntity();
        inputRecord.setAgentId(agentId);
        inputRecord.setMemberId(userId);
        inputRecord.setContent(callEntity.getInput());
        inputRecord.setDialogsId(callEntity.getDialoguesId());
        inputRecord.setRole(AgentApplicationDialoguesRecordConstants.ROLE.USER);
        inputRecord.setTimestamp(inputTimestamp);
        bizAgentApplicationDialoguesRecordService.save(inputRecord);

        BizAgentApplicationDialoguesRecordEntity outputRecord = new BizAgentApplicationDialoguesRecordEntity();
        outputRecord.setRole(AgentApplicationDialoguesRecordConstants.ROLE.ASSISTANT);
        outputRecord.setAgentId(infoEntity.getAgentId());
        outputRecord.setDialogsId(callEntity.getDialoguesId());
        outputRecord.setMemberId(userId);
        outputRecord.setTimestamp(System.currentTimeMillis());
        outputRecord.setContent(agentResultEntity.getMessage());
        outputRecord.setReasoningContent(agentResultEntity.getReasoningContent());
        bizAgentApplicationDialoguesRecordService.save(outputRecord);
    }

    private List<Message> buildMessages(String dialogsId, String agentId, Long userId, String input) throws Exception {
        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);
        logger.info("--------- Build Messages dialogsId:{},agentId:{},messages:{}--------------", dialogsId, agentId, messages);
        return messages;
    }
}
