package top.tqx.demo_1.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
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.entity.User;
import top.tqx.demo_1.service.AiChatService;
import top.tqx.demo_1.service.AuthService;
import top.tqx.demo_1.service.ChatService;
import top.tqx.demo_1.service.SseEmitterManager;
import top.tqx.demo_1.service.DepartmentService;
import top.tqx.demo_1.service.KnowledgeBasePathService;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Tag(name = "AI对话", description = "AI智能对话接口")
@RestController
@RequestMapping("/ai")
@Slf4j
public class AIChatController {

    @Autowired
    private AiChatService aiChatService;

    @Autowired
    private AuthService authService;

    @Autowired
    private ChatService chatService;

    @Autowired
    private SseEmitterManager sseEmitterManager;

    @Autowired
    private KnowledgeBasePathService knowledgeBasePathService;

    @Autowired
    private DepartmentService departmentService;

    @Operation(summary = "AI流式问答", description = "向AI服务发起流式问答请求，实时返回处理过程，完成后自动保存到数据库")
    @PostMapping(value = "/chat/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter chatStream(
            @RequestBody Map<String, Object> requestMap,
            HttpServletRequest httpRequest) {
        try {
            Long userId = getCurrentUserId(httpRequest);
            if (userId == null) {
                SseEmitter emitter = new SseEmitter();
                try {
                    emitter.send(SseEmitter.event()
                            .name("error")
                            .data("{\"type\":\"error\",\"message\":\"用户未登录\"}"));
                    emitter.complete();
                } catch (Exception e) {
                    emitter.completeWithError(e);
                }
                return emitter;
            }

            User user = authService.validateToken(httpRequest.getHeader("Authorization").substring(7));
            if (user == null) {
                SseEmitter emitter = new SseEmitter();
                try {
                    emitter.send(SseEmitter.event()
                            .name("error")
                            .data("{\"type\":\"error\",\"message\":\"用户信息获取失败\"}"));
                    emitter.complete();
                } catch (Exception e) {
                    emitter.completeWithError(e);
                }
                return emitter;
            }

            RagRequest request = new RagRequest();
            request.setMessage((String) requestMap.get("message"));
            request.setId((String) requestMap.get("id"));

            // 获取用户可访问的知识库
            String deptName = null;
            try {
                if (user.getDeptId() != null) {
                    top.tqx.demo_1.entity.Department department = departmentService.getDepartmentById(user.getDeptId());
                    if (department != null) {
                        deptName = department.getDeptName();
                    }
                }
            } catch (Exception e) {
                log.warn("获取部门信息失败: {}", e.getMessage());
            }

            List<String> collections = knowledgeBasePathService.getUserAccessibleKnowledgeBaseNames(userId, user.getDeptId(), deptName);
            if (collections.isEmpty()) {
                log.warn("用户无可用知识库");
                SseEmitter emitter = new SseEmitter();
                try {
                    emitter.send(SseEmitter.event()
                            .name("error")
                            .data("{\"type\":\"error\",\"message\":\"没有可用的知识库，请联系管理员添加知识库\"}"));
                    emitter.complete();
                } catch (Exception e) {
                    emitter.completeWithError(e);
                }
                return emitter;
            }
            request.setCollections(collections);

            // 生成或使用session_id
            String sessionId = (String) requestMap.get("session_id");
            if (sessionId == null || sessionId.isEmpty()) {
                sessionId = "sess_" + System.currentTimeMillis();
            }
            request.setSessionId(sessionId);

            request.setUserId(userId);
            request.setDeptId(user.getDeptId());
            request.setUserRole(user.getUserType());

            // 从数据库获取历史记录
            List<RagRequest.HistoryItem> history = new ArrayList<>();
            try {
                history = chatService.getSessionMessagesAsHistory(sessionId);
            } catch (Exception e) {
                log.warn("获取历史记录失败: {}", e.getMessage());
            }
            request.setHistory(history);

            log.info("开始AI流式问答: userId={}, deptId={}, role={}, message={}, collections={}, sessionId={}, id={}",
                    userId, user.getDeptId(), user.getUserType(), request.getMessage(),
                    request.getCollections(), request.getSessionId(), request.getId());
            return aiChatService.streamFromRagService(request, userId, user.getDeptId());

        } catch (Exception e) {
            log.error("AI流式问答失败", e);
            SseEmitter emitter = new SseEmitter();
            try {
                emitter.send(SseEmitter.event()
                        .name("error")
                        .data("{\"type\":\"error\",\"message\":\"" + e.getMessage() + "\"}"));
                emitter.complete();
            } catch (Exception ex) {
                emitter.completeWithError(ex);
            }
            return emitter;
        }
    }

