import { Request, Response } from 'express';
import { QuestionModel, QuizModel, SystemConfigModel } from '../models';
import { Question } from '../models/question';

export class QuizController {
  static async generateQuiz(req: Request, res: Response) {
    try {
      const { userId, subjectId, taskId } = req.body;

      if (!userId) {
        return res.status(400).json({
          success: false,
          message: '用户ID不能为空'
        });
      }

      if (taskId) {
        const { ExamTaskModel } = await import('../models/examTask');
        const result = await ExamTaskModel.generateQuizQuestions(taskId, userId);
        res.json({
          success: true,
          data: {
            questions: result.questions,
            totalScore: result.totalScore,
            timeLimit: result.timeLimitMinutes
          }
        });
        return;
      }

      if (!subjectId) {
        return res.status(400).json({
          success: false,
          message: 'subjectId或taskId必须提供其一'
        });
      }

      const { ExamSubjectModel } = await import('../models/examSubject');
      const subject = await ExamSubjectModel.findById(subjectId);
      if (!subject) {
        return res.status(404).json({
          success: false,
          message: '考试科目不存在'
        });
      }

      const result = await ExamSubjectModel.generateQuizQuestions(subject);

      res.json({
        success: true,
        data: {
          questions: result.questions,
          totalScore: result.totalScore,
          timeLimit: result.timeLimitMinutes
        }
      });
    } catch (error: any) {
      const message = error?.message || '生成试卷失败';
      const status = message.includes('不存在')
        ? 404
        : [
            '用户ID不能为空',
            'subjectId或taskId必须提供其一',
            '当前时间不在任务有效范围内',
            '用户未被分派到此任务',
            '考试次数已用尽',
          ].some((m) => message.includes(m))
          ? 400
          : 500;
      res.status(status).json({
        success: false,
        message,
      });
    }
  }

