package top.tqx.demo_1.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.*;
import top.tqx.demo_1.entity.*;
import top.tqx.demo_1.mapper.*;
import top.tqx.demo_1.service.ExamRecordService;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.LocalDateTime;
import java.util.*;
import java.util.UUID;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ExamRecordServiceImpl implements ExamRecordService {

    @Autowired
    private ExamRecordMapper examRecordMapper;

    @Autowired
    private ExamPaperMapper examPaperMapper;

    @Autowired
    private QuestionMapper questionMapper;

    @Autowired
    private UserAnswerMapper userAnswerMapper;
    
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public List<ExamRecordResponse> getUserPapers(Long userId, String answerType) {
        List<ExamRecord> records = examRecordMapper.selectList(
            new LambdaQueryWrapper<ExamRecord>()
                .eq(ExamRecord::getUserId, userId)
                .eq(ExamRecord::getAnswerType, answerType)
                .ne(ExamRecord::getStatus, "revoked")
                .orderByDesc(ExamRecord::getCreatedAt));
        
        List<ExamRecordResponse> responses = new ArrayList<>();
        for (ExamRecord record : records) {
            ExamRecordResponse response = convertToResponse(record);
            response.setPaperTitle(getPaperTitle(record.getPaperId()));
            responses.add(response);
        }
        
        return responses;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ExamRecordResponse startExamByPaperId(String paperId, Long userId, String answerType) {
        log.info("通过试卷ID开始考试: paperId={}, userId={}, answerType={}", paperId, userId, answerType);

        ExamPaper paper = examPaperMapper.selectOne(
            new LambdaQueryWrapper<ExamPaper>().eq(ExamPaper::getPaperId, paperId));

        if (paper == null) {
            throw new RuntimeException("试卷不存在");
        }

        ExamRecord record = examRecordMapper.selectOne(
            new LambdaQueryWrapper<ExamRecord>()
                .eq(ExamRecord::getPaperId, paperId)
                .eq(ExamRecord::getUserId, userId)
                .eq(ExamRecord::getAnswerType, answerType));

        if (record == null) {
            log.info("创建新考试记录: paperId={}, userId={}, answerType={}", paperId, userId, answerType);
            record = new ExamRecord();
            record.setRecordId(UUID.randomUUID().toString());
            record.setPaperId(paperId);
            record.setAnswerType(answerType);
            record.setUserId(userId);
            record.setStatus("not_started");
            record.setCreatedAt(LocalDateTime.now());
            record.setUpdatedAt(LocalDateTime.now());
            examRecordMapper.insert(record);
        } else {
            log.info("找到现有考试记录: recordId={}, currentStatus={}", record.getRecordId(), record.getStatus());
        }

        String recordId = record.getRecordId();
        log.info("开始考试: recordId={}, currentStatus={}", recordId, record.getStatus());

        String status = record.getStatus();

        if ("in_progress".equals(status)) {
            log.info("考试已在进行中，直接返回考试信息: recordId={}", recordId);
            ExamRecordResponse response = convertToResponse(record);
            response.setPaperTitle(paper.getTitle());
            response.setQuestions(getPaperQuestions(paper));
            return response;
        }

        if (!"not_started".equals(status) && !"pending".equals(status) && !"draft".equals(status)) {
            log.warn("考试状态不允许开始: recordId={}, currentStatus={}", recordId, status);
            throw new RuntimeException("考试状态不允许开始，当前状态: " + status);
        }

        record.setStatus("in_progress");
        record.setStartTime(LocalDateTime.now());
        record.setLastActiveTime(LocalDateTime.now());
        record.setUpdatedAt(LocalDateTime.now());

        examRecordMapper.updateById(record);

        log.info("考试状态更新成功: recordId={}", recordId);

        ExamRecordResponse response = convertToResponse(record);
        response.setPaperTitle(paper.getTitle());
        response.setQuestions(getPaperQuestions(paper));

        return response;
    }


    
    private List<ExamRecordResponse.ExamPaperQuestion> getPaperQuestions(ExamPaper paper) {
        List<ExamRecordResponse.ExamPaperQuestion> questions = new ArrayList<>();
        
        if (paper.getQuestionIds() != null) {
            List<String> questionIdList = JSONArray.parseArray(paper.getQuestionIds().toString(), String.class);
            for (String qId : questionIdList) {
                Question question = questionMapper.selectOne(
                    new LambdaQueryWrapper<Question>().eq(Question::getQuestionId, qId));
                if (question != null) {
                    ExamRecordResponse.ExamPaperQuestion detail = new ExamRecordResponse.ExamPaperQuestion();
                    detail.setQuestionId(question.getQuestionId());
                    detail.setQuestionType(question.getQuestionType());
                    detail.setDifficulty(question.getDifficulty());
                    detail.setScore(question.getScore());
                    detail.setContent(question.getContent() != null ? question.getContent().toString() : null);
                    questions.add(detail);
                }
            }
        }
        
        return questions;
    }

    @Override
    public ExamRecordResponse getRecordById(String recordId) {
        ExamRecord record = examRecordMapper.selectOne(
            new LambdaQueryWrapper<ExamRecord>().eq(ExamRecord::getRecordId, recordId));
        
        if (record == null) {
            return null;
        }
        
        ExamRecordResponse response = convertToResponse(record);
        response.setPaperTitle(getPaperTitle(record.getPaperId()));
        
        if ("submitted".equals(record.getStatus()) || "graded".equals(record.getStatus())) {
            response.setAnswers(getUserAnswers(record.getPaperId(), record.getUserId()));
        }
        
        return response;
    }

    private List<ExamRecordResponse.AnswerDetail> getUserAnswers(String paperId, Long userId) {
        List<UserAnswer> userAnswers = userAnswerMapper.selectList(
            new LambdaQueryWrapper<UserAnswer>()
                .eq(UserAnswer::getPaperId, paperId)
                .eq(UserAnswer::getUserId, userId));
        
        return userAnswers.stream()
            .map(ua -> {
                ExamRecordResponse.AnswerDetail detail = new ExamRecordResponse.AnswerDetail();
                detail.setQuestionId(ua.getQuestionId());
                detail.setQuestionType(ua.getQuestionType());
                detail.setScore(ua.getScore());
                detail.setMaxScore(ua.getMaxScore());
                detail.setIsCorrect(Boolean.TRUE.equals(ua.getIsCorrect()));
                detail.setFeedback(ua.getFeedback());
                
                // 获取用户答案
                detail.setUserAnswer(ua.getUserAnswer());
                
                // 从question表获取题目内容和正确答案
                Question question = questionMapper.selectOne(
                    new LambdaQueryWrapper<Question>().eq(Question::getQuestionId, ua.getQuestionId()));
                if (question != null && question.getContent() != null) {
                    try {
                        ExamGradeRequest.QuestionContent content = 
                            objectMapper.treeToValue(question.getContent(), ExamGradeRequest.QuestionContent.class);
                        detail.setStem(content.getStem());
                        detail.setCorrectAnswer(content.getAnswer());
                    } catch (Exception e) {
                        log.warn("解析题目内容失败: questionId={}", ua.getQuestionId(), e);
                    }
                }
                
                return detail;
            })
            .collect(Collectors.toList());
    }

    @Override
    public PageResponse<ExamRecordResponse> listRecords(String paperId, Integer page, Integer pageSize) {
        Page<ExamRecord> pageQuery = new Page<>(page, pageSize);
        
        LambdaQueryWrapper<ExamRecord> wrapper = new LambdaQueryWrapper<>();
        if (paperId != null && !paperId.isEmpty()) {
            wrapper.eq(ExamRecord::getPaperId, paperId);
        }
        wrapper.orderByDesc(ExamRecord::getSubmitTime);
        
        Page<ExamRecord> resultPage = examRecordMapper.selectPage(pageQuery, wrapper);
        
        List<ExamRecordResponse> responses = resultPage.getRecords().stream()
            .map(record -> {
                ExamRecordResponse r = convertToResponse(record);
                r.setPaperTitle(getPaperTitle(record.getPaperId()));
                return r;
            })
            .collect(Collectors.toList());
        
        return new PageResponse<>(responses, resultPage.getTotal(), page, pageSize);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteRecordsByPaperId(String paperId) {
        examRecordMapper.delete(new LambdaQueryWrapper<ExamRecord>().eq(ExamRecord::getPaperId, paperId));
    }

    private ExamRecordResponse convertToResponse(ExamRecord record) {
        ExamRecordResponse response = new ExamRecordResponse();
        response.setRecordId(record.getRecordId());
        response.setPaperId(record.getPaperId());
        response.setAnswerType(record.getAnswerType());
        response.setUserId(record.getUserId());
        response.setStatus(record.getStatus());
        response.setTotalScore(record.getTotalScore());
        response.setTimeSpent(record.getTimeSpent());
        response.setStartTime(record.getStartTime());
        response.setSubmitTime(record.getSubmitTime());
        response.setGradedTime(record.getGradedTime());
        return response;
    }

    private String getPaperTitle(String paperId) {
        ExamPaper paper = examPaperMapper.selectOne(
            new LambdaQueryWrapper<ExamPaper>().eq(ExamPaper::getPaperId, paperId));
        return paper != null ? paper.getTitle() : "";
    }

    }