    @Operation(summary = "获取用户会话列表", description = "获取当前登录用户的所有会话列表，按创建时间倒序排列")
    @GetMapping("/sessions")
    public Map<String, Object> getUserSessions(
            @Parameter(description = "页码，默认1") @RequestParam(defaultValue = "1") Integer page,
            @Parameter(description = "每页大小，默认10") @RequestParam(defaultValue = "10") Integer pageSize,
            HttpServletRequest httpRequest) {
        Map<String, Object> result = new HashMap<>();
        try {
            Long userId = getCurrentUserId(httpRequest);
            if (userId == null) {
                result.put("success", false);
                result.put("message", "用户未登录");
                return result;
            }

            List<ChatSession> sessions = chatService.getUserSessions(userId);
            // 实现简单分页
            int total = sessions.size();
            int start = (page - 1) * pageSize;
            int end = Math.min(start + pageSize, total);
            List<ChatSession> pageData = new ArrayList<>();
            if (start < total) {
                pageData = sessions.subList(start, end);
            }

            result.put("success", true);
            result.put("data", pageData);
            result.put("total", total);
            result.put("page", page);
            result.put("pageSize", pageSize);
            result.put("pages", (total + pageSize - 1) / pageSize);
        } catch (Exception e) {
            log.error("获取会话列表失败", e);
            result.put("success", false);
            result.put("message", "获取会话列表失败: " + e.getMessage());
        }
        return result;
    }

    @Operation(summary = "获取会话详情", description = "获取指定会话的完整交互记录，包括用户提问与AI回答")
    @GetMapping("/session/{sessionId}")
    public Map<String, Object> getSessionDetail(
            @Parameter(description = "会话ID") @PathVariable String sessionId,
            @Parameter(description = "页码，默认1") @RequestParam(defaultValue = "1") Integer page,
            @Parameter(description = "每页大小，默认20") @RequestParam(defaultValue = "20") Integer pageSize,
            HttpServletRequest httpRequest) {
        log.info("📨 收到获取会话详情请求，sessionId={}", sessionId);
        Map<String, Object> result = new HashMap<>();
        try {
            Long userId = getCurrentUserId(httpRequest);
            if (userId == null) {
                result.put("success", false);
                result.put("message", "用户未登录");
                log.warn("用户未登录，拒绝访问");
                return result;
            }

            // 验证会话所属权（确保用户只能访问自己的会话）
            List<ChatSession> userSessions = chatService.getUserSessions(userId);
            boolean isSessionBelongsToUser = userSessions.stream()
                    .anyMatch(session -> session.getSessionId().equals(sessionId));
            if (!isSessionBelongsToUser) {
                result.put("success", false);
                result.put("message", "无权访问该会话");
                log.warn("用户 {} 无权访问会话 {}", userId, sessionId);
                return result;
            }

            List<ChatMessage> messages = chatService.getSessionMessages(sessionId);
            log.info("获取到 {} 条消息", messages.size());
            
            // 打印第一条消息的详细信息用于调试
            if (!messages.isEmpty()) {
                ChatMessage firstMessage = messages.get(0);
                log.info("第一条消息，id={}, role={}, images={}", 
                         firstMessage.getId(), firstMessage.getRole(),
                         firstMessage.getImages() != null ? firstMessage.getImages().substring(0, Math.min(200, firstMessage.getImages().length())) : "null");
            }
            
            // 实现简单分页
            int total = messages.size();
            int start = (page - 1) * pageSize;
            int end = Math.min(start + pageSize, total);
            List<ChatMessage> pageData = new ArrayList<>();
            if (start < total) {
                pageData = messages.subList(start, end);
            }

            result.put("success", true);
            result.put("data", pageData);
            result.put("total", total);
            result.put("page", page);
            result.put("pageSize", pageSize);
            result.put("pages", (total + pageSize - 1) / pageSize);
            
            log.info("✅ 返回会话详情成功，共 {} 条消息", pageData.size());
        } catch (Exception e) {
            log.error("❌ 获取会话详情失败", e);
            result.put("success", false);
            result.put("message", "获取会话详情失败: " + e.getMessage());
        }
        return result;
    }