  static async submitQuiz(req: Request, res: Response) {
    try {
      const { userId, subjectId, taskId, answers } = req.body;

      if (!userId || !answers || !Array.isArray(answers)) {
        return res.status(400).json({
          success: false,
          message: '参数不完整'
        });
      }

      const processedAnswers = [];
      let totalPossibleScore = 0;
      for (const answer of answers) {
        const question = await QuestionModel.findById(answer.questionId);
        if (!question) {
          processedAnswers.push(answer);
          continue;
        }

        totalPossibleScore += Number(question.score) || 0;

        if (answer.userAnswer === undefined || answer.userAnswer === null) {
          answer.userAnswer = '';
        }

        // 规则：分值为0的题目不判定正误，不要求答案，默认正确
        if (Number(question.score) === 0) {
          answer.score = 0;
          answer.isCorrect = true;
          processedAnswers.push(answer);
          continue;
        }

        if (question.type === 'multiple') {
          const optionCount = question.options ? question.options.length : 0;
          const unitScore = optionCount > 0 ? question.score / optionCount : 0;
          let userAnsList: string[] = [];
          if (Array.isArray(answer.userAnswer)) {
            userAnsList = answer.userAnswer;
          } else if (typeof answer.userAnswer === 'string') {
            try {
              userAnsList = JSON.parse(answer.userAnswer);
            } catch (e) {
              userAnsList = [answer.userAnswer];
            }
          }

          let correctAnsList: string[] = [];
          if (Array.isArray(question.answer)) {
            correctAnsList = question.answer;
          } else if (typeof question.answer === 'string') {
            try {
              const parsed = JSON.parse(question.answer);
              if (Array.isArray(parsed)) correctAnsList = parsed;
              else correctAnsList = [question.answer];
            } catch {
              correctAnsList = [question.answer];
            }
          }

          const userSet = new Set(userAnsList);
          const correctSet = new Set(correctAnsList);
          let isFullCorrect = true;
          if (userSet.size !== correctSet.size) {
            isFullCorrect = false;
          } else {
            for (const a of userSet) {
              if (!correctSet.has(a)) {
                isFullCorrect = false;
                break;
              }
            }
          }

          if (isFullCorrect) {
            answer.score = question.score;
            answer.isCorrect = true;
          } else {
            let tempScore = 0;
            for (const uAns of userAnsList) {
              if (correctSet.has(uAns)) {
                tempScore += unitScore;
              } else {
                tempScore -= unitScore;
              }
            }
            let finalScore = Math.max(0, tempScore);
            finalScore = Math.round(finalScore * 10) / 10;
            answer.score = finalScore;
            answer.isCorrect = false;
          }
        } else if (question.type === 'single' || question.type === 'judgment') {
          const normalizeJudgment = (raw: unknown) => {
            const v = String(raw ?? '').trim();
            const yes = new Set(['A', 'T', 'TRUE', 'True', 'true', '1', '正确', '对', '是', 'Y', 'y', 'YES', 'yes']);
            const no = new Set(['B', 'F', 'FALSE', 'False', 'false', '0', '错误', '错', '否', '不是', 'N', 'n', 'NO', 'no']);
            if (yes.has(v)) return '正确';
            if (no.has(v)) return '错误';
            return v;
          };

          const isCorrect =
            question.type === 'judgment'
              ? normalizeJudgment(answer.userAnswer) === normalizeJudgment(question.answer)
              : answer.userAnswer === question.answer;
          answer.score = isCorrect ? question.score : 0;
          answer.isCorrect = isCorrect;
        }

        processedAnswers.push(answer);
      }

      const result = await QuizModel.submitQuiz({ userId, answers: processedAnswers, totalPossibleScore });

      if (subjectId || taskId) {
        let finalSubjectId: string | null = subjectId || null;
        const finalTaskId: string | null = taskId || null;

        // 任务考试场景下，如果前端未传subjectId，则从任务中反查
        if (!finalSubjectId && finalTaskId) {
          const { ExamTaskModel } = await import('../models/examTask');
          const task = await ExamTaskModel.findById(finalTaskId);
          if (task?.subjectId) {
            finalSubjectId = task.subjectId;
          }
        }

        const sql = `
          UPDATE quiz_records 
          SET subject_id = ?, task_id = ? 
          WHERE id = ?
        `;
        await import('../database').then(({ run }) => run(sql, [finalSubjectId, finalTaskId, result.record.id]));
      }

      res.json({
        success: true,
        data: {
          recordId: result.record.id,
          totalScore: result.record.totalScore,
          correctCount: result.record.correctCount,
          totalCount: result.record.totalCount
        }
      });
    } catch (error: any) {
      res.status(500).json({
        success: false,
        message: error.message || '提交答题失败'
      });
    }
  }

  static async getUserRecords(req: Request, res: Response) {
    try {
      const { userId } = req.params;
      const page = parseInt(req.query.page as string) || 1;
      const limit = parseInt(req.query.limit as string) || 10;
      
      const result = await QuizModel.findRecordsByUserId(userId, limit, (page - 1) * limit);
      
      res.json({
        success: true,
        data: result.records,
        pagination: {
          page,
          limit,
          total: result.total,
          pages: Math.ceil(result.total / limit)
        }
      });
    } catch (error: any) {
      res.status(500).json({
        success: false,
        message: error.message || '获取答题记录失败'
      });
    }
  }

  static async getRecordDetail(req: Request, res: Response) {
    try {
      const { recordId } = req.params;
      
      const record = await QuizModel.findRecordById(recordId);
      if (!record) {
        return res.status(404).json({
          success: false,
          message: '答题记录不存在'
        });
      }
      
      const answers = await QuizModel.findAnswersByRecordId(recordId);
      
      res.json({
        success: true,
        data: {
          record,
          answers
        }
      });
    } catch (error: any) {
      res.status(500).json({
        success: false,
        message: error.message || '获取答题记录详情失败'
      });
    }
  }

  static async getAllRecords(req: Request, res: Response) {
    try {
      const page = parseInt(req.query.page as string) || 1;
      const limit = parseInt(req.query.limit as string) || 10;
      
      const result = await QuizModel.findAllRecords(limit, (page - 1) * limit);
      
      res.json({
        success: true,
        data: result.records,
        pagination: {
          page,
          limit,
          total: result.total,
          pages: Math.ceil(result.total / limit)
        }
      });
    } catch (error: any) {
      res.status(500).json({
        success: false,
        message: error.message || '获取答题记录失败'
      });
    }
  }
}
