package cn.com.poc.ai_bi.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.BizAgentApplicationGcConfigService;
import cn.com.poc.agent_application.service.BizAgentApplicationPublishService;
import cn.com.poc.agent_application.utils.AgentApplicationTools;
import cn.com.poc.ai_bi.aggregate.AiBiService;
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.service.RedisService;
import cn.com.poc.common.utils.DocumentLoad;
import cn.com.poc.common.utils.JsonUtils;
import cn.com.poc.common.utils.SSEUtil;
import cn.com.poc.common.utils.StringUtils;
import cn.com.poc.knowledge.aggregate.KnowledgeService;
import cn.com.poc.knowledge.entity.BizKnowledgeDatabaseEntity;
import cn.com.poc.knowledge.service.BizKnowledgeDatabaseService;
import cn.com.poc.long_document.domain.LongtextDialoguesResult;
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.csvchain.CSVChainResponse;
import cn.com.poc.thirdparty.resource.demand.ai.entity.csvchain.CSVChainResult;
import cn.com.poc.thirdparty.resource.demand.ai.entity.dbchain.DBChainResponse;
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.dialogue.Tool;
import cn.com.poc.thirdparty.resource.demand.ai.entity.dialogue.ToolFunction;
import cn.com.poc.thirdparty.resource.demand.ai.entity.function.FunctionCallResult;
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.chart_data_convert.ChartData;
import cn.com.poc.thirdparty.resource.demand.ai.function.chart_data_convert.ChartDataConvertFunction;
import cn.com.poc.thirdparty.resource.demand.ai.function.echart.EChartGenerateFunction;
import cn.com.poc.thirdparty.service.ChainService;
import cn.com.poc.thirdparty.service.LLMService;
import cn.com.yict.framemax.core.exception.BusinessException;
import cn.com.yict.framemax.frame.service.FmxParamConfigService;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.lang3.ArrayUtils;
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.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author alex.yao
 * @date 2025/6/20
 */
@Service
public class AiBiServiceImpl implements AiBiService {

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


    private final String INSIGHT_REPORT_REDIS_PREFIX = "INSIGHT_REPORT:";


    private final String FMX_PARAM_AGENT_ID_CODE = "ai_bi.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;

    @Resource
    private ChainService chainService;

    @Resource
    private BizKnowledgeDatabaseService bizKnowledgeDatabaseService;

    @Resource
    private LLMService llmService;

    @Resource
    private RedisService redisService;

    @Resource
    private EChartGenerateFunction eChartGenerateFunction;

    @Resource
    private ChartDataConvertFunction chartDataConvertFunction;

    @Resource
    private BizAgentApplicationGcConfigService bizAgentApplicationGcConfigService;


    @Override
    public void call(String dialoguesId, String input, String fileUrl, Integer[] knowledgeIds, Integer[] databaseIds, 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(dialoguesId);
        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(input);
            bizAiDialoguesService.update(portalDialoguesEntity);
        }

        // 获取对话配置
        String largeModel = infoEntity.getLargeModel();//获取模型
        String agentSystem = infoEntity.getAgentSystem();//获取Agent角色词
        List<Integer> kdIds = knowledgeService.getKdIdsByKnowledgeInfoIds(knowledgeIds);//获取知识库ids
        List<Message> messages = AgentApplicationTools.buildMessage(dialoguesId, agentId, userId, input);//构建消息
        List<Tool> tools = AgentApplicationTools.buildFunctionConfig(infoEntity.getVariableStructure(), infoEntity.getIsLongMemory(), dialoguesId, agentId, infoEntity.getUnitIds(), infoEntity.getIsDocumentParsing());//构建函数配置

