import { v4 as uuidv4 } from 'uuid';
import { query, run, get } from '../database';

export interface Question {
  id: string;
  content: string;
  type: 'single' | 'multiple' | 'judgment' | 'text';
  category: string;
  options?: string[];
  answer: string | string[];
  analysis: string;
  score: number;
  createdAt: string;
}

export interface CreateQuestionData {
  content: string;
  type: 'single' | 'multiple' | 'judgment' | 'text';
  category?: string;
  options?: string[];
  answer: string | string[];
  analysis?: string;
  score: number;
}

export interface ExcelQuestionData {
  content: string;
  type: string;
  category?: string;
  answer: string;
  analysis?: string;
  score: number;
  options?: string[];
}

export class QuestionModel {
  private static normalizeJudgmentAnswer(raw: unknown): string {
    const v = String(raw ?? '').trim();
    if (!v) return v;

    // 兼容历史存储与导入：A/B、T/F、true/false、1/0 等
    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;
  }

  // 创建题目
  static async create(data: CreateQuestionData): Promise<Question> {
    const id = uuidv4();
    const optionsStr = data.options ? JSON.stringify(data.options) : null;
    const rawAnswer = (data as any).answer;
    const normalizedAnswer =
      data.type === 'judgment' && !Array.isArray(rawAnswer)
        ? this.normalizeJudgmentAnswer(rawAnswer)
        : rawAnswer;
    const answerStr = Array.isArray(normalizedAnswer) ? JSON.stringify(normalizedAnswer) : String(normalizedAnswer ?? '');
    const category = data.category && data.category.trim() ? data.category.trim() : '通用';
    const analysis = String(data.analysis ?? '').trim().slice(0, 255);
    
    const sql = `
      INSERT INTO questions (id, content, type, options, answer, analysis, score, category) 
      VALUES (?, ?, ?, ?, ?, ?, ?, ?)
    `;
    
    await run(sql, [id, data.content, data.type, optionsStr, answerStr, analysis, data.score, category]);
    return this.findById(id) as Promise<Question>;
  }

  // 批量创建题目 - 优化为使用事务批量插入
  static async createMany(questions: CreateQuestionData[]): Promise<{ success: number; errors: string[] }> {
    const errors: string[] = [];
    let success = 0;
    
    // 使用事务提高性能
    try {
      // 开始事务
      await run('BEGIN TRANSACTION');
      
      const sql = `
        INSERT INTO questions (id, content, type, options, answer, analysis, score, category) 
        VALUES (?, ?, ?, ?, ?, ?, ?, ?)
      `;
      
      for (let i = 0; i < questions.length; i++) {
        try {
          const question = questions[i];
          const id = uuidv4();
          const optionsStr = question.options ? JSON.stringify(question.options) : null;
          const rawAnswer = (question as any).answer;
          const normalizedAnswer =
            question.type === 'judgment' && !Array.isArray(rawAnswer)
              ? this.normalizeJudgmentAnswer(rawAnswer)
              : rawAnswer;
          const answerStr = Array.isArray(normalizedAnswer) ? JSON.stringify(normalizedAnswer) : String(normalizedAnswer ?? '');
          const category = question.category && question.category.trim() ? question.category.trim() : '通用';
          const analysis = String(question.analysis ?? '').trim().slice(0, 255);
          
          // 直接执行插入，不调用单个create方法
          await run(sql, [id, question.content, question.type, optionsStr, answerStr, analysis, question.score, category]);
          success++;
        } catch (error: any) {
          errors.push(`第${i + 1}题: ${error.message}`);
        }
      }
      
      // 提交事务
      await run('COMMIT');
    } catch (error: any) {
      // 回滚事务
      await run('ROLLBACK');
      errors.push(`事务错误: ${error.message}`);
    }
    
    return { success, errors };
  }

