package org.xyzh.ai.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.xyzh.ai.mapper.AiConversationMapper;
import org.xyzh.ai.mapper.AiMessageMapper;
import org.xyzh.api.ai.history.AiChatHistoryService;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.core.page.PageDomain;
import org.xyzh.common.core.page.PageParam;
import org.xyzh.common.dto.ai.TbAiConversation;
import org.xyzh.common.dto.ai.TbAiMessage;
import org.xyzh.common.dto.user.TbSysUser;
import org.xyzh.system.utils.LoginUtil;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @description AI对话历史服务实现
 * @filename AiChatHistoryServiceImpl.java
 * @author AI Assistant
 * @copyright xyzh
 * @since 2025-11-04
 */
@Slf4j
@Service
public class AiChatHistoryServiceImpl implements AiChatHistoryService {

    @Autowired
    private AiConversationMapper conversationMapper;

    @Autowired
    private AiMessageMapper messageMapper;

    @Override
    public PageDomain<TbAiConversation> pageUserConversations(
            String agentId,
            String keyword,
            Boolean isFavorite,
            Date startDate,
            Date endDate,
            PageParam pageParam) {

        try {
            TbSysUser currentUser = LoginUtil.getCurrentUser();
            if (currentUser == null) {
                return new PageDomain<>(pageParam, new ArrayList<>());
            }

            // 查询数据
            List<TbAiConversation> conversations = conversationMapper.selectUserConversationsPage(
                    currentUser.getID(),
                    agentId,
                    keyword,
                    isFavorite,
                    startDate,
                    endDate,
                    pageParam
            );

            // 查询总数
            long total = conversationMapper.countUserConversationsWithFilter(
                    currentUser.getID(),
                    agentId,
                    keyword,
                    isFavorite,
                    startDate,
                    endDate
            );

            // 构建分页结果
            int totalPages = (int) Math.ceil((double) total / pageParam.getPageSize());
            PageParam resultParam = new PageParam(
                    pageParam.getPageNumber(),
                    pageParam.getPageSize(),
                    totalPages,
                    total
            );

            return new PageDomain<>(resultParam, conversations);

        } catch (Exception e) {
            log.error("分页查询会话失败", e);
            return new PageDomain<>(pageParam, new ArrayList<>());
        }
    }

    @Override
    public PageDomain<TbAiConversation> searchConversations(String keyword, PageParam pageParam) {
        try {
            if (!StringUtils.hasText(keyword)) {
                return new PageDomain<>(pageParam, new ArrayList<>());
            }

            TbSysUser currentUser = LoginUtil.getCurrentUser();
            if (currentUser == null) {
                return new PageDomain<>(pageParam, new ArrayList<>());
            }

            // 搜索会话
            List<TbAiConversation> conversations = conversationMapper.searchConversationsByKeyword(
                    currentUser.getID(),
                    keyword,
                    pageParam
            );

            // 查询总数
            long total = conversationMapper.countSearchConversations(
                    currentUser.getID(),
                    keyword
            );

            // 构建分页结果
            int totalPages = (int) Math.ceil((double) total / pageParam.getPageSize());
            PageParam resultParam = new PageParam(
                    pageParam.getPageNumber(),
                    pageParam.getPageSize(),
                    totalPages,
                    total
            );

            return new PageDomain<>(resultParam, conversations);

        } catch (Exception e) {
            log.error("搜索会话失败", e);
            return new PageDomain<>(pageParam, new ArrayList<>());
        }
    }

