import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
import 'dart:io';
import 'dart:typed_data';
import '../models/data_models.dart';

/// 数据库帮助类 - 管理数据库的创建和版本控制
class DatabaseHelper {
  static final DatabaseHelper instance = DatabaseHelper._init();
  static Database? _database;

  DatabaseHelper._init();

  /// 数据库文件路径
  Future<String?> get databasePath async {
    final path = await getDatabasesPath();
    return join(path, 'mooknote.db');
  }

  /// 重新打开数据库（用于 WebDAV 同步后）
  Future<void> reopenDatabase() async {
    // 关闭现有连接
    if (_database != null) {
      await _database!.close();
      _database = null;
    }
    // 重新初始化
    _database = await _initDB('mooknote.db');
  }

  /// 从备份字节重写数据库文件并安全重连，
  /// 始终按当前代码的 targetVersion 重新初始化，避免版本不一致。
  Future<void> reopenDatabaseFromBytes(Uint8List bytes) async {
    await close();

    final dbPath = await getDatabasesPath();
    final path = join(dbPath, 'mooknote.db');

    final dbFile = File(path);
    if (await dbFile.exists()) {
      await dbFile.delete();
    }

    await dbFile.writeAsBytes(bytes, flush: true);
    _database = await _initDB('mooknote.db');
  }

  Future<Database> get database async {
    if (_database != null) return _database!;
    _database = await _initDB('mooknote.db');
    return _database!;
  }

  Future<Database> _initDB(String filePath) async {
    final dbPath = await getDatabasesPath();
    final path = join(dbPath, filePath);

    return await openDatabase(
      path,
      version: 13,
      onCreate: _createDB,
      onUpgrade: _onUpgrade,
    );
  }

  /// 数据库升级
  Future<void> _onUpgrade(Database db, int oldVersion, int newVersion) async {
    if (oldVersion < 2) {
      // 升级movies表结构
      await _upgradeMoviesTableV2(db);
    }
    if (oldVersion < 3) {
      // 升级books表结构
      await _upgradeBooksTableV3(db);
    }
    if (oldVersion < 4) {
      // 升级notes表结构
      await _upgradeNotesTableV4(db);
    }
    if (oldVersion < 5) {
      // 创建影评表和海报墙表
      await _createMovieReviewsTable(db);
      await _createMoviePostersTable(db);
    }
    if (oldVersion < 6) {
      // 为笔记表添加软删除字段
      await _upgradeNotesTableV6(db);
    }
    if (oldVersion < 7) {
      // 创建书评表和摘抄表
      await _createBookReviewsTable(db);
      await _createBookExcerptsTable(db);
    }
    if (oldVersion < 8) {
      // 确保书评表和摘抄表存在（兼容之前版本未成功创建的情况）
      await _createBookReviewsTable(db);
      await _createBookExcerptsTable(db);
    }
    if (oldVersion < 9) {
      // 为笔记表添加图片字段
      await _upgradeNotesTableV9(db);
    }
    if (oldVersion < 10) {
      // 为影视表添加观看日期字段
      await _upgradeMoviesTableV10(db);
    }
    if (oldVersion < 11) {
      // 为书籍表添加ISBN和出版时间字段
      await _upgradeBooksTableV11(db);
    }
    if (oldVersion < 12) {
      // 确保notes表有title列
      await _upgradeNotesTableV12(db);
    }
    if (oldVersion < 13) {
      await _upgradeToV13(db);
    }
  }

  /// 升级books表到V11（添加ISBN和出版时间字段）
  Future<void> _upgradeBooksTableV11(Database db) async {
    // 检查是否存在 isbn 列
    final columns = await db.rawQuery('PRAGMA table_info(books)');
    final hasIsbn = columns.any((col) => col['name'] == 'isbn');
    final hasPublishDate = columns.any((col) => col['name'] == 'publish_date');

    if (!hasIsbn) {
      await db.execute('ALTER TABLE books ADD COLUMN isbn TEXT');
    }
    if (!hasPublishDate) {
      await db.execute('ALTER TABLE books ADD COLUMN publish_date TEXT');
    }
  }

  /// 升级movies表到V10（添加观看日期字段）
  Future<void> _upgradeMoviesTableV10(Database db) async {
    // 检查是否存在 watch_date 列
    final columns = await db.rawQuery('PRAGMA table_info(movies)');
    final hasWatchDate = columns.any((col) => col['name'] == 'watch_date');

    if (!hasWatchDate) {
      await db.execute('ALTER TABLE movies ADD COLUMN watch_date TEXT');
    }
  }
  
