package org.xyzh.workcase.service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;

import org.xyzh.api.ai.dto.ChatPrepareData;
import org.xyzh.api.ai.dto.TbAgent;
import org.xyzh.api.ai.service.AgentChatService;
import org.xyzh.api.system.service.SysConfigService;
import org.xyzh.api.workcase.dto.ChatRoomSummaryRequest;
import org.xyzh.api.workcase.dto.ChatRoomSummaryResponse;
import org.xyzh.api.workcase.dto.TbChatRoomMessageDTO;
import org.xyzh.api.workcase.dto.TbChatRoomSummaryDTO;
import org.xyzh.api.workcase.dto.TbWordCloudDTO;
import org.xyzh.api.workcase.service.AgentService;
import org.xyzh.api.workcase.vo.ChatRoomMessageVO;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.utils.id.IdUtil;
import org.xyzh.workcase.mapper.TbChatMessageMapper;
import org.xyzh.workcase.mapper.TbChatRoomSummaryMapper;
import org.xyzh.workcase.mapper.TbWordCloudMapper;

/**
 * @description    智能体服务实现类，提供AI相关的业务功能
 * @filename    AgentServiceImpl.java
 * @author    system
 * @copyright xyzh
 * @since 2026-01-01
 */
@DubboService(version = "1.0.0", group = "workcase", timeout = 30000, retries = 0)
public class AgentServiceImpl implements AgentService {
    private static final Logger logger = LoggerFactory.getLogger(AgentServiceImpl.class);

    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    // 系统配置键名
    private static final String CONFIG_KEY_SUMMARY_API = "dify.workcase.workflow.summary";

    @Autowired
    private TbChatMessageMapper chatMessageMapper;

    @Autowired
    private TbWordCloudMapper wordCloudMapper;

    @Autowired
    private TbChatRoomSummaryMapper chatRoomSummaryMapper;

    @DubboReference(version = "1.0.0", group = "system", timeout = 30000, retries = 0)
    private SysConfigService sysConfigService;

    @DubboReference(version = "1.0.0", group = "ai", timeout = 30000, retries = 0)
    private org.xyzh.api.ai.service.AgentService aiAgentService;

    @DubboReference(version = "1.0.0", group = "ai", timeout = 60000, retries = 0)
    private AgentChatService agentChatService;