    @Override
    public PageDomain<TbAiMessage> searchMessages(String keyword, String conversationId, PageParam pageParam) {
        try {
            if (!StringUtils.hasText(keyword)) {
                return new PageDomain<>(pageParam, new ArrayList<>());
            }

            TbSysUser currentUser = LoginUtil.getCurrentUser();
            if (currentUser == null) {
                return new PageDomain<>(pageParam, new ArrayList<>());
            }

            // 搜索消息
            List<TbAiMessage> messages = messageMapper.searchMessagesByContent(
                    currentUser.getID(),
                    keyword,
                    conversationId,
                    pageParam
            );

            // 查询总数
            long total = messageMapper.countSearchMessages(
                    currentUser.getID(),
                    keyword,
                    conversationId
            );

            // 构建分页结果
            int totalPages = (int) Math.ceil((double) total / pageParam.getPageSize());
            PageParam resultParam = new PageParam(
                    pageParam.getPageNumber(),
                    pageParam.getPageSize(),
                    totalPages,
                    total
            );

            return new PageDomain<>(resultParam, messages);

        } catch (Exception e) {
            log.error("搜索消息失败", e);
            return new PageDomain<>(pageParam, new ArrayList<>());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<Boolean> toggleFavorite(String conversationId, Boolean isFavorite) {
        ResultDomain<Boolean> resultDomain = new ResultDomain<>();

        try {
            if (!StringUtils.hasText(conversationId)) {
                resultDomain.fail("会话ID不能为空");
                return resultDomain;
            }

            // 验证所属权
            TbSysUser currentUser = LoginUtil.getCurrentUser();
            TbAiConversation conversation = conversationMapper.selectConversationById(conversationId);
            
            if (conversation == null || conversation.getDeleted()) {
                resultDomain.fail("会话不存在");
                return resultDomain;
            }

            if (currentUser != null && !conversation.getUserID().equals(currentUser.getID())) {
                resultDomain.fail("无权操作此会话");
                return resultDomain;
            }

            // 更新收藏状态
            TbAiConversation update = new TbAiConversation();
            update.setID(conversationId);
            update.setIsFavorite(isFavorite);
            update.setUpdateTime(new Date());
            conversationMapper.updateConversation(update);

            log.info("会话收藏状态更新: {} - {}", conversationId, isFavorite);
            resultDomain.success("操作成功", true);
            return resultDomain;

        } catch (Exception e) {
            log.error("更新收藏状态失败", e);
            resultDomain.fail("操作失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<Boolean> togglePin(String conversationId, Boolean isPinned) {
        ResultDomain<Boolean> resultDomain = new ResultDomain<>();

        try {
            if (!StringUtils.hasText(conversationId)) {
                resultDomain.fail("会话ID不能为空");
                return resultDomain;
            }

            // 验证所属权
            TbSysUser currentUser = LoginUtil.getCurrentUser();
            TbAiConversation conversation = conversationMapper.selectConversationById(conversationId);
            
            if (conversation == null || conversation.getDeleted()) {
                resultDomain.fail("会话不存在");
                return resultDomain;
            }

            if (currentUser != null && !conversation.getUserID().equals(currentUser.getID())) {
                resultDomain.fail("无权操作此会话");
                return resultDomain;
            }

            // 更新置顶状态
            TbAiConversation update = new TbAiConversation();
            update.setID(conversationId);
            update.setIsPinned(isPinned);
            update.setUpdateTime(new Date());
            conversationMapper.updateConversation(update);

            log.info("会话置顶状态更新: {} - {}", conversationId, isPinned);
            resultDomain.success("操作成功", true);
            return resultDomain;

        } catch (Exception e) {
            log.error("更新置顶状态失败", e);
            resultDomain.fail("操作失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<Integer> batchDeleteConversations(List<String> conversationIds) {
        ResultDomain<Integer> resultDomain = new ResultDomain<>();

        try {
            if (conversationIds == null || conversationIds.isEmpty()) {
                resultDomain.fail("会话ID列表不能为空");
                return resultDomain;
            }

            TbSysUser currentUser = LoginUtil.getCurrentUser();
            if (currentUser == null) {
                resultDomain.fail("用户未登录");
                return resultDomain;
            }

            // 验证所有会话的所属权
            int deleteCount = 0;
            for (String conversationId : conversationIds) {
                TbAiConversation conversation = conversationMapper.selectConversationById(conversationId);
                if (conversation != null && conversation.getUserID().equals(currentUser.getID())) {
                    // 逻辑删除会话
                    TbAiConversation deleteEntity = new TbAiConversation();
                    deleteEntity.setID(conversationId);
                    conversationMapper.deleteConversation(deleteEntity);

                    // 同时删除消息
                    List<TbAiMessage> messages = messageMapper.selectMessagesByConversationId(conversationId);
                    for (TbAiMessage message : messages) {
                        TbAiMessage deleteMsg = new TbAiMessage();
                        deleteMsg.setID(message.getID());
                        messageMapper.deleteMessage(deleteMsg);
                    }

                    deleteCount++;
                }
            }

            log.info("批量删除会话完成: {}/{}", deleteCount, conversationIds.size());
            resultDomain.success("删除成功", deleteCount);
            return resultDomain;

        } catch (Exception e) {
            log.error("批量删除会话失败", e);
            resultDomain.fail("删除失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<Map<String, Object>> getUserChatStatistics(String userId) {
        ResultDomain<Map<String, Object>> resultDomain = new ResultDomain<>();

        try {
            TbSysUser currentUser = LoginUtil.getCurrentUser();
            if (currentUser == null) {
                resultDomain.fail("用户未登录");
                return resultDomain;
            }

            String targetUserId = StringUtils.hasText(userId) ? userId : currentUser.getID();

            // 统计数据
            Map<String, Object> statistics = new HashMap<>();

            // 会话总数
            long totalConversations = conversationMapper.countUserConversations(targetUserId);
            statistics.put("totalConversations", totalConversations);

            // 查询用户所有会话
            List<TbAiConversation> conversations = conversationMapper.selectConversationsByUserId(targetUserId, null);

            // 消息总数和Token总数
            int totalMessages = conversations.stream()
                    .mapToInt(c -> c.getMessageCount() != null ? c.getMessageCount() : 0)
                    .sum();
            int totalTokens = conversations.stream()
                    .mapToInt(c -> c.getTotalTokens() != null ? c.getTotalTokens() : 0)
                    .sum();

            statistics.put("totalMessages", totalMessages);
            statistics.put("totalTokens", totalTokens);

            // 收藏会话数
            long favoriteCount = conversations.stream()
                    .filter(c -> c.getIsFavorite() != null && c.getIsFavorite())
                    .count();
            statistics.put("favoriteConversations", favoriteCount);

            // 最近活跃会话（最近7天）
            Date sevenDaysAgo = new Date(System.currentTimeMillis() - 7L * 24 * 60 * 60 * 1000);
            long recentActiveCount = conversations.stream()
                    .filter(c -> c.getLastMessageTime() != null && c.getLastMessageTime().after(sevenDaysAgo))
                    .count();
            statistics.put("recentActiveConversations", recentActiveCount);

            resultDomain.success("查询成功", statistics);
            return resultDomain;

        } catch (Exception e) {
            log.error("查询用户统计信息失败", e);
            resultDomain.fail("查询失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<Map<String, Object>> getConversationStatistics(String conversationId) {
        ResultDomain<Map<String, Object>> resultDomain = new ResultDomain<>();

        try {
            if (!StringUtils.hasText(conversationId)) {
                resultDomain.fail("会话ID不能为空");
                return resultDomain;
            }

            // 验证所属权
            TbAiConversation conversation = conversationMapper.selectConversationById(conversationId);
            if (conversation == null || conversation.getDeleted()) {
                resultDomain.fail("会话不存在");
                return resultDomain;
            }

            TbSysUser currentUser = LoginUtil.getCurrentUser();
            if (currentUser != null && !conversation.getUserID().equals(currentUser.getID())) {
                resultDomain.fail("无权访问此会话");
                return resultDomain;
            }

            Map<String, Object> statistics = new HashMap<>();

            // 基本信息
            statistics.put("conversationId", conversationId);
            statistics.put("title", conversation.getTitle());
            statistics.put("messageCount", conversation.getMessageCount());
            statistics.put("totalTokens", conversation.getTotalTokens());
            statistics.put("createTime", conversation.getCreateTime());
            statistics.put("lastMessageTime", conversation.getLastMessageTime());

            // 查询消息列表
            List<TbAiMessage> messages = messageMapper.selectMessagesByConversationId(conversationId);

            // 用户消息和AI回复数量
            long userMessageCount = messages.stream()
                    .filter(m -> "user".equals(m.getRole()))
                    .count();
            long assistantMessageCount = messages.stream()
                    .filter(m -> "assistant".equals(m.getRole()))
                    .count();

            statistics.put("userMessageCount", userMessageCount);
            statistics.put("assistantMessageCount", assistantMessageCount);

            // 评分统计
            List<Map<String, Object>> ratings = messageMapper.countMessageRatings(conversationId);
            statistics.put("ratingDistribution", ratings);

            // 有反馈的消息数
            long feedbackCount = messages.stream()
                    .filter(m -> m.getFeedback() != null && !m.getFeedback().isEmpty())
                    .count();
            statistics.put("feedbackCount", feedbackCount);

            resultDomain.success("查询成功", statistics);
            return resultDomain;

        } catch (Exception e) {
            log.error("查询会话统计失败", e);
            resultDomain.fail("查询失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<String> exportConversationAsMarkdown(String conversationId) {
        ResultDomain<String> resultDomain = new ResultDomain<>();

        try {
            if (!StringUtils.hasText(conversationId)) {
                resultDomain.fail("会话ID不能为空");
                return resultDomain;
            }

            // 验证所属权
            TbAiConversation conversation = conversationMapper.selectConversationById(conversationId);
            if (conversation == null || conversation.getDeleted()) {
                resultDomain.fail("会话不存在");
                return resultDomain;
            }

            TbSysUser currentUser = LoginUtil.getCurrentUser();
            if (currentUser != null && !conversation.getUserID().equals(currentUser.getID())) {
                resultDomain.fail("无权访问此会话");
                return resultDomain;
            }

            // 查询消息
            List<TbAiMessage> messages = messageMapper.selectMessagesByConversationId(conversationId);

            // 生成Markdown
            StringBuilder markdown = new StringBuilder();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

            // 标题和元数据
            markdown.append("# ").append(conversation.getTitle()).append("\n\n");
            markdown.append("**创建时间**: ").append(sdf.format(conversation.getCreateTime())).append("\n\n");
            markdown.append("**消息数量**: ").append(messages.size()).append("\n\n");
            if (conversation.getSummary() != null) {
                markdown.append("**摘要**: ").append(conversation.getSummary()).append("\n\n");
            }
            markdown.append("---\n\n");

            // 消息内容
            for (TbAiMessage message : messages) {
                String role = "user".equals(message.getRole()) ? "👤 用户" : "🤖 AI助手";
                markdown.append("### ").append(role).append("\n\n");
                markdown.append(message.getContent()).append("\n\n");
                
                if (message.getRating() != null) {
                    String ratingEmoji = message.getRating() == 1 ? "👍" : "👎";
                    markdown.append("**评价**: ").append(ratingEmoji).append("\n\n");
                }
                
                if (message.getFeedback() != null && !message.getFeedback().isEmpty()) {
                    markdown.append("**反馈**: ").append(message.getFeedback()).append("\n\n");
                }
                
                markdown.append("---\n\n");
            }

            log.info("导出会话Markdown成功: {}", conversationId);
            resultDomain.success("导出成功", markdown.toString());
            return resultDomain;

        } catch (Exception e) {
            log.error("导出会话Markdown失败", e);
            resultDomain.fail("导出失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<String> exportConversationAsJson(String conversationId) {
        ResultDomain<String> resultDomain = new ResultDomain<>();

        try {
            if (!StringUtils.hasText(conversationId)) {
                resultDomain.fail("会话ID不能为空");
                return resultDomain;
            }

            // 验证所属权
            TbAiConversation conversation = conversationMapper.selectConversationById(conversationId);
            if (conversation == null || conversation.getDeleted()) {
                resultDomain.fail("会话不存在");
                return resultDomain;
            }

            TbSysUser currentUser = LoginUtil.getCurrentUser();
            if (currentUser != null && !conversation.getUserID().equals(currentUser.getID())) {
                resultDomain.fail("无权访问此会话");
                return resultDomain;
            }

            // 查询消息
            List<TbAiMessage> messages = messageMapper.selectMessagesByConversationId(conversationId);

            // 构建导出对象
            Map<String, Object> exportData = new HashMap<>();
            exportData.put("conversation", conversation);
            exportData.put("messages", messages);
            exportData.put("exportTime", new Date());

            // 使用Fastjson2转JSON（格式化输出）
            String json = JSON.toJSONString(exportData, JSONWriter.Feature.PrettyFormat);

            log.info("导出会话JSON成功: {}", conversationId);
            resultDomain.success("导出成功", json);
            return resultDomain;

        } catch (Exception e) {
            log.error("导出会话JSON失败", e);
            resultDomain.fail("导出失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<String> batchExportConversations(List<String> conversationIds, String format) {
        ResultDomain<String> resultDomain = new ResultDomain<>();

        try {
            if (conversationIds == null || conversationIds.isEmpty()) {
                resultDomain.fail("会话ID列表不能为空");
                return resultDomain;
            }

            TbSysUser currentUser = LoginUtil.getCurrentUser();
            if (currentUser == null) {
                resultDomain.fail("用户未登录");
                return resultDomain;
            }

            StringBuilder result = new StringBuilder();
            boolean isMarkdown = "markdown".equalsIgnoreCase(format);

            for (int i = 0; i < conversationIds.size(); i++) {
                String conversationId = conversationIds.get(i);
                
                if (isMarkdown) {
                    ResultDomain<String> exportResult = exportConversationAsMarkdown(conversationId);
                    if (exportResult.isSuccess()) {
                        result.append(exportResult.getData());
                        if (i < conversationIds.size() - 1) {
                            result.append("\n\n---\n\n");
                        }
                    }
                } else {
                    ResultDomain<String> exportResult = exportConversationAsJson(conversationId);
                    if (exportResult.isSuccess()) {
                        result.append(exportResult.getData());
                        if (i < conversationIds.size() - 1) {
                            result.append(",\n");
                        }
                    }
                }
            }

            if (!isMarkdown) {
                // JSON格式需要数组包装
                result.insert(0, "[\n");
                result.append("\n]");
            }

            log.info("批量导出会话成功: {} 个会话", conversationIds.size());
            resultDomain.success("导出成功", result.toString());
            return resultDomain;

        } catch (Exception e) {
            log.error("批量导出会话失败", e);
            resultDomain.fail("导出失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<Integer> cleanExpiredConversations(Integer days) {
        ResultDomain<Integer> resultDomain = new ResultDomain<>();

        try {
            if (days == null || days < 1) {
                resultDomain.fail("天数必须大于0");
                return resultDomain;
            }

            TbSysUser currentUser = LoginUtil.getCurrentUser();
            if (currentUser == null) {
                resultDomain.fail("用户未登录");
                return resultDomain;
            }

            // 计算过期日期
            Date beforeDate = new Date(System.currentTimeMillis() - days * 24L * 60 * 60 * 1000);

            // 查询过期会话ID
            List<String> expiredIds = conversationMapper.selectExpiredConversationIds(
                    currentUser.getID(),
                    beforeDate
            );

            if (expiredIds.isEmpty()) {
                resultDomain.success("没有过期会话", 0);
                return resultDomain;
            }

            // 批量删除
            int deleteCount = conversationMapper.batchUpdateConversations(expiredIds, true);

            // 同时删除相关消息
            for (String conversationId : expiredIds) {
                List<TbAiMessage> messages = messageMapper.selectMessagesByConversationId(conversationId);
                for (TbAiMessage message : messages) {
                    TbAiMessage deleteMsg = new TbAiMessage();
                    deleteMsg.setID(message.getID());
                    messageMapper.deleteMessage(deleteMsg);
                }
            }

            log.info("清理过期会话: {} 天前，清理数量: {}", days, deleteCount);
            resultDomain.success("清理成功", deleteCount);
            return resultDomain;

        } catch (Exception e) {
            log.error("清理过期会话失败", e);
            resultDomain.fail("清理失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbAiConversation> getRecentConversations(Integer limit) {
        ResultDomain<TbAiConversation> resultDomain = new ResultDomain<>();

        try {
            TbSysUser currentUser = LoginUtil.getCurrentUser();
            if (currentUser == null) {
                resultDomain.fail("用户未登录");
                return resultDomain;
            }

            int queryLimit = (limit != null && limit > 0) ? limit : 10;
            List<TbAiConversation> conversations = conversationMapper.selectRecentConversations(
                    currentUser.getID(),
                    queryLimit
            );

            resultDomain.success("查询成功", conversations);
            return resultDomain;

        } catch (Exception e) {
            log.error("查询最近会话失败", e);
            resultDomain.fail("查询失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbAiConversation> getPopularConversations(Integer limit) {
        ResultDomain<TbAiConversation> resultDomain = new ResultDomain<>();

        try {
            TbSysUser currentUser = LoginUtil.getCurrentUser();
            if (currentUser == null) {
                resultDomain.fail("用户未登录");
                return resultDomain;
            }

            int queryLimit = (limit != null && limit > 0) ? limit : 10;
            List<TbAiConversation> conversations = conversationMapper.selectPopularConversations(
                    currentUser.getID(),
                    queryLimit
            );

            resultDomain.success("查询成功", conversations);
            return resultDomain;

        } catch (Exception e) {
            log.error("查询热门会话失败", e);
            resultDomain.fail("查询失败: " + e.getMessage());
            return resultDomain;
        }
    }
}

