package top.tqx.demo_1.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.web.bind.annotation.*;
import top.tqx.demo_1.common.Result;
import top.tqx.demo_1.dto.*;
import top.tqx.demo_1.entity.Question;
import top.tqx.demo_1.enums.AnswerType;
import top.tqx.demo_1.service.AuthService;
import top.tqx.demo_1.service.ExamService;
import top.tqx.demo_1.service.ExamRecordService;
import top.tqx.demo_1.service.UserAnswerService;
import top.tqx.demo_1.service.UserService;
import top.tqx.demo_1.vo.UserVO;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Tag(name = "考试管理", description = "题目生成与答案批改接口")
@RestController
@RequestMapping("/exam")
@Slf4j
public class ExamController extends BaseController {

    @Autowired
    private ExamService examService;

    @Autowired
    private AuthService authService;

    @Autowired
    private UserService userService;

    @Autowired
    private UserAnswerService userAnswerService;

    @Autowired
    private top.tqx.demo_1.service.ExamRecordService examRecordService;

    @Operation(summary = "开始考试（获取题目）", description = "通过试卷ID开始模拟考试，同时返回试卷题目内容")
    @PostMapping("/paper/{paperId}/start")
    public Result<ExamRecordResponse> startExamByPaperId(
            @PathVariable String paperId,
            HttpServletRequest httpRequest) {
        try {
            Long userId = getCurrentUserId(httpRequest);
            ExamRecordResponse response = examRecordService.startExamByPaperId(paperId, userId, AnswerType.PRACTICE.getCode());
            return Result.success(response);
        } catch (Exception e) {
            log.error("开始考试失败: {}", e.getMessage());
            return Result.error(500, e.getMessage());
        }
    }

    @Operation(summary = "获取考试结果", description = "获取模拟考试的完整结果，包括题目、答案、分数等信息")
    @GetMapping("/record/{recordId}/result")
    public Result<ExamRecordResponse> getExamResult(
            @PathVariable String recordId,
            HttpServletRequest httpRequest) {
        try {
            Long userId = getCurrentUserId(httpRequest);
            ExamRecordResponse response = examRecordService.getRecordById(recordId);
            
            if (response == null) {
                return Result.error(404, "记录不存在");
            }
            
            if (!response.getUserId().equals(userId)) {
                return Result.error(403, "无权查看此记录");
            }
            
            return Result.success(response);
        } catch (Exception e) {
            log.error("获取考试结果失败: {}", e.getMessage());
            return Result.error(500, e.getMessage());
        }
    }

    @Operation(summary = "生成试卷", description = "根据权限范围从题库中动态生成试卷")
    @PostMapping("/paper/generate")
    public Result<ExamPaperGenerateResponse> generatePaper(
            @RequestBody ExamPaperGenerateRequest request,
            HttpServletRequest httpRequest) {

        Long userId = getCurrentUserId(httpRequest);
        if (userId == null) {
            return Result.error(401, "用户未登录");
        }

        UserVO userVO = userService.getUserById(userId);
        if (userVO == null) {
            return Result.error(401, "用户不存在");
        }

        if (request.getIncludePersonal() == null) {
            request.setIncludePersonal(false);
        }

        log.info("生成试卷请求: userId={}, deptId={}, userType={}, includePersonal={}, singleChoiceCount={}, multipleChoiceCount={}, trueFalseCount={}, fillBlankCount={}, subjectiveCount={}, difficulty={}",
                userId, userVO.getDeptId(), userVO.getUserType(), request.getIncludePersonal(),
                request.getSingleChoiceCount(), request.getMultipleChoiceCount(),
                request.getTrueFalseCount(), request.getFillBlankCount(),
                request.getSubjectiveCount(), request.getDifficulty());

        try {
            ExamPaperGenerateResponse response = examService.generatePaper(request, userId, userVO.getDeptId(), userVO.getUserType());
            return Result.success("试卷生成成功", response);
        } catch (Exception e) {
            log.error("生成试卷异常: {}", e.getMessage(), e);
            return Result.error(500, "生成试卷异常: " + e.getMessage());
        }
    }