    @Operation(summary = "获取消息文件来源列表", description = "获取指定消息引用的文件来源列表（去重），包含文件名称、类型、引用数量和页码范围")
    @GetMapping("/message/{messageId}/sources")
    public Map<String, Object> getMessageSources(
            @Parameter(description = "消息ID") @PathVariable Long messageId,
            HttpServletRequest httpRequest) {
        Map<String, Object> result = new HashMap<>();
        try {
            Long userId = getCurrentUserId(httpRequest);
            if (userId == null) {
                result.put("success", false);
                result.put("message", "用户未登录");
                return result;
            }

            List<ChatReference> references = chatService.getMessageReferences(messageId);
            
            Map<String, Integer> docCountMap = new HashMap<>();
            Map<String, String> docTypeMap = new HashMap<>();
            Map<String, List<Integer>> docPageMap = new HashMap<>();
            
            for (ChatReference ref : references) {
                String docName = ref.getDocName();
                docCountMap.merge(docName, 1, Integer::sum);
                if (ref.getDocType() != null) {
                    docTypeMap.put(docName, ref.getDocType());
                }
                if (ref.getPage() != null) {
                    docPageMap.computeIfAbsent(docName, k -> new ArrayList<>()).add(ref.getPage());
                }
            }
            
            List<Map<String, Object>> sourcesList = new ArrayList<>();
            for (Map.Entry<String, Integer> entry : docCountMap.entrySet()) {
                Map<String, Object> source = new HashMap<>();
                source.put("docName", entry.getKey());
                source.put("docType", docTypeMap.getOrDefault(entry.getKey(), ""));
                source.put("referenceCount", entry.getValue());
                
                List<Integer> pages = docPageMap.get(entry.getKey());
                if (pages != null && !pages.isEmpty()) {
                    int minPage = pages.stream().mapToInt(Integer::intValue).min().orElse(0);
                    int maxPage = pages.stream().mapToInt(Integer::intValue).max().orElse(0);
                    if (minPage == maxPage) {
                        source.put("pages", String.valueOf(minPage));
                    } else {
                        source.put("pages", minPage + "-" + maxPage);
                    }
                }
                sourcesList.add(source);
            }
            
            result.put("success", true);
            result.put("data", sourcesList);
            result.put("total", sourcesList.size());
        } catch (Exception e) {
            log.error("获取文件来源列表失败", e);
            result.put("success", false);
            result.put("message", "获取文件来源列表失败: " + e.getMessage());
        }
        return result;
    }

    @Operation(summary = "获取消息引用信息", description = "获取指定消息的引用信息，包括文档来源、页码、片段内容等，支持按文档名称过滤")
    @GetMapping("/message/{messageId}/references")
    public Map<String, Object> getMessageReferences(
            @Parameter(description = "消息ID") @PathVariable Long messageId,
            @Parameter(description = "文档名称（可选，用于过滤）") @RequestParam(required = false) String docName,
            HttpServletRequest httpRequest) {
        Map<String, Object> result = new HashMap<>();
        try {
            Long userId = getCurrentUserId(httpRequest);
            if (userId == null) {
                result.put("success", false);
                result.put("message", "用户未登录");
                return result;
            }

            List<ChatReference> references = chatService.getMessageReferences(messageId);
            
            if (docName != null && !docName.isEmpty()) {
                references = references.stream()
                        .filter(ref -> docName.equals(ref.getDocName()))
                        .collect(Collectors.toList());
            }
            
            result.put("success", true);
            result.put("data", references);
            result.put("total", references.size());
        } catch (Exception e) {
            log.error("获取引用信息失败", e);
            result.put("success", false);
            result.put("message", "获取引用信息失败: " + e.getMessage());
        }
        return result;
    }

    @Operation(summary = "获取会话引用信息", description = "获取指定会话的所有引用信息，包括文档来源、页码、片段内容等")
    @GetMapping("/session/{sessionId}/references")
    public Map<String, Object> getSessionReferences(
            @Parameter(description = "会话ID") @PathVariable String sessionId,
            HttpServletRequest httpRequest) {
        Map<String, Object> result = new HashMap<>();
        try {
            Long userId = getCurrentUserId(httpRequest);
            if (userId == null) {
                result.put("success", false);
                result.put("message", "用户未登录");
                return result;
            }

            // 验证会话所属权（确保用户只能访问自己的会话）
            List<ChatSession> userSessions = chatService.getUserSessions(userId);
            boolean isSessionBelongsToUser = userSessions.stream()
                    .anyMatch(session -> session.getSessionId().equals(sessionId));
            if (!isSessionBelongsToUser) {
                result.put("success", false);
                result.put("message", "无权访问该会话");
                return result;
            }

            // 获取会话的所有引用信息
            List<ChatReference> references = chatService.getSessionReferences(sessionId);
            result.put("success", true);
            result.put("data", references);
            result.put("total", references.size());
        } catch (Exception e) {
            log.error("获取会话引用信息失败", e);
            result.put("success", false);
            result.put("message", "获取会话引用信息失败: " + e.getMessage());
        }
        return result;
    }