    @Override
    public ResultDomain<ChatRoomSummaryResponse> summaryChatRoom(ChatRoomSummaryRequest request) {
        try {
            logger.info("开始总结聊天室: roomId={}", request.getRoomId());

            // 1. 从系统配置获取API Key
            String apiKey = sysConfigService.getStringConfig(CONFIG_KEY_SUMMARY_API);
            if (apiKey == null || apiKey.isEmpty()) {
                logger.error("未配置聊天室总结工作流的API Key: {}", CONFIG_KEY_SUMMARY_API);
                return ResultDomain.failure("系统未配置聊天室总结功能");
            }

            // 2. 根据API Key查询对应的Agent
            TbAgent agentFilter = new TbAgent();
            agentFilter.setApiKey(apiKey);
            ResultDomain<TbAgent> agentResult = aiAgentService.getAgentList(agentFilter);
            if (!agentResult.getSuccess() || agentResult.getDataList() == null || agentResult.getDataList().isEmpty()) {
                logger.error("未找到API Key对应的智能体: {}", apiKey);
                return ResultDomain.failure("未找到对应的智能体配置");
            }

            TbAgent agent = agentResult.getDataList().get(0);
            logger.info("找到智能体: agentId={}, name={}", agent.getAgentId(), agent.getName());

            // 3. 获取聊天室的所有消息
            TbChatRoomMessageDTO filter = new TbChatRoomMessageDTO();
            filter.setRoomId(request.getRoomId());

            List<ChatRoomMessageVO> messages = chatMessageMapper.selectChatMessageList(filter);
            if (messages == null || messages.isEmpty()) {
                return ResultDomain.failure("聊天室没有消息");
            }

            // 4. 过滤消息（根据请求参数）
            List<Map<String, Object>> filteredMessages = new ArrayList<>();
            for (ChatRoomMessageVO message : messages) {
                String messageType = message.getMessageType();

                // 根据请求参数决定是否包含系统消息和会议消息
                boolean shouldInclude = true;
                if ("system".equals(messageType) && !Boolean.TRUE.equals(request.getIncludeSystemMessages())) {
                    shouldInclude = false;
                }
                if ("meeting".equals(messageType) && !Boolean.TRUE.equals(request.getIncludeMeetingMessages())) {
                    shouldInclude = false;
                }

                if (shouldInclude) {
                    Map<String, Object> msgMap = new HashMap<>();
                    msgMap.put("senderType", message.getSenderType()); // guest/ai/agent
                    msgMap.put("content", message.getContent());
                    msgMap.put("send_time", DATE_FORMAT.format(message.getSendTime()));
                    filteredMessages.add(msgMap);
                }
            }

            if (filteredMessages.isEmpty()) {
                return ResultDomain.failure("聊天室没有有效的对话消息");
            }

            logger.info("聊天室 {} 共有 {} 条有效消息", request.getRoomId(), filteredMessages.size());

            // 5. 将消息列表转换为JSON字符串
            String chatMessagesJson = JSON.toJSONString(filteredMessages);

            // 6. 准备调用工作流的参数
            ChatPrepareData prepareData = new ChatPrepareData();
            prepareData.setAgentId(agent.getAgentId());
            prepareData.setQuery("总结聊天内容");
            prepareData.setUserId("system_summary");
            prepareData.setUserType(true); // 作为员工身份调用
            prepareData.setAppType("workflow"); // 设置为workflow类型

            // 7. 设置工作流的输入参数
            Map<String, Object> inputsMap = new HashMap<>();
            inputsMap.put("chatMessages", chatMessagesJson); // 工作流期望的输入参数名
            prepareData.setInputsMap(inputsMap);

            logger.info("准备工作流会话，输入参数: chatMessages长度={}", chatMessagesJson.length());

            // 8. 调用准备会话
            ResultDomain<String> prepareResult = agentChatService.prepareChatMessageSession(prepareData);
            if (!prepareResult.getSuccess()) {
                logger.error("准备工作流会话失败: {}", prepareResult.getMessage());
                return ResultDomain.failure("准备会话失败: " + prepareResult.getMessage());
            }

            String sessionId = prepareResult.getData();
            logger.info("工作流会话准备成功: sessionId={}", sessionId);

            // 9. 调用工作流执行，获取完整结果
            ResultDomain<String> workflowResult = agentChatService.runWorkflowWithSession(sessionId);
            if (!workflowResult.getSuccess()) {
                logger.error("工作流执行失败: {}", workflowResult.getMessage());
                return ResultDomain.failure("总结失败: " + workflowResult.getMessage());
            }

            String outputsJson = workflowResult.getData();
            logger.debug("工作流返回结果: {}", outputsJson);

            // 10. 解析工作流返回的outputs（JSON格式）
            JSONObject outputsObject;
            try {
                outputsObject = JSON.parseObject(outputsJson);
            } catch (Exception e) {
                logger.error("解析工作流输出失败: {}", outputsJson, e);
                return ResultDomain.failure("工作流输出格式错误");
            }

            // 11. 从outputs中获取text字段（工作流的输出节点）
            String text = outputsObject.getString("text");
            if (text == null || text.isEmpty()) {
                logger.error("工作流输出中没有text字段: {}", outputsJson);
                return ResultDomain.failure("工作流输出缺少text字段");
            }

            // 12. 解析text中的JSON结果
            JSONObject resultJson;
            try {
                resultJson = JSON.parseObject(text);
            } catch (Exception e) {
                logger.error("解析工作流text字段失败: {}", text, e);
                return ResultDomain.failure("工作流返回结果格式错误");
            }

            // 13. 构建响应对象
            ChatRoomSummaryResponse response = new ChatRoomSummaryResponse();
            response.setRoomId(request.getRoomId());
            response.setQuestion(resultJson.getString("question"));

            // 安全获取needs数组
            List<String> needs = resultJson.getList("needs", String.class);
            response.setNeeds(needs != null ? needs : new ArrayList<>());

            response.setAnswer(resultJson.getString("answer"));

            // 安全获取workcloud数组
            List<String> workcloud = resultJson.getList("workcloud", String.class);
            response.setWorkcloud(workcloud != null ? workcloud : new ArrayList<>());

            response.setSummaryTime(DATE_FORMAT.format(new java.util.Date()));
            response.setMessageCount(filteredMessages.size());

            // 14. 保存词云数据到数据库
            if (workcloud != null && !workcloud.isEmpty()) {
                saveWordCloudData(request.getRoomId(), workcloud);
            }

            // 15. 保存总结数据到数据库
            saveChatRoomSummary(request.getRoomId(), resultJson, filteredMessages.size());

            logger.info("聊天室总结完成: roomId={}, question={}, wordcloud数量={}",
                    request.getRoomId(), response.getQuestion(), workcloud != null ? workcloud.size() : 0);

            return ResultDomain.success("总结成功", response);

        } catch (Exception e) {
            logger.error("总结聊天室异常: roomId={}", request.getRoomId(), e);
            return ResultDomain.failure("总结失败: " + e.getMessage());
        }
    }

