import 'package:drift/drift.dart';

import '../facade/storage_sdk_api.dart';
import 'storage_sdk_core.dart';

/// [StorageSdkApi] 的实现，委托给 [StorageSdkCore]。
class StorageSdkApiImpl implements StorageSdkApi, StorageSdkLifecycle {
  final StorageSdkCore _core;
  final Map<Type, TableInfo> Function(GeneratedDatabase) _tableRegistry;

  StorageSdkApiImpl({
    required StorageSdkCore core,
    required Map<Type, TableInfo> Function(GeneratedDatabase) tableRegistry,
  }) : _core = core,
       _tableRegistry = tableRegistry;

  // ── 表查找 ───────────────────────────────────────────────────────────────

  /// 根据泛型数据类型从注册表中查找对应的 [TableInfo]。
  TableInfo<T, D> _tableFor<T extends Table, D>() {
    final db = _core.dataSource.current;
    if (db == null) throw StateError('数据库未开启，请先调用 openDatabase()');
    final table = _tableRegistry(db)[D];
    if (table == null) throw StateError('未注册类型 $D 对应的表，请检查 tableRegistry');
    return table as TableInfo<T, D>;
  }

  /// 获取当前已开启的数据库实例，未开启则抛出 [StateError]。
  GeneratedDatabase get _db {
    final db = _core.dataSource.current;
    if (db == null) throw StateError('数据库未开启，请先调用 openDatabase()');
    return db;
  }

  // ── 生命周期 ─────────────────────────────────────────────────────────────

  @override
  Future<void> openDatabase(int uid) => _core.dataSource.openDatabase(uid);

  @override
  Future<void> closeDatabase() => _core.dataSource.closeDatabase();

  @override
  bool get isDatabaseOpen => _core.dataSource.current != null;

  // ── 事务 ─────────────────────────────────────────────────────────────────

  /// 在单个事务内执行 [action]。
  ///
  /// - 成功则自动 COMMIT
  /// - 抛出异常则自动 ROLLBACK，异常会继续向上传递
  @override
  Future<T> transaction<T>(Future<T> Function() action) =>
      _db.transaction(action);

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

  @override
  Future<void> insertOrReplace<D>(Insertable<D> companion) =>
      _core.repo.insertOrReplace(_tableFor<Table, D>(), companion);

  @override
  Future<void> insert<D>(Insertable<D> companion) =>
      _core.repo.insert(_tableFor<Table, D>(), companion);

  @override
  Future<void> batchInsertOrReplace<D>(List<Insertable<D>> companions) =>
      _core.repo.batchInsertOrReplace(_tableFor<Table, D>(), companions);

  @override
  Future<void> insertOnConflictUpdate<D>(Insertable<D> companion) =>
      _core.repo.insertOnConflictUpdate(_tableFor<Table, D>(), companion);

  @override
  Future<void> batchInsertOnConflictUpdate<D>(List<Insertable<D>> companions) =>
      _core.repo.batchInsertOnConflictUpdate(_tableFor<Table, D>(), companions);

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

  @override
  Future<void> updateWhere<D, T extends Table>(
    Insertable<D> companion,
    Expression<bool> Function(T) filter,
  ) => _core.repo.updateWhere(_tableFor<T, D>(), companion, filter);

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

  @override
  Future<void> deleteWhere<D, T extends Table>(
    Expression<bool> Function(T) filter,
  ) => _core.repo.deleteWhere(_tableFor<T, D>(), filter);

  @override
  Future<void> deleteAll<D>() => _core.repo.deleteAll(_tableFor<Table, D>());

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

  @override
  Future<List<D>> selectAll<D>() => _core.repo.selectAll(_tableFor<Table, D>());

  @override
  Future<List<D>> selectWhere<D, T extends Table>(
    Expression<bool> Function(T) filter,
  ) => _core.repo.selectWhere(_tableFor<T, D>(), filter);

  @override
  Future<D?> selectFirst<D, T extends Table>(
    Expression<bool> Function(T) filter,
  ) => _core.repo.selectFirst(_tableFor<T, D>(), filter);

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

  @override
  Stream<List<D>> watchAll<D>() => _core.repo.watchAll(_tableFor<Table, D>());

  @override
  Stream<List<D>> watchWhere<D, T extends Table>(
    Expression<bool> Function(T) filter,
  ) => _core.repo.watchWhere(_tableFor<T, D>(), filter);

  @override
  Stream<D?> watchFirst<D, T extends Table>(
    Expression<bool> Function(T) filter,
  ) => _core.repo.watchFirst(_tableFor<T, D>(), filter);

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

  @override
  Future<List<QueryRow>> rawQuery(
    String sql, [
    List<Object?> args = const [],
  ]) => _core.repo.rawQuery(sql, args);

  @override
  Future<void> rawExecute(String sql, [List<Object?> args = const []]) =>
      _core.repo.rawExecute(sql, args);

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

  @override
  Future<int> count<D, T extends Table>({
    Expression<bool> Function(T)? filter,
  }) => _core.repo.count(_tableFor<T, D>(), filter: filter);
}
