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

export interface QuestionCategory {
  id: string;
  name: string;
  createdAt: string;
}

export interface QuestionCategoryWithQuestionCount extends QuestionCategory {
  questionCount: number;
}

export class QuestionCategoryModel {
  // 获取所有题目类别，包括从题目表中聚合的新类别
  static async findAll(): Promise<QuestionCategory[]> {
    try {
      // 1. 首先从题目表中聚合所有唯一类别
      const questionCategoriesSql = `
        SELECT DISTINCT category as name
        FROM questions
        WHERE category IS NOT NULL AND category != ''
      `;
      const questionCategories = await query(questionCategoriesSql);
      
      // 2. 获取现有类别表中的类别
      const existingCategoriesSql = `
        SELECT id, name, created_at as createdAt
        FROM question_categories
        ORDER BY created_at DESC
      `;
      const existingCategories = await query(existingCategoriesSql);
      
      // 3. 创建现有类别名称的映射，用于快速查找
      const existingCategoryNames = new Set(existingCategories.map(cat => cat.name));
      
      // 4. 找出题目表中存在但类别表中不存在的新类别
      const newCategories = questionCategories.filter(qCat => !existingCategoryNames.has(qCat.name));
      
      // 5. 批量创建新类别
      if (newCategories.length > 0) {
        await run('BEGIN TRANSACTION');
        
        const createSql = `INSERT INTO question_categories (id, name) VALUES (?, ?)`;
        for (const newCat of newCategories) {
          await run(createSql, [uuidv4(), newCat.name]);
        }
        
        await run('COMMIT');
        
        // 6. 重新获取所有类别，包括新创建的
        return this.findAll();
      }
      
      // 如果没有新类别，直接返回现有类别
      return existingCategories;
    } catch (error: any) {
      try {
        // 如果事务失败，尝试回滚
        await run('ROLLBACK');
      } catch (rollbackError) {
        // 回滚失败，忽略
      }
      
      console.error('获取题目类别失败:', error);
      
      // 回退到原始逻辑，尝试返回基本的类别列表
      try {
        const sql = `SELECT id, name, created_at as createdAt FROM question_categories ORDER BY created_at DESC`;
        return await query(sql);
      } catch (fallbackError) {
        // 如果所有数据库操作都失败，返回一个默认类别
        return [{ id: 'default', name: '通用', createdAt: new Date().toISOString() }];
      }
    }
  }

  static async findById(id: string): Promise<QuestionCategory | null> {
    const sql = `SELECT id, name, created_at as createdAt FROM question_categories WHERE id = ?`;
    const row = await get(sql, [id]);
    return row || null;
  }

  static async create(name: string): Promise<QuestionCategory> {
    const trimmed = name.trim();
    if (!trimmed) throw new Error('类别名称不能为空');

    const id = uuidv4();
    const sql = `INSERT INTO question_categories (id, name) VALUES (?, ?)`;

    try {
      await run(sql, [id, trimmed]);
    } catch (error: any) {
      if (error.code === 'SQLITE_CONSTRAINT_UNIQUE') {
        throw new Error('类别名称已存在');
      }
      throw error;
    }

    return (await this.findById(id)) as QuestionCategory;
  }

  static async update(id: string, name: string): Promise<QuestionCategory> {
    const existing = await this.findById(id);
    if (!existing) throw new Error('类别不存在');

    const trimmed = name.trim();
    if (!trimmed) throw new Error('类别名称不能为空');

    try {
      await run(`UPDATE question_categories SET name = ? WHERE id = ?`, [trimmed, id]);
    } catch (error: any) {
      if (error.code === 'SQLITE_CONSTRAINT_UNIQUE') {
        throw new Error('类别名称已存在');
      }
      throw error;
    }

    await run(`UPDATE questions SET category = ? WHERE category = ?`, [trimmed, existing.name]);
    return (await this.findById(id)) as QuestionCategory;
  }

  static async delete(id: string): Promise<void> {
    if (id === 'default') throw new Error('默认类别不允许删除');

    const existing = await this.findById(id);
    if (!existing) throw new Error('类别不存在');

    await run(`UPDATE questions SET category = '通用' WHERE category = ?`, [existing.name]);
    await run(`DELETE FROM question_categories WHERE id = ?`, [id]);
  }

  static async findAllWithQuestionCounts(): Promise<QuestionCategoryWithQuestionCount[]> {
    const categories = await this.findAll();

    try {
      const countSql = `
        SELECT
          COALESCE(NULLIF(TRIM(category), ''), '通用') as name,
          COUNT(*) as questionCount
        FROM questions
        GROUP BY COALESCE(NULLIF(TRIM(category), ''), '通用')
      `;
      const rows: Array<{ name: string; questionCount: number }> = await query(countSql);
      const countByName = new Map<string, number>(
        rows.map((r) => [String(r.name), Number(r.questionCount ?? 0)]),
      );

      return categories.map((c) => ({
        ...c,
        questionCount: countByName.get(c.name) ?? 0,
      }));
    } catch {
      return categories.map((c) => ({
        ...c,
        questionCount: 0,
      }));
    }
  }
}