    /**
     * 保存词云数据到数据库
     * @param roomId 聊天室ID
     * @param wordList 词云关键词列表
     */
    private void saveWordCloudData(String roomId, List<String> wordList) {
        try {
            String today = new SimpleDateFormat("yyyy-MM-dd").format(new java.util.Date());

            for (String word : wordList) {
                if (word == null || word.trim().isEmpty()) {
                    continue;
                }

                // 查询是否已存在该词条（同一天、同一分类）
                TbWordCloudDTO filter = new TbWordCloudDTO();
                filter.setWord(word.trim());
                filter.setCategory("chatroom_summary"); // 分类：聊天室总结
                filter.setStatDate(today);

                TbWordCloudDTO existing = wordCloudMapper.selectWordCloudOne(filter);

                if (existing != null) {
                    // 已存在，增加词频
                    wordCloudMapper.incrementFrequency(existing.getWordId(), 1);
                    logger.debug("词云词频递增: word={}, wordId={}", word, existing.getWordId());
                } else {
                    // 不存在，插入新词条
                    TbWordCloudDTO newWord = new TbWordCloudDTO();
                    newWord.setWordId(IdUtil.getSnowflakeId());
                    newWord.setOptsn(IdUtil.getOptsn());
                    newWord.setWord(word.trim());
                    newWord.setFrequency("1");
                    newWord.setCategory("chatroom_summary");
                    newWord.setStatDate(today);

                    wordCloudMapper.insertWordCloud(newWord);
                    logger.debug("插入新词云: word={}, wordId={}", word, newWord.getWordId());
                }
            }

            logger.info("词云数据保存完成: roomId={}, 词条数量={}", roomId, wordList.size());
        } catch (Exception e) {
            logger.error("保存词云数据失败: roomId={}", roomId, e);
            // 词云保存失败不影响总结流程，仅记录日志
        }
    }

    /**
     * 保存聊天室总结数据到数据库
     * @param roomId 聊天室ID
     * @param resultJson 工作流返回的JSON结果
     * @param messageCount 参与总结的消息数量
     */
    private void saveChatRoomSummary(String roomId, JSONObject resultJson, int messageCount) {
        try {
            TbChatRoomSummaryDTO summary = new TbChatRoomSummaryDTO();
            summary.setSummaryId(IdUtil.getSnowflakeId());
            summary.setOptsn(IdUtil.getOptsn());
            summary.setRoomId(roomId);
            summary.setQuestion(resultJson.getString("question"));

            // 获取needs数组并转换为String[]
            List<String> needsList = resultJson.getList("needs", String.class);
            if (needsList != null && !needsList.isEmpty()) {
                summary.setNeeds(needsList);
            } else {
                summary.setNeeds(new ArrayList<>());
            }

            summary.setAnswer(resultJson.getString("answer"));

            // 获取workcloud数组并转换为String[]
            List<String> workcloudList = resultJson.getList("workcloud", String.class);
            if (workcloudList != null && !workcloudList.isEmpty()) {
                summary.setWorkcloud(workcloudList);
            } else {
                summary.setWorkcloud(new ArrayList<>());
            }

            summary.setMessageCount(messageCount);
            summary.setSummaryTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date()));
            summary.setCreator("system");

            chatRoomSummaryMapper.insertChatRoomSummary(summary);

            logger.info("聊天室总结数据保存成功: roomId={}, summaryId={}", roomId, summary.getSummaryId());
        } catch (Exception e) {
            logger.error("保存聊天室总结数据失败: roomId={}", roomId, e);
            // 总结数据保存失败不影响主流程，仅记录日志
        }
    }

    @Override
    public ResultDomain<ChatRoomSummaryResponse> getLatestSummary(String roomId) {
        try {
            logger.info("查询聊天室最新总结: roomId={}", roomId);

            // 查询最新的总结记录
            TbChatRoomSummaryDTO summary = chatRoomSummaryMapper.selectLatestSummaryByRoomId(roomId);

            if (summary == null) {
                logger.info("未找到聊天室总结: roomId={}", roomId);
                return ResultDomain.failure("暂无总结数据");
            }

            // 构建响应对象
            ChatRoomSummaryResponse response = new ChatRoomSummaryResponse();
            response.setRoomId(summary.getRoomId());
            response.setQuestion(summary.getQuestion());
            response.setNeeds(summary.getNeeds());
            response.setAnswer(summary.getAnswer());
            response.setWorkcloud(summary.getWorkcloud());
            response.setSummaryTime(summary.getSummaryTime());
            response.setMessageCount(summary.getMessageCount());

            logger.info("查询聊天室总结成功: roomId={}, summaryId={}", roomId, summary.getSummaryId());
            return ResultDomain.success("查询成功", response);

        } catch (Exception e) {
            logger.error("查询聊天室总结异常: roomId={}", roomId, e);
            return ResultDomain.failure("查询失败: " + e.getMessage());
        }
    }
}