import { Request, Response } from 'express';
import { QuestionModel, CreateQuestionData, ExcelQuestionData } from '../models';
import * as XLSX from 'xlsx';

export class QuestionController {
  // 获取题目列表
  static async getQuestions(req: Request, res: Response) {
    try {
      const { type, category, keyword, startDate, endDate, page = 1, limit = 10 } = req.query;
      
      const result = await QuestionModel.findAll({
        type: type as string,
        category: category as string,
        keyword: keyword as string,
        startDate: startDate as string,
        endDate: endDate as string,
        limit: parseInt(limit as string),
        offset: (parseInt(page as string) - 1) * parseInt(limit as string)
      });
      
      res.json({
        success: true,
        data: result.questions,
        pagination: {
          page: parseInt(page as string),
          limit: parseInt(limit as string),
          total: result.total,
          pages: Math.ceil(result.total / parseInt(limit as string))
        }
      });
    } catch (error: any) {
      console.error('获取题目列表失败:', error);
      res.status(500).json({
        success: false,
        message: error.message || '获取题目列表失败'
      });
    }
  }

  // 获取单个题目
  static async getQuestion(req: Request, res: Response) {
    try {
      const { id } = req.params;
      
      const question = await QuestionModel.findById(id);
      if (!question) {
        return res.status(404).json({
          success: false,
          message: '题目不存在'
        });
      }
      
      res.json({
        success: true,
        data: question
      });
    } catch (error: any) {
      console.error('获取题目失败:', error);
      res.status(500).json({
        success: false,
        message: error.message || '获取题目失败'
      });
    }
  }

  // 创建题目
  static async createQuestion(req: Request, res: Response) {
    try {
      const { content, type, category, options, answer, analysis, score } = req.body;
      
      const questionData: CreateQuestionData = {
        content,
        type,
        category,
        options,
        answer,
        analysis,
        score
      };
      
      // 验证题目数据
      const errors = QuestionModel.validateQuestionData(questionData);
      if (errors.length > 0) {
        return res.status(400).json({
          success: false,
          message: '数据验证失败',
          errors
        });
      }
      
      const question = await QuestionModel.create(questionData);
      
      res.json({
        success: true,
        data: question
      });
    } catch (error: any) {
      console.error('创建题目失败:', error);
      res.status(500).json({
        success: false,
        message: error.message || '创建题目失败'
      });
    }
  }

  // 更新题目
  static async updateQuestion(req: Request, res: Response) {
    try {
      const { id } = req.params;
      const { content, type, category, options, answer, analysis, score } = req.body;
      
      const updateData: Partial<CreateQuestionData> = {};
      if (content !== undefined) updateData.content = content;
      if (type !== undefined) updateData.type = type;
      if (category !== undefined) updateData.category = category;
      if (options !== undefined) updateData.options = options;
      if (answer !== undefined) updateData.answer = answer;
      if (analysis !== undefined) updateData.analysis = analysis;
      if (score !== undefined) updateData.score = score;
      
      const question = await QuestionModel.update(id, updateData);
      
      res.json({
        success: true,
        data: question
      });
    } catch (error: any) {
      console.error('更新题目失败:', error);
      res.status(500).json({
        success: false,
        message: error.message || '更新题目失败'
      });
    }
  }

  // 删除题目
  static async deleteQuestion(req: Request, res: Response) {
    try {
      const { id } = req.params;
      
      const success = await QuestionModel.delete(id);
      if (!success) {
        return res.status(404).json({
          success: false,
          message: '题目不存在'
        });
      }
      
      res.json({
        success: true,
        message: '删除成功'
      });
    } catch (error: any) {
      console.error('删除题目失败:', error);
      res.status(500).json({
        success: false,
        message: error.message || '删除题目失败'
      });
    }
  }