  /// 升级notes表到V12（确保title列存在）
  Future<void> _upgradeNotesTableV12(Database db) async {
    // 检查是否存在 title 列
    final columns = await db.rawQuery('PRAGMA table_info(notes)');
    final hasTitle = columns.any((col) => col['name'] == 'title');

    if (!hasTitle) {
      await db.execute('ALTER TABLE notes ADD COLUMN title TEXT DEFAULT \'\'');
    }
  }

  /// 升级到V13：创建标签表并回填已有数据
  Future<void> _upgradeToV13(Database db) async {
    await db.execute('''
      CREATE TABLE IF NOT EXISTS tags (
        id TEXT PRIMARY KEY,
        name TEXT NOT NULL,
        type TEXT NOT NULL,
        created_at TEXT NOT NULL,
        UNIQUE(name, type)
      )
    ''');
    await _backfillTags(db);
  }

  Future<void> _backfillTags(Database db) async {
    final now = DateTime.now().toIso8601String();
    int counter = 0;

    Future<void> insertTag(String name, String type) async {
      try {
        await db.insert('tags', {
          'id': 'tag_${DateTime.now().millisecondsSinceEpoch}_${counter++}',
          'name': name,
          'type': type,
          'created_at': now,
        });
      } catch (_) {
        // 忽略 UNIQUE 约束冲突
      }
    }

    // 回填影视类型
    final movies = await db.query('movies',
        where: 'genres IS NOT NULL AND genres != ?', whereArgs: ['[]']);
    for (final row in movies) {
      for (final genre in Movie.parseStringList(row['genres'])) {
        await insertTag(genre, 'movie_genre');
      }
    }

    // 回填书籍类型
    final books = await db.query('books',
        where: 'genres IS NOT NULL AND genres != ?', whereArgs: ['[]']);
    for (final row in books) {
      for (final genre in Movie.parseStringList(row['genres'])) {
        await insertTag(genre, 'book_genre');
      }
    }

    // 回填笔记标签
    final notes = await db.query('notes',
        where: 'tags IS NOT NULL AND tags != ? AND tags != ?',
        whereArgs: ['[]', '']);
    for (final row in notes) {
      for (final tag in Movie.parseStringList(row['tags'])) {
        await insertTag(tag, 'note_tag');
      }
    }
  }

  /// 升级notes表到V9（添加图片字段）
  Future<void> _upgradeNotesTableV9(Database db) async {
    // 检查是否存在 images 列
    final columns = await db.rawQuery('PRAGMA table_info(notes)');
    final hasImages = columns.any((col) => col['name'] == 'images');
    
    if (!hasImages) {
      await db.execute('ALTER TABLE notes ADD COLUMN images TEXT');
    }
  }
  
  /// 升级notes表到V6（添加软删除字段）
  Future<void> _upgradeNotesTableV6(Database db) async {
    // 检查是否存在 is_deleted 列
    final columns = await db.rawQuery('PRAGMA table_info(notes)');
    final hasIsDeleted = columns.any((col) => col['name'] == 'is_deleted');
    
    if (!hasIsDeleted) {
      await db.execute('ALTER TABLE notes ADD COLUMN is_deleted INTEGER DEFAULT 0');
    }
  }
  
  /// 创建影评表
  Future<void> _createMovieReviewsTable(Database db) async {
    await db.execute('''
      CREATE TABLE IF NOT EXISTS movie_reviews (
        id TEXT PRIMARY KEY,
        movie_id TEXT NOT NULL,
        content TEXT NOT NULL,
        reviewer TEXT,
        source TEXT,
        review_type INTEGER DEFAULT 1,
        is_deleted INTEGER DEFAULT 0,
        created_at TEXT NOT NULL,
        updated_at TEXT NOT NULL,
        FOREIGN KEY (movie_id) REFERENCES movies (id)
      )
    ''');
  }

  /// 创建影视海报墙表
  Future<void> _createMoviePostersTable(Database db) async {
    await db.execute('''
      CREATE TABLE IF NOT EXISTS movie_posters (
        id TEXT PRIMARY KEY,
        movie_id TEXT NOT NULL,
        poster_path TEXT NOT NULL,
        is_deleted INTEGER DEFAULT 0,
        created_at TEXT NOT NULL,
        FOREIGN KEY (movie_id) REFERENCES movies (id)
      )
    ''');
  }

  /// 创建书评表
  Future<void> _createBookReviewsTable(Database db) async {
    await db.execute('''
      CREATE TABLE IF NOT EXISTS book_reviews (
        id TEXT PRIMARY KEY,
        book_id TEXT NOT NULL,
        content TEXT NOT NULL,
        reviewer TEXT,
        source TEXT,
        review_type INTEGER DEFAULT 1,
        is_deleted INTEGER DEFAULT 0,
        created_at TEXT NOT NULL,
        updated_at TEXT NOT NULL,
        FOREIGN KEY (book_id) REFERENCES books (id)
      )
    ''');
  }