    @Operation(summary = "生成题目", description = "根据知识库内容生成考试题目，支持单选题、多选题、判断题、填空题、简答题")
    @PostMapping("/generate")
    public Result<Map<String, Object>> generateQuestions(
            @RequestBody ExamGenerateRequest request,
            HttpServletRequest httpRequest) {

        Long userId = getCurrentUserId(httpRequest);
        if (userId == null) {
            return Result.error(401, "用户未登录");
        }

        if (request.getQuestionTypes() == null) {
            return Result.error(400, "question_types 不能为空，请指定题型及数量");
        }

        boolean hasCollection = (request.getCollection() != null) ||
                                (request.getCollectionName() != null && !request.getCollectionName().isEmpty());
        if (!hasCollection) {
            return Result.error(400, "collection 或 collection_name 不能为空，请指定向量库");
        }

        if (request.getFilePath() == null || request.getFilePath().isEmpty()) {
            return Result.error(400, "file_path 不能为空，请指定文件路径");
        }

        if (request.getRequestId() == null || request.getRequestId().isEmpty()) {
            request.setRequestId(UUID.randomUUID().toString());
        }

        log.info("生成题目请求: userId={}, requestId={}, questionTypes={}, difficulty={}, collection={}, collectionName={}, filePath={}",
                userId, request.getRequestId(), request.getQuestionTypes(),
                request.getDifficulty(), request.getCollection(), request.getCollectionName(), request.getFilePath());

        examService.generateQuestionsAsync(request);

        Map<String, Object> result = new HashMap<>();
        result.put("requestId", request.getRequestId());
        result.put("message", "收到请求，正在生成题目，请稍后查看文件状态");
        
        return Result.success("收到请求", result);
    }

    @Operation(summary = "提交考试并批改（正式考试专用）", description = "通过考试记录ID提交正式考试答案并批改")
    @PostMapping("/record/{recordId}/grade")
    public Result<ExamRecordResponse> gradeExamRecord(
            @PathVariable String recordId,
            @RequestBody ExamSaveRequest request,
            HttpServletRequest httpRequest) {

        Long userId = getCurrentUserId(httpRequest);
        if (userId == null) {
            return Result.error(401, "用户未登录");
        }

        log.info("提交正式考试: userId={}, recordId={}", userId, recordId);

        try {
            ExamRecordResponse response = examService.gradeAnswersForRecord(recordId, request, userId, "formal_exam");
            return Result.success("提交成功", response);
        } catch (Exception e) {
            log.error("提交正式考试失败: {}", e.getMessage(), e);
            return Result.error(500, "提交失败: " + e.getMessage());
        }
    }

    @Operation(summary = "批改答案（日常练习/模拟考/正式考试通用）", description = "对学生提交的答案进行批改，支持客观题本地批改和主观题LLM评分")
    @PostMapping("/grade")
    public Result<Object> gradeAnswers(
            @RequestBody ExamGradeRequest request,
            HttpServletRequest httpRequest) {

        Long userId = getCurrentUserId(httpRequest);
        if (userId == null) {
            return Result.error(401, "用户未登录");
        }

        if (request.getAnswers() == null || request.getAnswers().isEmpty()) {
            return Result.error(400, "答案列表不能为空");
        }

        // 检查是否是通过 recordId 提交的正式考试
        if (request.getRecordId() != null && !request.getRecordId().isEmpty()) {
            // 需要转换 ExamGradeRequest 为 ExamSaveRequest
            ExamSaveRequest saveRequest = new ExamSaveRequest();
            List<ExamSaveRequest.AnswerItem> saveItems = request.getAnswers().stream().map(gradeItem -> {
                ExamSaveRequest.AnswerItem saveItem = new ExamSaveRequest.AnswerItem();
                saveItem.setQuestionId(gradeItem.getQuestionId());
                saveItem.setQuestionType(gradeItem.getQuestionType());
                saveItem.setAnswer(gradeItem.getStudentAnswer());
                return saveItem;
            }).collect(java.util.stream.Collectors.toList());
            saveRequest.setAnswers(saveItems);

            log.info("通过recordId提交考试: userId={}, recordId={}", userId, request.getRecordId());

            try {
                ExamRecordResponse response = examService.gradeAnswersForRecord(
                    request.getRecordId(), 
                    saveRequest, 
                    userId, 
                    request.getAnswerType() != null ? request.getAnswerType() : "formal_exam");
                return Result.success("批阅成功", response);
            } catch (Exception e) {
                log.error("批改失败: {}", e.getMessage(), e);
                return Result.error(500, "批改失败: " + e.getMessage());
            }
        }

        // 日常练习/模拟考模式
        for (int i = 0; i < request.getAnswers().size(); i++) {
            ExamGradeRequest.AnswerItem answer = request.getAnswers().get(i);
            if (answer.getQuestionId() == null || answer.getQuestionId().isEmpty()) {
                return Result.error(400, "第" + (i + 1) + "个答案的question_id不能为空");
            }
            if (answer.getQuestionType() == null || answer.getQuestionType().isEmpty()) {
                return Result.error(400, "第" + (i + 1) + "个答案的question_type不能为空");
            }
            if (answer.getQuestionContent() == null) {
                return Result.error(400, "第" + (i + 1) + "个答案的question_content不能为空");
            }
            if (answer.getMaxScore() == null) {
                return Result.error(400, "第" + (i + 1) + "个答案的max_score不能为空");
            }
        }

        if (request.getRequestId() == null || request.getRequestId().isEmpty()) {
            request.setRequestId(UUID.randomUUID().toString());
        }

        if (request.getPaperId() == null || request.getPaperId().isEmpty()) {
            String generatedPaperId = UUID.randomUUID().toString();
            request.setPaperId(generatedPaperId);
            log.info("自动生成试卷ID: paperId={}", generatedPaperId);
        }

        if (request.getSessionId() == null || request.getSessionId().isEmpty()) {
            request.setSessionId("grade_" + UUID.randomUUID().toString().substring(0, 8));
        }

        log.info("批改答案请求: userId={}, requestId={}, paperId={}, sessionId={}, type={}, answers count={}",
                userId, request.getRequestId(), request.getPaperId(), request.getSessionId(), 
                request.getAnswerType(), request.getAnswers().size());

        try {
            ExamGradeResponse response = examService.gradeAnswers(request, userId, request.getPaperId(), 
                    request.getSessionId(), request.getAnswerType());

            if (Boolean.TRUE.equals(response.getSuccess())) {
                return Result.success("批阅成功", response);
            } else {
                String errorMessage = response.getError() != null ? response.getError() : "答案批改失败";
                return Result.error(500, errorMessage);
            }

        } catch (IOException e) {
            log.error("批改答案失败: {}", e.getMessage(), e);
            return Result.error(500, "批改答案失败: " + e.getMessage());
        } catch (Exception e) {
            log.error("批改答案异常: {}", e.getMessage(), e);
            return Result.error(500, "批改答案异常: " + e.getMessage());
        }
    }