  // Excel导入题目
  static async importQuestions(req: Request, res: Response) {
    try {
      if (!req.file) {
        return res.status(400).json({
          success: false,
          message: '请上传Excel文件'
        });
      }
      
      // 读取Excel文件
      const workbook = XLSX.read(req.file.buffer, { type: 'buffer' });
      const sheetName = workbook.SheetNames[0];
      const worksheet = workbook.Sheets[sheetName];
      
      // 转换为JSON数据
      const rawData = XLSX.utils.sheet_to_json(worksheet);
      
      // 转换数据格式
      const questionsData: ExcelQuestionData[] = rawData.map((row: any) => ({
        content: row['题目内容'] || row['content'],
        type: QuestionController.mapQuestionType(row['题型'] || row['type']),
        category: row['题目类别'] || row['category'] || '通用',
        answer: row['标准答案'] || row['answer'],
        analysis: row['解析'] || row['analysis'] || '',
        score: parseInt(row['分值'] || row['score']) || 0,
        options: QuestionController.parseOptions(row['选项'] || row['options'])
      }));
      
      // 验证数据
      const validation = QuestionModel.validateExcelData(questionsData);
      if (!validation.valid) {
        return res.status(400).json({
          success: false,
          message: 'Excel数据格式错误',
          errors: validation.errors
        });
      }
      
      // 批量创建题目
      const result = await QuestionModel.createMany(questionsData as any[]);
      
      res.json({
        success: true,
        data: {
          imported: result.success,
          total: questionsData.length,
          errors: result.errors
        }
      });
    } catch (error: any) {
      console.error('Excel导入失败:', error);
      res.status(500).json({
        success: false,
        message: error.message || 'Excel导入失败'
      });
    }
  }

  static async importTextQuestions(req: Request, res: Response) {
    try {
      const mode = req.body?.mode as 'overwrite' | 'incremental';
      const rawQuestions = req.body?.questions as any[];

      if (mode !== 'overwrite' && mode !== 'incremental') {
        return res.status(400).json({
          success: false,
          message: '导入模式不合法',
        });
      }

      if (!Array.isArray(rawQuestions) || rawQuestions.length === 0) {
        return res.status(400).json({
          success: false,
          message: '题目列表不能为空',
        });
      }

      const errors: string[] = [];
      const normalized = new Map<string, CreateQuestionData>();

      const normalizeAnswer = (type: string, answer: unknown): string | string[] => {
        if (type === 'multiple') {
          if (Array.isArray(answer)) {
            return answer.map((a) => String(a).trim()).filter(Boolean);
          }
          return String(answer || '')
            .split(/[|,，、\s]+/g)
            .map((s) => s.trim())
            .filter(Boolean);
        }
        if (Array.isArray(answer)) {
          return String(answer[0] ?? '').trim();
        }
        return String(answer ?? '').trim();
      };

      const normalizeJudgment = (answer: string) => {
        const v = String(answer || '').trim();
        const yes = new Set(['正确', '对', '是', 'true', 'True', 'TRUE', '1', 'Y', 'y', 'yes', 'YES']);
        const no = new Set(['错误', '错', '否', '不是', 'false', 'False', 'FALSE', '0', 'N', 'n', 'no', 'NO']);
        if (yes.has(v)) return '正确';
        if (no.has(v)) return '错误';
        return v;
      };

      for (let i = 0; i < rawQuestions.length; i++) {
        const q = rawQuestions[i] || {};
        const content = String(q.content ?? '').trim();
        if (!content) {
          errors.push(`第${i + 1}题：题目内容不能为空`);
          continue;
        }

        const type = QuestionController.mapQuestionType(String(q.type ?? '').trim());
        const category = String(q.category ?? '通用').trim() || '通用';
        const score = Number(q.score);
        const options = Array.isArray(q.options) ? q.options.map((o: any) => String(o).trim()).filter(Boolean) : undefined;
        let answer = normalizeAnswer(type, q.answer);
        const analysis = String(q.analysis ?? '').trim();

        if (type === 'judgment' && typeof answer === 'string') {
          answer = normalizeJudgment(answer);
        }

        const questionData: CreateQuestionData = {
          content,
          type: type as any,
          category,
          options: type === 'single' || type === 'multiple' ? options : undefined,
          answer: answer as any,
          analysis,
          score,
        };

        const validationErrors = QuestionModel.validateQuestionData(questionData);
        if (validationErrors.length > 0) {
          errors.push(`第${i + 1}题：${validationErrors.join('；')}`);
          continue;
        }

        normalized.set(content, questionData);
      }

      if (errors.length > 0) {
        return res.status(400).json({
          success: false,
          message: '数据验证失败',
          errors,
        });
      }

      const result = await QuestionModel.importFromText(mode, Array.from(normalized.values()));
      res.json({
        success: true,
        data: {
          mode,
          total: normalized.size,
          inserted: result.inserted,
          updated: result.updated,
          errors: result.errors,
          cleared: result.cleared ?? undefined,
        },
      });
    } catch (error: any) {
      console.error('文本导入失败:', error);
      res.status(500).json({
        success: false,
        message: error.message || '文本导入失败',
      });
    }
  }