  static async importFromText(
    mode: 'overwrite' | 'incremental',
    questions: CreateQuestionData[],
  ): Promise<{
    inserted: number;
    updated: number;
    errors: string[];
    cleared?: { questions: number; quizRecords: number; quizAnswers: number };
  }> {
    const errors: string[] = [];
    let inserted = 0;
    let updated = 0;
    let cleared: { questions: number; quizRecords: number; quizAnswers: number } | undefined;

    const insertSql = `
      INSERT INTO questions (id, content, type, options, answer, analysis, score, category)
      VALUES (?, ?, ?, ?, ?, ?, ?, ?)
    `;

    await run('BEGIN TRANSACTION');
    try {
      if (mode === 'overwrite') {
        const [qCount, rCount, aCount] = await Promise.all([
          get(`SELECT COUNT(*) as total FROM questions`),
          get(`SELECT COUNT(*) as total FROM quiz_records`),
          get(`SELECT COUNT(*) as total FROM quiz_answers`),
        ]);
        cleared = { questions: qCount.total, quizRecords: rCount.total, quizAnswers: aCount.total };

        await run(`DELETE FROM quiz_answers`);
        await run(`DELETE FROM quiz_records`);
        await run(`DELETE FROM questions`);
      }

      for (let i = 0; i < questions.length; i++) {
        const question = questions[i];
        try {
          const optionsStr = question.options ? JSON.stringify(question.options) : null;
          const rawAnswer = (question as any).answer;
          const normalizedAnswer =
            question.type === 'judgment' && !Array.isArray(rawAnswer)
              ? this.normalizeJudgmentAnswer(rawAnswer)
              : rawAnswer;
          const answerStr = Array.isArray(normalizedAnswer) ? JSON.stringify(normalizedAnswer) : String(normalizedAnswer ?? '');
          const category = question.category && question.category.trim() ? question.category.trim() : '通用';
          const analysis = String(question.analysis ?? '').trim().slice(0, 255);

          if (mode === 'incremental') {
            const existing = await get(`SELECT id FROM questions WHERE content = ?`, [question.content]);
            if (existing?.id) {
              await run(
                `UPDATE questions SET content = ?, type = ?, options = ?, answer = ?, analysis = ?, score = ?, category = ? WHERE id = ?`,
                [question.content, question.type, optionsStr, answerStr, analysis, question.score, category, existing.id],
              );
              updated++;
              continue;
            }
          }

          const id = uuidv4();
          await run(insertSql, [id, question.content, question.type, optionsStr, answerStr, analysis, question.score, category]);
          inserted++;
        } catch (error: any) {
          errors.push(`第${i + 1}题: ${error.message}`);
        }
      }

      await run('COMMIT');
    } catch (error) {
      await run('ROLLBACK');
      throw error;
    }

    return { inserted, updated, errors, cleared };
  }

  // 根据ID查找题目
  static async findById(id: string): Promise<Question | null> {
    const sql = `SELECT * FROM questions WHERE id = ?`;
    const question = await get(sql, [id]);
    
    if (!question) return null;
    
    return this.formatQuestion(question);
  }

  // 根据题目内容查找题目
  static async findByContent(content: string): Promise<Question | null> {
    const sql = `SELECT * FROM questions WHERE content = ?`;
    const question = await get(sql, [content]);
    
    if (!question) return null;
    
    return this.formatQuestion(question);
  }

  // 获取题目列表（支持筛选和分页）
  static async findAll(filters: {
    type?: string;
    category?: string;
    keyword?: string;
    startDate?: string;
    endDate?: string;
    limit?: number;
    offset?: number;
  } = {}): Promise<{ questions: Question[]; total: number }> {
    const { type, category, keyword, startDate, endDate, limit = 10, offset = 0 } = filters;
    
    const whereParts: string[] = [];
    const params: any[] = [];
    
    if (type) {
      whereParts.push('type = ?');
      params.push(type);
    }

    if (category) {
      whereParts.push('category = ?');
      params.push(category);
    }

    if (keyword) {
      whereParts.push('content LIKE ?');
      params.push(`%${keyword}%`);
    }

    if (startDate) {
      whereParts.push('created_at >= ?');
      params.push(`${startDate} 00:00:00`);
    }

    if (endDate) {
      whereParts.push('created_at <= ?');
      params.push(`${endDate} 23:59:59`);
    }

    const whereClause = whereParts.length > 0 ? `WHERE ${whereParts.join(' AND ')}` : '';
    
    const questionsSql = `
      SELECT * FROM questions 
      ${whereClause}
      ORDER BY created_at DESC 
      LIMIT ? OFFSET ?
    `;
    
    const countSql = `
      SELECT COUNT(*) as total FROM questions ${whereClause}
    `;
    
    const [questions, countResult] = await Promise.all([
      query(questionsSql, [...params, limit, offset]),
      get(countSql, params)
    ]);
    
    return {
      questions: questions.map((q) => this.formatQuestion(q)),
      total: countResult.total
    };
  }

  // 随机获取题目（按类型和数量）
  static async getRandomQuestions(type: string, count: number, categories?: string[]): Promise<Question[]> {
    const whereParts: string[] = ['type = ?'];
    const params: any[] = [type];

    if (categories && categories.length > 0) {
      whereParts.push(`category IN (${categories.map(() => '?').join(',')})`);
      params.push(...categories);
    }

    const sql = `
      SELECT * FROM questions 
      WHERE ${whereParts.join(' AND ')}
      ORDER BY RANDOM() 
      LIMIT ?
    `;
    
    const questions = await query(sql, [...params, count]);
    return questions.map((q) => this.formatQuestion(q));
  }