  /// 创建书籍摘抄表
  Future<void> _createBookExcerptsTable(Database db) async {
    await db.execute('''
      CREATE TABLE IF NOT EXISTS book_excerpts (
        id TEXT PRIMARY KEY,
        book_id TEXT NOT NULL,
        chapter TEXT,
        content TEXT NOT NULL,
        comment TEXT,
        is_deleted INTEGER DEFAULT 0,
        created_at TEXT NOT NULL,
        updated_at TEXT NOT NULL,
        FOREIGN KEY (book_id) REFERENCES books (id)
      )
    ''');
  }
  
  /// 升级notes表到V4
  Future<void> _upgradeNotesTableV4(Database db) async {
    // 备份旧数据
    final oldData = await db.query('notes');
    
    // 删除旧表
    await db.execute('DROP TABLE IF EXISTS notes');
    
    // 创建新表
    await db.execute('''
      CREATE TABLE notes (
        id TEXT PRIMARY KEY,
        title TEXT DEFAULT '',
        content TEXT NOT NULL,
        content_type TEXT DEFAULT 'markdown',
        tags TEXT,
        created_at TEXT NOT NULL,
        updated_at TEXT NOT NULL
      )
    ''');
    
    // 迁移旧数据（将title字段恢复）
    for (final row in oldData) {
      try {
        final now = DateTime.now().toIso8601String();
        final title = row['title']?.toString() ?? '';
        final content = row['content']?.toString() ?? '';
        
        await db.insert('notes', {
          'id': row['id']?.toString() ?? DateTime.now().millisecondsSinceEpoch.toString(),
          'title': title,
          'content': content,
          'content_type': 'markdown',
          'tags': row['tags'] ?? '',
          'created_at': row['created_at']?.toString() ?? now,
          'updated_at': row['updated_at']?.toString() ?? now,
        });
      } catch (e) {
        // 忽略迁移失败的记录
      }
    }
  }
  
  /// 升级books表到V3
  Future<void> _upgradeBooksTableV3(Database db) async {
    // 备份旧数据
    final oldData = await db.query('books');
    
    // 删除旧表
    await db.execute('DROP TABLE IF EXISTS books');
    
    // 创建新表
    await db.execute('''
      CREATE TABLE books (
        id TEXT PRIMARY KEY,
        title TEXT NOT NULL,
        cover_path TEXT,
        authors TEXT,
        alternate_titles TEXT,
        publisher TEXT,
        genres TEXT,
        summary TEXT,
        rating REAL,
        status TEXT NOT NULL,
        created_at TEXT NOT NULL,
        updated_at TEXT NOT NULL,
        is_deleted INTEGER DEFAULT 0
      )
    ''');
    
    // 迁移旧数据
    for (final row in oldData) {
      try {
        final now = DateTime.now().toIso8601String();
        await db.insert('books', {
          'id': row['id']?.toString() ?? DateTime.now().millisecondsSinceEpoch.toString(),
          'title': row['title']?.toString() ?? '',
          'cover_path': row['cover'],
          'authors': row['author'] != null ? '["${row['author']}"]' : '[]',
          'alternate_titles': '[]',
          'publisher': null,
          'genres': '[]',
          'summary': row['note'],
          'rating': row['rating'],
          'status': row['status'] ?? 'want_to_read',
          'created_at': now,
          'updated_at': now,
          'is_deleted': 0,
        });
      } catch (e) {
        // 忽略迁移失败的记录
      }
    }
  }

  /// 升级movies表到V2
  Future<void> _upgradeMoviesTableV2(Database db) async {
    // 备份旧数据
    final oldData = await db.query('movies');
    
    // 删除旧表
    await db.execute('DROP TABLE IF EXISTS movies');
    
    // 创建新表
    await db.execute('''
      CREATE TABLE movies (
        id TEXT PRIMARY KEY,
        title TEXT NOT NULL,
        poster_path TEXT,
        release_date TEXT,
        directors TEXT,
        writers TEXT,
        actors TEXT,
        genres TEXT,
        alternate_titles TEXT,
        summary TEXT,
        rating REAL,
        status TEXT NOT NULL,
        created_at TEXT NOT NULL,
        updated_at TEXT NOT NULL,
        is_deleted INTEGER DEFAULT 0
      )
    ''');
    
    // 迁移旧数据（尽可能保留）
    for (final row in oldData) {
      try {
        await db.insert('movies', {
          'id': row['id']?.toString() ?? DateTime.now().millisecondsSinceEpoch.toString(),
          'title': row['title']?.toString() ?? '',
          'poster_path': row['poster_path'],
          'release_date': null,
          'directors': '[]',
          'writers': '[]',
          'actors': '[]',
          'genres': '[]',
          'alternate_titles': '[]',
          'summary': row['note'],
          'rating': row['rating'],
          'status': row['status'] ?? 'want_to_watch',
          'created_at': row['created_at']?.toString() ?? DateTime.now().toIso8601String(),
          'updated_at': DateTime.now().toIso8601String(),
          'is_deleted': row['is_deleted'] ?? 0,
        });
      } catch (e) {
        // 忽略迁移失败的记录
      }
    }
  }