    @Operation(summary = "查询用户答题记录", description = "根据试卷ID或会话ID查询用户答题记录，支持按试卷/练习维度分组展示")
    @PostMapping("/answers/query")
    public Result<UserAnswerQueryResponse> queryUserAnswers(
            @RequestBody UserAnswerQueryRequest request,
            HttpServletRequest httpRequest) {

        Long userId = getCurrentUserId(httpRequest);
        if (userId == null) {
            return Result.error(401, "用户未登录");
        }

        boolean hasPaperId = request.getPaperId() != null && !request.getPaperId().isEmpty();
        boolean hasSessionId = request.getSessionId() != null && !request.getSessionId().isEmpty();

        if (!hasPaperId && !hasSessionId) {
            return Result.error(400, "paper_id 或 session_id 不能为空");
        }

        if (hasPaperId && hasSessionId) {
            return Result.error(400, "paper_id 和 session_id 不能同时提供");
        }

        request.setUserId(userId);

        log.info("查询用户答题记录: userId={}, paperId={}, sessionId={}",
                userId, request.getPaperId(), request.getSessionId());

        try {
            UserAnswerQueryResponse response = userAnswerService.queryUserAnswers(request);

            if (response.getTotalCount() == 0) {
                return Result.success("未找到答题记录", response);
            }

            return Result.success("查询成功", response);

        } catch (Exception e) {
            log.error("查询用户答题记录异常: {}", e.getMessage(), e);
            return Result.error(500, "查询用户答题记录异常: " + e.getMessage());
        }
    }

    @Operation(summary = "获取考试记录列表", description = "根据类型获取用户的考试/练习记录，支持日常练习(practice)、模拟考(mock_exam)、正式考(formal_exam)")
    @GetMapping("/records")
    public Result<Object> getExamRecords(
            @Parameter(description = "记录类型：practice(日常练习), mock_exam(模拟考), formal_exam(正式考)", example = "practice") 
            @RequestParam(defaultValue = "practice") String type,
            HttpServletRequest httpRequest) {

        Long userId = getCurrentUserId(httpRequest);
        if (userId == null) {
            return Result.error(401, "用户未登录");
        }

        log.info("查询考试记录: userId={}, type={}", userId, type);

        try {
            // 根据类型选择不同的查询逻辑
            if ("practice".equals(type)) {
                // 日常练习：从 user_answer 表查询，按 session_id 分组
                UserAnswerQueryRequest queryRequest = new UserAnswerQueryRequest();
                queryRequest.setUserId(userId);
                UserAnswerQueryResponse response = userAnswerService.queryUserAnswers(queryRequest);
                return Result.success(response);
            } else if ("mock_exam".equals(type) || "formal_exam".equals(type)) {
                // 模拟考/正式考：从 exam_record 表查询
                List<ExamRecordResponse> records = examRecordService.getUserPapers(userId, type);
                return Result.success(records);
            } else {
                return Result.error(400, "无效的类型参数，支持的值: practice, mock_exam, formal_exam");
            }
        } catch (Exception e) {
            log.error("查询考试记录失败: {}", e.getMessage(), e);
            return Result.error(500, "查询考试记录失败: " + e.getMessage());
        }
    }

}