  // 更新题目
  static async update(id: string, data: Partial<CreateQuestionData>): Promise<Question> {
    const fields: string[] = [];
    const values: any[] = [];
    
    if (data.content) {
      fields.push('content = ?');
      values.push(data.content);
    }
    
    if (data.type) {
      fields.push('type = ?');
      values.push(data.type);
    }
    
    if (data.options !== undefined) {
      fields.push('options = ?');
      values.push(data.options ? JSON.stringify(data.options) : null);
    }
    
    if (data.answer !== undefined) {
      const rawAnswer = (data as any).answer;
      const normalizedAnswer =
        data.type === 'judgment' && !Array.isArray(rawAnswer)
          ? this.normalizeJudgmentAnswer(rawAnswer)
          : rawAnswer;
      const answerStr = Array.isArray(normalizedAnswer) ? JSON.stringify(normalizedAnswer) : String(normalizedAnswer ?? '');
      fields.push('answer = ?');
      values.push(answerStr);
    }

    if (data.analysis !== undefined) {
      fields.push('analysis = ?');
      values.push(String(data.analysis ?? '').trim().slice(0, 255));
    }
    
    if (data.score !== undefined) {
      fields.push('score = ?');
      values.push(data.score);
    }

    if (data.category !== undefined) {
      fields.push('category = ?');
      values.push(data.category && data.category.trim() ? data.category.trim() : '通用');
    }
    
    if (fields.length === 0) {
      throw new Error('没有要更新的字段');
    }
    
    values.push(id);
    const sql = `UPDATE questions SET ${fields.join(', ')} WHERE id = ?`;
    
    await run(sql, values);
    return this.findById(id) as Promise<Question>;
  }

  // 删除题目
  static async delete(id: string): Promise<boolean> {
    const sql = `DELETE FROM questions WHERE id = ?`;
    const result = await run(sql, [id]);
    return result.id !== undefined;
  }

  // 格式化题目数据
  private static formatQuestion(row: any): Question {
    return {
      id: row.id,
      content: row.content,
      type: row.type,
      category: row.category || '通用',
      options: row.options ? JSON.parse(row.options) : undefined,
      answer: this.parseAnswer(row.answer, row.type),
      analysis: String(row.analysis ?? ''),
      score: row.score,
      createdAt: row.created_at
    };
  }

  // 解析答案
  private static parseAnswer(answerStr: string, type: string): string | string[] {
    if (type === 'multiple') {
      try {
        return JSON.parse(answerStr);
      } catch {
        return answerStr;
      }
    }
    if (type === 'judgment') {
      return this.normalizeJudgmentAnswer(answerStr);
    }
    return answerStr;
  }

  // 验证题目数据
  static validateQuestionData(data: CreateQuestionData): string[] {
    const errors: string[] = [];
    
    // 验证题目内容
    if (!data.content || data.content.trim().length === 0) {
      errors.push('题目内容不能为空');
    }
    
    // 验证题型
    const validTypes = ['single', 'multiple', 'judgment', 'text'];
    if (!validTypes.includes(data.type)) {
      errors.push('题型必须是 single、multiple、judgment 或 text');
    }
    
    // 验证选项
    if (data.type === 'single' || data.type === 'multiple') {
      if (!data.options || data.options.length < 2) {
        errors.push('单选题和多选题必须至少包含2个选项');
      }
    }
    
    // 验证答案
    const score = Number((data as any).score);
    const allowEmptyAnswer = Number.isFinite(score) && score === 0;
    if (!allowEmptyAnswer) {
      const ans = (data as any).answer;
      const isEmptyArray = Array.isArray(ans) && ans.length === 0;
      const isEmptyString = typeof ans === 'string' && ans.trim().length === 0;
      if (ans === undefined || ans === null || isEmptyArray || isEmptyString) {
        errors.push('答案不能为空');
      }
    }
    
    // 验证分值
    if (!Number.isFinite(score) || score < 0) {
      errors.push('分值必须是非负数');
    }

    if (data.category !== undefined && data.category.trim().length === 0) {
      errors.push('题目类别不能为空');
    }

    if (data.analysis !== undefined && String(data.analysis).length > 255) {
      errors.push('解析长度不能超过255个字符');
    }
    
    return errors;
  }

  // 验证Excel数据格式
  static validateExcelData(data: ExcelQuestionData[]): { valid: boolean; errors: string[] } {
    const errors: string[] = [];
    
    data.forEach((row, index) => {
      if (!row.content) {
        errors.push(`第${index + 1}行：题目内容不能为空`);
      }
      
      const validTypes = ['single', 'multiple', 'judgment', 'text'];
      if (!validTypes.includes(row.type)) {
        errors.push(`第${index + 1}行：题型必须是 single、multiple、judgment 或 text`);
      }
      
      const score = Number((row as any).score);
      const allowEmptyAnswer = Number.isFinite(score) && score === 0;
      const ans = (row as any).answer;
      const isEmptyString = typeof ans === 'string' && ans.trim().length === 0;
      if (!allowEmptyAnswer && (ans === undefined || ans === null || isEmptyString)) {
        errors.push(`第${index + 1}行：答案不能为空`);
      }
      
      if (!Number.isFinite(score) || score < 0) {
        errors.push(`第${index + 1}行：分值必须是非负数`);
      }
    });
    
    return {
      valid: errors.length === 0,
      errors
    };
  }
}
