import 'package:drift/drift.dart';

import '../../domain/repositories/database_repository.dart';
import '../local/datasources/database_datasource.dart';

/// [DatabaseRepository] 的 Drift 实现。
///
/// 通过 [DatabaseDataSource.current] 获取当前数据库实例。
/// 数据库未打开（null）时所有方法静默返回，不抛异常。
class DatabaseRepositoryImpl implements DatabaseRepository {
  final DatabaseDataSource _dataSource;

  DatabaseRepositoryImpl(this._dataSource);

  GeneratedDatabase? get _db => _dataSource.current;

  // ── 插入 ─────────────────────────────────────────────────────────────────

  @override
  Future<void> insertOrReplace<T extends Table, D>(
    TableInfo<T, D> table,
    Insertable<D> companion,
  ) async {
    final db = _db;
    if (db == null) return;
    await db.into(table).insert(companion, mode: InsertMode.insertOrReplace);
  }

  @override
  Future<void> insert<T extends Table, D>(
    TableInfo<T, D> table,
    Insertable<D> companion,
  ) async {
    final db = _db;
    if (db == null) return;
    await db.into(table).insert(companion, mode: InsertMode.insertOrIgnore);
  }

  @override
  Future<void> batchInsertOrReplace<T extends Table, D>(
    TableInfo<T, D> table,
    List<Insertable<D>> companions,
  ) async {
    final db = _db;
    if (db == null) return;
    await db.batch(
      (batch) =>
          batch.insertAll(table, companions, mode: InsertMode.insertOrReplace),
    );
  }

  @override
  Future<void> insertOnConflictUpdate<T extends Table, D>(
    TableInfo<T, D> table,
    Insertable<D> companion,
  ) async {
    final db = _db;
    if (db == null) return;
    await db.into(table).insertOnConflictUpdate(companion);
  }

  @override
  Future<void> batchInsertOnConflictUpdate<T extends Table, D>(
    TableInfo<T, D> table,
    List<Insertable<D>> companions,
  ) async {
    final db = _db;
    if (db == null) return;
    await db.transaction(() async {
      for (final companion in companions) {
        await db.into(table).insertOnConflictUpdate(companion);
      }
    });
  }

  // ── 更新 ─────────────────────────────────────────────────────────────────

  @override
  Future<void> updateWhere<T extends Table, D>(
    TableInfo<T, D> table,
    Insertable<D> companion,
    Expression<bool> Function(T) filter,
  ) async {
    final db = _db;
    if (db == null) return;
    await (db.update(table)..where(filter)).write(companion);
  }

  // ── 删除 ─────────────────────────────────────────────────────────────────

  @override
  Future<void> deleteWhere<T extends Table, D>(
    TableInfo<T, D> table,
    Expression<bool> Function(T) filter,
  ) async {
    final db = _db;
    if (db == null) return;
    await (db.delete(table)..where(filter)).go();
  }

  @override
  Future<void> deleteAll<T extends Table, D>(TableInfo<T, D> table) async {
    final db = _db;
    if (db == null) return;
    await db.delete(table).go();
  }

  // ── 查询 ─────────────────────────────────────────────────────────────────

  @override
  Future<List<D>> selectAll<T extends Table, D>(TableInfo<T, D> table) async {
    final db = _db;
    if (db == null) return [];
    return db.select(table).get();
  }

  @override
  Future<List<D>> selectWhere<T extends Table, D>(
    TableInfo<T, D> table,
    Expression<bool> Function(T) filter,
  ) async {
    final db = _db;
    if (db == null) return [];
    return (db.select(table)..where(filter)).get();
  }

  @override
  Future<D?> selectFirst<T extends Table, D>(
    TableInfo<T, D> table,
    Expression<bool> Function(T) filter,
  ) async {
    final db = _db;
    if (db == null) return null;
    return (db.select(table)
          ..where(filter)
          ..limit(1))
        .getSingleOrNull();
  }

  // ── 监听 ─────────────────────────────────────────────────────────────────

  @override
  Stream<List<D>> watchAll<T extends Table, D>(TableInfo<T, D> table) {
    final db = _db;
    if (db == null) return const Stream.empty();
    return db.select(table).watch();
  }

  @override
  Stream<List<D>> watchWhere<T extends Table, D>(
    TableInfo<T, D> table,
    Expression<bool> Function(T) filter,
  ) {
    final db = _db;
    if (db == null) return const Stream.empty();
    return (db.select(table)..where(filter)).watch();
  }

  @override
  Stream<D?> watchFirst<T extends Table, D>(
    TableInfo<T, D> table,
    Expression<bool> Function(T) filter,
  ) {
    final db = _db;
    if (db == null) return const Stream.empty();
    return (db.select(table)
          ..where(filter)
          ..limit(1))
        .watchSingleOrNull();
  }

  // ── 原始 SQL ─────────────────────────────────────────────────────────────

  @override
  Future<List<QueryRow>> rawQuery(
    String sql, [
    List<Object?> args = const [],
  ]) async {
    final db = _db;
    if (db == null) return [];
    return db
        .customSelect(sql, variables: args.map((e) => Variable(e)).toList())
        .get();
  }

  @override
  Future<void> rawExecute(String sql, [List<Object?> args = const []]) async {
    final db = _db;
    if (db == null) return;
    await db.customStatement(sql, args);
  }

  // ── 统计 ─────────────────────────────────────────────────────────────────

  @override
  Future<int> count<T extends Table, D>(
    TableInfo<T, D> table, {
    Expression<bool> Function(T)? filter,
  }) async {
    final db = _db;
    if (db == null) return 0;
    final countExpr = table.$columns.first.count();
    final query = db.selectOnly(table)..addColumns([countExpr]);
    if (filter != null) query.where(filter(table.asDslTable));
    final row = await query.getSingle();
    return row.read(countExpr) ?? 0;
  }
}