        List<String> fileUrls = new ArrayList<>();//构建文件链接
        if (StringUtils.isNotBlank(fileUrl)) {
            fileUrls.add(fileUrl);
        }
        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,
                dialoguesId,
                largeModel,
                agentSystem,
                kdIds.toArray(new Integer[0]),
                databaseIds,
                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(input);
        inputRecord.setDialogsId(dialoguesId);
        inputRecord.setRole(AgentApplicationDialoguesRecordConstants.ROLE.USER);
        inputRecord.setTimestamp(inputTimestamp);
        bizAgentApplicationDialoguesRecordService.save(inputRecord);
        //AI输出记录
        BizAgentApplicationDialoguesRecordEntity outputRecord = new BizAgentApplicationDialoguesRecordEntity();
        outputRecord.setRole(AgentApplicationDialoguesRecordConstants.ROLE.ASSISTANT);
        outputRecord.setAgentId(infoEntity.getAgentId());
        outputRecord.setDialogsId(dialoguesId);
        outputRecord.setMemberId(userId);
        outputRecord.setTimestamp(System.currentTimeMillis());
        outputRecord.setContent(agentResultEntity.getMessage());
        outputRecord.setReasoningContent(agentResultEntity.getReasoningContent());
        bizAgentApplicationDialoguesRecordService.save(outputRecord);
    }


    @Override
    public void callV2(String dialoguesId, String input, String fileUrl, Integer[] knowledgeIds, Integer[] databaseIds, Long userId) throws IOException {
        SSEUtil sseUtil = new SSEUtil();
        // 保存对话基础信息
        try {
            BizAiDialoguesEntity bizAiDialoguesEntity = new BizAiDialoguesEntity();
            bizAiDialoguesEntity.setMemberId(userId);
            bizAiDialoguesEntity.setDialoguesId(dialoguesId);
            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(input);
                bizAiDialoguesService.update(portalDialoguesEntity);
            }

            if (databaseIds.length > 1) {
                throw new BusinessException("仅支持单个数据库");
            }
            long inputTime = System.currentTimeMillis();

            CSVChainResult csvChainResult = new CSVChainResult();
            List<DBChainResult> dbChainResults = new ArrayList<>();
            String functionRecord = StringUtils.EMPTY;

            BizAgentApplicationGcConfigEntity gcConfigEntity = bizAgentApplicationGcConfigService.getByConfigCode("AIBIPrompt");
            if (gcConfigEntity == null) {
                throw new BusinessException("无法找到【智能问数】配置");
            }

            //1. 文件/数据库 chain
            if (ArrayUtils.isNotEmpty(databaseIds)) {
                for (Integer databaseId : databaseIds) {
                    BizKnowledgeDatabaseEntity bizKnowledgeDatabaseEntity = bizKnowledgeDatabaseService.get(databaseId.longValue());
                    if (bizKnowledgeDatabaseEntity == null) {
                        continue;
                    }
                    DBChainResponse dbChainResponse = new DBChainResponse();
                    dbChainResponse.setQuestion(input);
                    dbChainResponse.setContext(null);
                    dbChainResponse.setPrompt(null);
                    dbChainResponse.setTableFilters(null);
                    dbChainResponse.setMysqlUser(bizKnowledgeDatabaseEntity.getDbUsername());
                    dbChainResponse.setMysqlPassword(bizKnowledgeDatabaseEntity.getDbPassword());
                    dbChainResponse.setMysqlHost(bizKnowledgeDatabaseEntity.getDbHost());
                    dbChainResponse.setMysqlPort(bizKnowledgeDatabaseEntity.getDbPort());
                    dbChainResponse.setMysqlDatabase(bizKnowledgeDatabaseEntity.getDbName());
                    DBChainResult dbChainResult = chainService.dbChain(dbChainResponse);
                    if (dbChainResult != null) {
                        dbChainResult.setSql("```SQL\n" + dbChainResult.getSql() + "\n```");
                        dbChainResults.add(dbChainResult);
                    }
                }
                //2. 若有数据, 执行[EChart Agent] 判断并生成EChart Option
                if (CollectionUtils.isNotEmpty(dbChainResults)) {
                    DBChainResult dbChainResult = dbChainResults.get(0);
                    //输出SQL
                    LargeModelDemandResult result = new LargeModelDemandResult();
                    result.setCode("0");
                    result.setFunction(null);
                    result.setDbChainResult(dbChainResults);
                    result.setKnowledgeContentResult(null);
                    sseUtil.send(JsonUtils.serialize(result));

                    JSONObject chartJSONObject = new JSONObject();
                    chartJSONObject.put("data", JsonUtils.serialize(dbChainResult));
                    chartJSONObject.put("question", input);
                    AbstractFunctionResult<ChartData> functionResult = chartDataConvertFunction.doFunction(chartJSONObject.toJSONString(), null, null, null);
                    functionRecord = outputChartData(functionResult.getPromptContent(), sseUtil, functionRecord);
                }
            } else if (StringUtils.isNotBlank(fileUrl)) {
                CSVChainResponse csvChainResponse = new CSVChainResponse();
                csvChainResponse.setQuestion(input);
                csvChainResponse.setContext(null);
                csvChainResponse.setFilePath(fileUrl);
                csvChainResult = chainService.csvChain(csvChainResponse);


                if (csvChainResult != null) {
                    LargeModelDemandResult result = new LargeModelDemandResult();
                    result.setCode("0");
                    result.setFunction(null);
                    result.setDbChainResult(null);
                    result.setKnowledgeContentResult(null);
                    result.setCsvChainResult(csvChainResult);
                    sseUtil.send(JsonUtils.serialize(result));
                    if (StringUtils.isNotBlank(csvChainResult.getResult())) {

                        JSONObject chartJSONObject = new JSONObject();
                        chartJSONObject.put("data", csvChainResult.getResult());
                        chartJSONObject.put("question", input);
                        AbstractFunctionResult<ChartData> functionResult = chartDataConvertFunction.doFunction(chartJSONObject.toJSONString(), null, null, null);
                        functionRecord = outputChartData(functionResult.getPromptContent(), sseUtil, functionRecord);
                    }
                }
            }


            //3. 执行对话大模型
            List<Message> messages = buildMessage(userId, dialoguesId, gcConfigEntity.getConfigSystem(), input, dbChainResults, csvChainResult);
            LargeModelResponse largeModelResponse = new LargeModelResponse();
            largeModelResponse.setModel(gcConfigEntity.getLargeModel());
            largeModelResponse.setMessages(messages.toArray(new Message[0]));
            largeModelResponse.setStream(true);
            largeModelResponse.setUser("AI_BI_CHAT");
            BufferedReader bufferedReader = llmService.chatChunk(largeModelResponse);
            LongtextDialoguesResult longtextDialoguesResult = textOutputStream(sseUtil, bufferedReader);

            //保存对话记录
            BizAgentApplicationDialoguesRecordEntity inputRecord = new BizAgentApplicationDialoguesRecordEntity();
            inputRecord.setMemberId(userId);
            inputRecord.setContent(input);
            if (StringUtils.isNotBlank(fileUrl)) {
                inputRecord.setFileUrl(fileUrl);
            }
            inputRecord.setDialogsId(dialoguesId);
            inputRecord.setRole("user");
            inputRecord.setTimestamp(inputTime);

            // 保存AI回复记录
            BizAgentApplicationDialoguesRecordEntity assistantRecord = new BizAgentApplicationDialoguesRecordEntity();
            assistantRecord.setMemberId(userId);
            assistantRecord.setContent(longtextDialoguesResult.getMessage());
            assistantRecord.setReasoningContent(longtextDialoguesResult.getReasoningContent());
            assistantRecord.setDialogsId(dialoguesId);
            assistantRecord.setFunction(functionRecord);
            assistantRecord.setRole("assistant");
            assistantRecord.setTimestamp(System.currentTimeMillis());

            bizAgentApplicationDialoguesRecordService.save(inputRecord);
            bizAgentApplicationDialoguesRecordService.save(assistantRecord);
        } catch (Exception e) {
            sseUtil.completeByError(e.getMessage());
        }

    }

    private String outputECharts(String eChartOption, SSEUtil sseUtil, String functionRecord) throws IOException {
        //输出EChart
        if (eChartOption != null && StringUtils.isNotBlank(eChartOption)) {
            JSONObject jsonObject = JSONObject.parseObject(eChartOption);
            if (!jsonObject.containsKey("skip")) {
                ToolFunction toolFunction = new ToolFunction();
                toolFunction.setName("echart_function");
                toolFunction.setResult(eChartOption);
                toolFunction.setDisplayFormat("json");
                toolFunction.setArguments(null);
                LargeModelDemandResult result = new LargeModelDemandResult();
                result.setCode("0");
                result.setFunction(toolFunction);
                result.setDbChainResult(null);
                result.setKnowledgeContentResult(null);

                String toolFunctionJson = JsonUtils.serialize(result);
                sseUtil.send(toolFunctionJson);
                functionRecord = toolFunctionJson;
            }
        }
        return functionRecord;
    }

    private String outputChartData(String chartData, SSEUtil sseUtil, String functionRecord) throws IOException {
        if (chartData != null && StringUtils.isNotBlank(chartData)) {
            JSONObject jsonObject = JSONObject.parseObject(chartData);
            if (jsonObject.containsKey("skip") && !jsonObject.getBoolean("skip")) {
                ToolFunction toolFunction = new ToolFunction();
                toolFunction.setName("chart_data_generate");
                toolFunction.setResult(chartData);
                toolFunction.setDisplayFormat("json");
                toolFunction.setArguments(null);
                LargeModelDemandResult result = new LargeModelDemandResult();
                result.setCode("0");
                result.setFunction(toolFunction);
                result.setDbChainResult(null);
                result.setKnowledgeContentResult(null);

                String toolFunctionJson = JsonUtils.serialize(result);
                sseUtil.send(toolFunctionJson);
                functionRecord = toolFunctionJson;
            }
        }
        return functionRecord;
    }


    private List<Message> buildMessage(Long userId, String dialoguesId, String prompt, String input, List<DBChainResult> dbChainResults, CSVChainResult csvChainResult) throws Exception {
        List<Message> messages = new ArrayList<>();
        String databaseResult = StringUtils.EMPTY, csvResult = StringUtils.EMPTY;

        if (CollectionUtils.isNotEmpty(dbChainResults)) {
            databaseResult = JsonUtils.serialize(dbChainResults);
        }
        if (csvChainResult != null && csvChainResult.getResult() != null) {
            csvResult = JsonUtils.serialize(csvChainResult);
        }
        prompt = prompt.replace("${csvResult}", csvResult)
                .replace("${databaseResult}", databaseResult)
                .replace("${question}", input);
        Message systemMessage = new Message();
        systemMessage.setRole(LLMRoleEnum.SYSTEM.getRole());
        systemMessage.setContent(prompt);
        messages.add(systemMessage);
        messages.addAll(AgentApplicationTools.buildMessage(dialoguesId, null, userId, input));
        return messages;
    }

    /**
     * 文本输出结果
     *
     * @param sseUtil
     * @param bufferedReader
     * @throws IOException
     */
    private LongtextDialoguesResult textOutputStream(SSEUtil sseUtil, BufferedReader bufferedReader) throws IOException {
        String res = "";
        StringBuilder output = new StringBuilder();
        StringBuilder reasoningContent = new StringBuilder();
        try {
            while ((res = bufferedReader.readLine()) != null) {
                if (org.apache.commons.lang3.StringUtils.isEmpty(res)) {
                    continue;
                }
                res = org.apache.commons.lang3.StringUtils.replace(res, "data: ", org.apache.commons.lang3.StringUtils.EMPTY);
                LargeModelDemandResult result = JsonUtils.deSerialize(res, LargeModelDemandResult.class);
                if (!"0".equals(result.getCode())) {
                    logger.error("LLM Error,code:{}", result.getCode());
                    BusinessException ex = new BusinessException("exception/call.failure");
                    result.setMessage(ex.getMessage());
                    sseUtil.send(JsonUtils.serialize(result));
                    sseUtil.send("[DONE]");
                    sseUtil.complete();
                    throw ex;
                }
                result.setFunction(null);
                result.setDbChainResult(null);
                result.setKnowledgeContentResult(null);
                sseUtil.send(JsonUtils.serialize(result));
                if (org.apache.commons.lang3.StringUtils.isNotEmpty(result.getMessage())) {
                    output.append(result.getMessage());
                }
                if (org.apache.commons.lang3.StringUtils.isNotEmpty(result.getReasoningContent())) {
                    reasoningContent.append(result.getReasoningContent());
                }
            }
            // 关闭资源
            sseUtil.send("[DONE]");
            sseUtil.complete();
            LongtextDialoguesResult longtextDialoguesResult = new LongtextDialoguesResult();
            longtextDialoguesResult.setMessage(output.toString());
            longtextDialoguesResult.setReasoningContent(reasoningContent.toString());
            return longtextDialoguesResult;
        } catch (IOException e) {
            logger.error("连接断开,code:{}", e.getMessage());
            sseUtil.completeByError("连接断开");
            throw new BusinessException("连接断开");
        } finally {
            bufferedReader.close();
            sseUtil.complete();
        }
    }


    @Override
    public void generateInsightReport(String dialoguesId, String fileUrl, String SQL, String result, String question) throws Exception {

        String redisKey = INSIGHT_REPORT_REDIS_PREFIX + dialoguesId;

        BizAgentApplicationGcConfigEntity gcConfigEntity = bizAgentApplicationGcConfigService.getByConfigCode("AIBIInsightReport");
        if (gcConfigEntity == null) {
            throw new BusinessException("无法找到【洞察报告生成】配置");
        }

        String prompt = gcConfigEntity.getConfigSystem();
        if (StringUtils.isNotBlank(fileUrl)) {
            // 获取文件表头
            File file = DocumentLoad.downloadURLDocument(fileUrl);
            try (Reader reader = new FileReader(file)) {
                CSVParser csvParser = new CSVParser(reader, CSVFormat.DEFAULT
                        .withFirstRecordAsHeader()
                        .withIgnoreHeaderCase()
                        .withTrim());
                Map<String, Integer> headerMap = csvParser.getHeaderMap();
                String headers = StringUtils.EMPTY;
                if (MapUtils.isNotEmpty(headerMap)) {
                    Set<String> headerSet = headerMap.keySet();
                    headers = JsonUtils.serialize(headerSet);
                }
                prompt = prompt.replace("${question}", question)
                        .replace("${index}", headers)
                        .replace("${sql}", StringUtils.EMPTY)
                        .replace("${result}", result);
            } catch (Exception e) {
                throw new BusinessException("获取文件失败");
            }
        } else {
            prompt = prompt.replace("${question}", question)
                    .replace("${index}", StringUtils.EMPTY)
                    .replace("${sql}", SQL)
                    .replace("${result}", result);
        }
        //生成洞察报告
        String insightReport = StringUtils.EMPTY;
        Message message = new Message();
        message.setRole(LLMRoleEnum.USER.getRole());
        message.setContent(prompt);

        LargeModelResponse largeModelResponse = new LargeModelResponse();
        largeModelResponse.setModel(gcConfigEntity.getLargeModel());
        largeModelResponse.setMessages(new Message[]{message});
        largeModelResponse.setStream(true);
        largeModelResponse.setUser("GENERATE_INSIGHT_REPORT");
        BufferedReader bufferedReader = llmService.chatChunk(largeModelResponse);
        LongtextDialoguesResult longtextDialoguesResult = textOutputStream(new SSEUtil(), bufferedReader);
        insightReport = longtextDialoguesResult.getMessage();
        //保存
        redisService.set(redisKey, insightReport);
    }


    @Override
    public String getInsightReport(String dialoguesId) {
        String redisKey = INSIGHT_REPORT_REDIS_PREFIX + dialoguesId;
        if (redisService.hasKey(redisKey)) {
            return redisService.get(redisKey).toString();
        }
        return StringUtils.EMPTY;
    }
}