  // 映射题型
  private static mapQuestionType(type: string): string {
    const typeMap: { [key: string]: string } = {
      '单选': 'single',
      '多选': 'multiple',
      '判断': 'judgment',
      '文字描述': 'text',
      'single': 'single',
      'multiple': 'multiple',
      'judgment': 'judgment',
      'text': 'text'
    };
    
    return typeMap[type] || 'single';
  }

  // 解析选项
  private static parseOptions(optionsStr: string): string[] | undefined {
    if (!optionsStr) return undefined;
    
    // 支持多种分隔符：|、;、\n
    const separators = ['|', ';', '\n'];
    for (const separator of separators) {
      if (optionsStr.includes(separator)) {
        return optionsStr.split(separator).map(opt => opt.trim()).filter(opt => opt);
      }
    }
    
    // 如果没有找到分隔符，返回单个选项
    return [optionsStr.trim()];
  }

  // Excel导出题目
  static async exportQuestions(req: Request, res: Response) {
    try {
      const { type, category } = req.query;
      
      // 获取所有题目数据（使用大的limit值获取所有题目）
      const result = await QuestionModel.findAll({ 
        type: type as string, 
        category: category as string,
        limit: 10000, // 使用大的limit值获取所有题目
        offset: 0
      });
      
      const questions = result.questions;
      
      // 转换为Excel数据格式
      const excelData = questions.map((question: any) => ({
        '题目ID': question.id,
        '题目内容': question.content,
        '题型': this.getQuestionTypeLabel(question.type),
        '题目类别': question.category || '通用',
        '选项': question.options ? question.options.join('|') : '',
        '标准答案': question.answer,
        '解析': question.analysis || '',
        '分值': question.score,
        '创建时间': new Date(question.createdAt).toLocaleString()
      }));
      
      // 创建Excel工作簿和工作表
      const workbook = XLSX.utils.book_new();
      const worksheet = XLSX.utils.json_to_sheet(excelData);
      
      // 设置列宽
      const columnWidths = [
        { wch: 10 }, // 题目ID
        { wch: 60 }, // 题目内容
        { wch: 10 }, // 题型
        { wch: 15 }, // 题目类别
        { wch: 80 }, // 选项
        { wch: 20 }, // 标准答案
        { wch: 8 },  // 分值
        { wch: 20 }  // 创建时间
      ];
      worksheet['!cols'] = columnWidths;
      
      // 将工作表添加到工作簿
      XLSX.utils.book_append_sheet(workbook, worksheet, '题目列表');
      
      // 设置响应头
      res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
      res.setHeader('Content-Disposition', `attachment; filename=questions_${new Date().getTime()}.xlsx`);
      
      // 生成Excel文件并发送
      const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'buffer' });
      res.send(excelBuffer);
    } catch (error: any) {
      console.error('Excel导出失败:', error);
      res.status(500).json({
        success: false,
        message: error.message || 'Excel导出失败'
      });
    }
  }

  // 获取题型中文标签
  private static getQuestionTypeLabel(type: string): string {
    const typeMap: { [key: string]: string } = {
      'single': '单选题',
      'multiple': '多选题',
      'judgment': '判断题',
      'text': '文字题'
    };
    
    return typeMap[type] || type;
  }
}