  // 创建数据库表
  Future<void> _createDB(Database db, int version) async {
    const idType = 'INTEGER PRIMARY KEY AUTOINCREMENT';
    const textType = 'TEXT NOT NULL';
    const integerType = 'INTEGER NOT NULL';
    const booleanType = 'INTEGER NOT NULL';

    // 影视表
    await db.execute('''
      CREATE TABLE movies (
        id TEXT PRIMARY KEY,
        title TEXT NOT NULL,
        poster_path TEXT,
        release_date TEXT,
        directors TEXT,
        writers TEXT,
        actors TEXT,
        genres TEXT,
        alternate_titles TEXT,
        summary TEXT,
        rating REAL,
        status TEXT NOT NULL,
        watch_date TEXT,
        created_at TEXT NOT NULL,
        updated_at TEXT NOT NULL,
        is_deleted INTEGER DEFAULT 0
      )
    ''');

    // 书籍表
    await db.execute('''
      CREATE TABLE books (
        id TEXT PRIMARY KEY,
        title TEXT NOT NULL,
        cover_path TEXT,
        authors TEXT,
        alternate_titles TEXT,
        publisher TEXT,
        genres TEXT,
        summary TEXT,
        rating REAL,
        status TEXT NOT NULL,
        isbn TEXT,
        publish_date TEXT,
        created_at TEXT NOT NULL,
        updated_at TEXT NOT NULL,
        is_deleted INTEGER DEFAULT 0
      )
    ''');

    // 笔记表
    await db.execute('''
      CREATE TABLE notes (
        id TEXT PRIMARY KEY,
        title TEXT DEFAULT '',
        content TEXT NOT NULL,
        content_type TEXT DEFAULT 'markdown',
        tags TEXT,
        images TEXT,
        created_at TEXT NOT NULL,
        updated_at TEXT NOT NULL,
        is_deleted INTEGER DEFAULT 0
      )
    ''');
    
    // 影评表
    await db.execute('''
      CREATE TABLE movie_reviews (
        id TEXT PRIMARY KEY,
        movie_id TEXT NOT NULL,
        content TEXT NOT NULL,
        reviewer TEXT,
        source TEXT,
        review_type INTEGER DEFAULT 1,
        is_deleted INTEGER DEFAULT 0,
        created_at TEXT NOT NULL,
        updated_at TEXT NOT NULL,
        FOREIGN KEY (movie_id) REFERENCES movies (id)
      )
    ''');
    
    // 影视海报墙表
    await db.execute('''
      CREATE TABLE movie_posters (
        id TEXT PRIMARY KEY,
        movie_id TEXT NOT NULL,
        poster_path TEXT NOT NULL,
        is_deleted INTEGER DEFAULT 0,
        created_at TEXT NOT NULL,
        FOREIGN KEY (movie_id) REFERENCES movies (id)
      )
    ''');

    // 书评表
    await db.execute('''
      CREATE TABLE book_reviews (
        id TEXT PRIMARY KEY,
        book_id TEXT NOT NULL,
        content TEXT NOT NULL,
        reviewer TEXT,
        source TEXT,
        review_type INTEGER DEFAULT 1,
        is_deleted INTEGER DEFAULT 0,
        created_at TEXT NOT NULL,
        updated_at TEXT NOT NULL,
        FOREIGN KEY (book_id) REFERENCES books (id)
      )
    ''');

    // 书籍摘抄表
    await db.execute('''
      CREATE TABLE book_excerpts (
        id TEXT PRIMARY KEY,
        book_id TEXT NOT NULL,
        chapter TEXT,
        content TEXT NOT NULL,
        comment TEXT,
        is_deleted INTEGER DEFAULT 0,
        created_at TEXT NOT NULL,
        updated_at TEXT NOT NULL,
        FOREIGN KEY (book_id) REFERENCES books (id)
      )
    ''');

    // 标签表
    await db.execute('''
      CREATE TABLE IF NOT EXISTS tags (
        id TEXT PRIMARY KEY,
        name TEXT NOT NULL,
        type TEXT NOT NULL,
        created_at TEXT NOT NULL,
        UNIQUE(name, type)
      )
    ''');
  }

  // 关闭数据库
  Future close() async {
    if (_database != null) {
      await _database!.close();
      _database = null;
    }
  }

  // 重新打开（关闭后重新初始化）
  Future reopen() async {
    await close();
    await database;
  }
}
