package top.tqx.demo_1.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.tqx.demo_1.dto.RagRequest;
import top.tqx.demo_1.entity.ChatMessage;
import top.tqx.demo_1.entity.ChatReference;
import top.tqx.demo_1.entity.ChatSession;
import top.tqx.demo_1.mapper.ChatMessageMapper;
import top.tqx.demo_1.entity.CollectionFile;
import top.tqx.demo_1.mapper.ChatReferenceMapper;
import top.tqx.demo_1.mapper.ChatSessionMapper;
import top.tqx.demo_1.mapper.CollectionFileMapper;
import top.tqx.demo_1.service.ChatService;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Slf4j
@Service
public class ChatServiceImpl implements ChatService {

    @Autowired
    private ChatSessionMapper chatSessionMapper;

    @Autowired
    private ChatMessageMapper chatMessageMapper;

    @Autowired
    private ChatReferenceMapper chatReferenceMapper;

    @Autowired
    private CollectionFileMapper collectionFileMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ChatSession createSession(Long userId, String sessionId) {
        ChatSession session = new ChatSession();
        session.setSessionId(sessionId != null && !sessionId.isEmpty() ? sessionId : generateSessionId());
        session.setUserId(userId);
        session.setSummary("");
        session.setCreateTime(LocalDateTime.now());
        chatSessionMapper.insert(session);
        log.info("创建会话: sessionId={}, userId={}", session.getSessionId(), userId);
        return session;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ChatSession getOrCreateSession(Long userId, String sessionId) {
        if (sessionId != null && !sessionId.isEmpty()) {
            LambdaQueryWrapper<ChatSession> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ChatSession::getSessionId, sessionId)
                   .eq(ChatSession::getUserId, userId);
            ChatSession existing = chatSessionMapper.selectOne(wrapper);
            if (existing != null) {
                return existing;
            }
        }
        return createSession(userId, sessionId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ChatSession updateSessionSummary(Long sessionId, String summary) {
        ChatSession session = chatSessionMapper.selectById(sessionId);
        if (session != null) {
            session.setSummary(summary);
            chatSessionMapper.updateById(session);
            log.info("更新会话摘要: sessionId={}, summary={}", sessionId, summary);
        }
        return session;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ChatMessage saveUserMessage(Long sessionId, String content, String kbPaths) {
        ChatMessage message = new ChatMessage();
        message.setConversationId(sessionId);
        message.setRole("user");
        message.setContent(content);
        message.setMessageType("text");
        message.setIsFinished(1);
        message.setKbPaths(kbPaths);
        message.setCreateTime(LocalDateTime.now());
        chatMessageMapper.insert(message);
        log.info("保存用户消息: messageId={}, sessionId={}, contentLength={}", message.getId(), sessionId, content.length());
        return message;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ChatMessage saveAssistantMessage(Long sessionId, String content, String answer, String kbPaths, String messageType, Integer isFinished, Long durationMs, String images) {
        if (content == null || content.isEmpty()) {
            log.warn("助手消息内容为空，跳过保存");
            return null;
        }
        
        if (answer == null || answer.isEmpty()) {
            log.warn("助手回答内容为空，跳过保存");
            return null;
        }
        
        ChatMessage message = new ChatMessage();
        message.setConversationId(sessionId);
        message.setRole("assistant");
        message.setContent(content);
        message.setAnswer(answer);
        message.setKbPaths(kbPaths);
        message.setMessageType(messageType != null ? messageType : "text");
        message.setIsFinished(isFinished != null ? isFinished : 1);
        message.setDurationMs(durationMs);
        message.setImages(images);
        message.setCreateTime(LocalDateTime.now());
        chatMessageMapper.insert(message);
        log.info("保存助手消息: messageId={}, sessionId={}, type={}, finished={}, duration={}ms, images={}", message.getId(), sessionId, messageType, isFinished, durationMs, images != null ? "[" + images.length() + " chars]" : "null");
        return message;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ChatReference saveReference(Long messageId, String chunkId, String docPath, String docName, Integer page, String excerpt, Double score) {
        ChatReference reference = new ChatReference();
        reference.setMessageId(messageId);
        reference.setChunkId(chunkId);
        
        // 通过 collection 和 docName 查找 collection_file 的 id
        String collection = extractCollectionFromDocPath(docPath);
        if (collection != null && docName != null && !docName.isEmpty()) {
            CollectionFile collectionFile = collectionFileMapper.findByCollectionAndDocName(collection, docName);
            if (collectionFile != null) {
                reference.setFileId(collectionFile.getId());
            }
        }
        
        reference.setDocName(docName);
        reference.setPage(page);
        reference.setExcerpt(excerpt);
        reference.setCreateTime(LocalDateTime.now());
        chatReferenceMapper.insert(reference);
        log.info("保存引用: referenceId={}, messageId={}, docName={}, fileId={}", reference.getId(), messageId, docName, reference.getFileId());
        return reference;
    }
    
    private String extractCollectionFromDocPath(String docPath) {
        if (docPath == null || docPath.isEmpty()) {
            return null;
        }
        int index = docPath.indexOf("/");
        if (index > 0) {
            return docPath.substring(0, index);
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<ChatReference> saveReferences(Long messageId, List<ChatReference> references) {
        List<ChatReference> saved = new ArrayList<>();
        for (ChatReference ref : references) {
            ref.setMessageId(messageId);
            ref.setCreateTime(LocalDateTime.now());
            
            // 通过 collection 和 docName 查找 collection_file 的 id
            String collection = ref.getCollection();
            String docName = ref.getDocName();
            if (collection != null && !collection.isEmpty() && docName != null && !docName.isEmpty()) {
                CollectionFile collectionFile = collectionFileMapper.findByCollectionAndDocName(collection, docName);
                if (collectionFile != null) {
                    ref.setFileId(collectionFile.getId());
                }
            }
            
            chatReferenceMapper.insert(ref);
            saved.add(ref);
        }
        log.info("批量保存引用: messageId={}, count={}", messageId, saved.size());
        return saved;
    }

    @Override
    public List<ChatSession> getUserSessions(Long userId) {
        LambdaQueryWrapper<ChatSession> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChatSession::getUserId, userId)
               .orderByDesc(ChatSession::getCreateTime);
        return chatSessionMapper.selectList(wrapper);
    }

    @Override
    public List<ChatMessage> getSessionMessages(String sessionId) {
        // 先通过 sessionId 查找会话，获取会话的 id
        LambdaQueryWrapper<ChatSession> sessionWrapper = new LambdaQueryWrapper<>();
        sessionWrapper.eq(ChatSession::getSessionId, sessionId);
        ChatSession session = chatSessionMapper.selectOne(sessionWrapper);
        
        if (session == null) {
            return new ArrayList<>();
        }
        
        // 然后通过会话 id 查找消息
        LambdaQueryWrapper<ChatMessage> messageWrapper = new LambdaQueryWrapper<>();
        messageWrapper.eq(ChatMessage::getConversationId, session.getId())
               .orderByAsc(ChatMessage::getCreateTime);
        return chatMessageMapper.selectList(messageWrapper);
    }

    @Override
    public List<RagRequest.HistoryItem> getSessionMessagesAsHistory(String sessionId) {
        List<ChatMessage> messages = getSessionMessages(sessionId);
        List<RagRequest.HistoryItem> history = new ArrayList<>();
        for (ChatMessage message : messages) {
            RagRequest.HistoryItem item = new RagRequest.HistoryItem();
            item.setRole(message.getRole());
            item.setContent(message.getContent());
            history.add(item);
        }
        log.info("获取历史记录: sessionId={}, count={}", sessionId, history.size());
        return history;
    }

    @Override
    public List<ChatReference> getMessageReferences(Long messageId) {
        LambdaQueryWrapper<ChatReference> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChatReference::getMessageId, messageId);
        return chatReferenceMapper.selectList(wrapper);
    }

    @Override
    public List<ChatReference> getSessionReferences(String sessionId) {
        // 先通过 sessionId 查找会话，获取会话的 id
        LambdaQueryWrapper<ChatSession> sessionWrapper = new LambdaQueryWrapper<>();
        sessionWrapper.eq(ChatSession::getSessionId, sessionId);
        ChatSession session = chatSessionMapper.selectOne(sessionWrapper);
        
        if (session == null) {
            return new ArrayList<>();
        }
        
        // 查找该会话的所有消息
        LambdaQueryWrapper<ChatMessage> messageWrapper = new LambdaQueryWrapper<>();
        messageWrapper.eq(ChatMessage::getConversationId, session.getId());
        List<ChatMessage> messages = chatMessageMapper.selectList(messageWrapper);
        
        if (messages.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 收集所有消息ID
        List<Long> messageIds = new ArrayList<>();
        for (ChatMessage message : messages) {
            messageIds.add(message.getId());
        }
        
        // 查找所有引用
        LambdaQueryWrapper<ChatReference> referenceWrapper = new LambdaQueryWrapper<>();
        referenceWrapper.in(ChatReference::getMessageId, messageIds);
        return chatReferenceMapper.selectList(referenceWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteSession(String sessionId, Long userId) {
        try {
            // 先通过 sessionId 和 userId 查找会话，确保只能删除自己的会话
            LambdaQueryWrapper<ChatSession> sessionWrapper = new LambdaQueryWrapper<>();
            sessionWrapper.eq(ChatSession::getSessionId, sessionId)
                   .eq(ChatSession::getUserId, userId);
            ChatSession session = chatSessionMapper.selectOne(sessionWrapper);
            
            if (session == null) {
                log.warn("会话不存在或无权删除: sessionId={}, userId={}", sessionId, userId);
                return false;
            }
            
            // 查找该会话的所有消息
            LambdaQueryWrapper<ChatMessage> messageWrapper = new LambdaQueryWrapper<>();
            messageWrapper.eq(ChatMessage::getConversationId, session.getId());
            List<ChatMessage> messages = chatMessageMapper.selectList(messageWrapper);
            
            // 收集所有消息ID
            List<Long> messageIds = new ArrayList<>();
            for (ChatMessage message : messages) {
                messageIds.add(message.getId());
            }
            
            // 删除所有引用
            if (!messageIds.isEmpty()) {
                LambdaQueryWrapper<ChatReference> referenceWrapper = new LambdaQueryWrapper<>();
                referenceWrapper.in(ChatReference::getMessageId, messageIds);
                chatReferenceMapper.delete(referenceWrapper);
            }
            
            // 删除所有消息
            if (!messages.isEmpty()) {
                chatMessageMapper.delete(messageWrapper);
            }
            
            // 删除会话
            chatSessionMapper.delete(sessionWrapper);
            
            log.info("删除会话成功: sessionId={}, userId={}", sessionId, userId);
            return true;
        } catch (Exception e) {
            log.error("删除会话失败: sessionId={}, userId={}", sessionId, userId, e);
            return false;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteSessions(List<String> sessionIds, Long userId) {
        try {
            for (String sessionId : sessionIds) {
                boolean success = deleteSession(sessionId, userId);
                if (!success) {
                    log.warn("批量删除会话失败: sessionId={}", sessionId);
                    // 继续删除其他会话，不中断整个操作
                }
            }
            log.info("批量删除会话完成: count={}, userId={}", sessionIds.size(), userId);
            return true;
        } catch (Exception e) {
            log.error("批量删除会话失败: userId={}", userId, e);
            return false;
        }
    }

    private String generateSessionId() {
        return "sess_" + System.currentTimeMillis() + "_" + UUID.randomUUID().toString().substring(0, 8);
    }
}