    @Operation(summary = "删除单个会话", description = "删除指定的会话及其所有相关消息和引用信息")
    @DeleteMapping("/session/{sessionId}")
    public Map<String, Object> deleteSession(
            @Parameter(description = "会话ID") @PathVariable String sessionId,
            HttpServletRequest httpRequest) {
        Map<String, Object> result = new HashMap<>();
        try {
            Long userId = getCurrentUserId(httpRequest);
            if (userId == null) {
                result.put("success", false);
                result.put("message", "用户未登录");
                return result;
            }

            // 验证会话所属权（确保用户只能删除自己的会话）
            List<ChatSession> userSessions = chatService.getUserSessions(userId);
            boolean isSessionBelongsToUser = userSessions.stream()
                    .anyMatch(session -> session.getSessionId().equals(sessionId));
            if (!isSessionBelongsToUser) {
                result.put("success", false);
                result.put("message", "无权删除该会话");
                return result;
            }

            // 执行删除操作
            boolean success = chatService.deleteSession(sessionId, userId);
            if (success) {
                result.put("success", true);
                result.put("message", "会话删除成功");
            } else {
                result.put("success", false);
                result.put("message", "会话删除失败");
            }
        } catch (Exception e) {
            log.error("删除会话失败", e);
            result.put("success", false);
            result.put("message", "删除会话失败: " + e.getMessage());
        }
        return result;
    }

    @Operation(summary = "批量删除会话", description = "批量删除多个会话及其所有相关消息和引用信息")
    @DeleteMapping("/sessions")
    public Map<String, Object> deleteSessions(
            @Parameter(description = "会话ID列表") @RequestBody List<String> sessionIds,
            HttpServletRequest httpRequest) {
        Map<String, Object> result = new HashMap<>();
        try {
            Long userId = getCurrentUserId(httpRequest);
            if (userId == null) {
                result.put("success", false);
                result.put("message", "用户未登录");
                return result;
            }

            if (sessionIds == null || sessionIds.isEmpty()) {
                result.put("success", false);
                result.put("message", "会话ID列表不能为空");
                return result;
            }

            // 验证所有会话的所属权
            List<ChatSession> userSessions = chatService.getUserSessions(userId);
            Set<String> userSessionIds = userSessions.stream()
                    .map(ChatSession::getSessionId)
                    .collect(Collectors.toSet());

            boolean allSessionsBelongToUser = sessionIds.stream()
                    .allMatch(userSessionIds::contains);
            if (!allSessionsBelongToUser) {
                result.put("success", false);
                result.put("message", "无权删除部分会话");
                return result;
            }

            // 执行批量删除操作
            boolean success = chatService.deleteSessions(sessionIds, userId);
            if (success) {
                result.put("success", true);
                result.put("message", "会话批量删除成功");
                result.put("deletedCount", sessionIds.size());
            } else {
                result.put("success", false);
                result.put("message", "会话批量删除失败");
            }
        } catch (Exception e) {
            log.error("批量删除会话失败", e);
            result.put("success", false);
            result.put("message", "批量删除会话失败: " + e.getMessage());
        }
        return result;
    }

    @Operation(summary = "中断AI流式问答", description = "中断指定会话的AI流式问答进程")
    @PostMapping("/chat/stop")
    public Map<String, Object> stopChatStream(
            @Parameter(description = "会话ID") @RequestParam String sessionId,
            HttpServletRequest httpRequest) {
        Map<String, Object> result = new HashMap<>();
        try {
            Long userId = getCurrentUserId(httpRequest);
            if (userId == null) {
                result.put("success", false);
                result.put("message", "用户未登录");
                return result;
            }

            log.info("收到中断请求: sessionId={}, userId={}", sessionId, userId);

            boolean success = sseEmitterManager.stop(sessionId);
            if (success) {
                result.put("success", true);
                result.put("message", "已中断AI回答");
            } else {
                result.put("success", false);
                result.put("message", "未找到活跃的AI进程或已结束");
            }
        } catch (Exception e) {
            log.error("中断AI流式问答失败", e);
            result.put("success", false);
            result.put("message", "中断失败: " + e.getMessage());
        }
        return result;
    }

    private Long getCurrentUserId(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        if (token == null || !token.startsWith("Bearer ")) {
            return null;
        }

        User user = authService.validateToken(token.substring(7));
        return user != null ? user.getId() : null;
    }
}