import 'package:drift/drift.dart';
import 'package:im_app/domain/entities/mini_app.dart';
import 'package:im_app/domain/repositories/mini_app_repository.dart';
import 'package:storage_sdk/storage_sdk.dart';

/// 小程序仓储基类
///
/// discover / explore / favorite / recent 四张表共用同一套映射逻辑。
/// 子类只需提供泛型类型参数 + 实现 [toCompanion]。
abstract class BaseMiniAppRepositoryImpl<D, T extends Table>
    implements MiniAppRepository {
  final StorageSdkApi _storage;

  BaseMiniAppRepositoryImpl(this._storage);

  // ── DB row → Domain ──────────────────────────────────────────────────────

  MiniApp _toEntity(dynamic row) => MiniApp(
    id: row.id as String,
    name: row.name as String?,
    openuid: row.openuid as String?,
    devId: row.devId as String?,
    icon: row.icon as String?,
    iconGaussian: row.iconGaussian as String?,
    downloadUrl: row.downloadUrl as String?,
    description: row.description as String?,
    version: row.version as int?,
    typ: row.typ as int?,
    flag: row.flag as int?,
    reviewStatus: row.reviewStatus as int?,
    favoriteAt: row.favoriteAt as int?,
    isActive: row.isActive as int?,
    createdAt: row.createdAt as int?,
    updatedAt: row.updatedAt as int?,
    deletedAt: row.deletedAt as int?,
    score: row.score as double?,
    channels: row.channels as String?,
    devName: row.devName as String?,
    pictureGaussian: row.pictureGaussian as String?,
    picture: row.picture as String?,
    commentNum: row.commentNum as int?,
    lastLoginAt: row.lastLoginAt as String?,
    screen: row.screen as String?,
  );

  /// 子类提供对应表的 Companion
  Insertable<D> toCompanion(MiniApp miniApp);

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

  @override
  Stream<List<MiniApp>> watchAll() {
    return _storage.watchAll<D>().map((rows) => rows.map(_toEntity).toList());
  }

  @override
  Stream<MiniApp?> watch(String id) {
    return _storage
        .watchFirst<D, T>((t) => (t as dynamic).id.equals(id))
        .map((row) => row != null ? _toEntity(row) : null);
  }

  // ── 读取 ─────────────────────────────────────────────────────────────────

  @override
  Future<List<MiniApp>> getAll() async {
    final rows = await _storage.selectAll<D>();
    return rows.map(_toEntity).toList();
  }

  @override
  Future<MiniApp?> get(String id) async {
    final row = await _storage.selectFirst<D, T>(
      (t) => (t as dynamic).id.equals(id),
    );
    return row != null ? _toEntity(row) : null;
  }

  @override
  Future<bool> isExist(String id) async {
    final row = await _storage.selectFirst<D, T>(
      (t) => (t as dynamic).id.equals(id),
    );
    return row != null;
  }

  // ── 写入 ─────────────────────────────────────────────────────────────────

  @override
  Future<void> insertOrReplace(MiniApp miniApp) async {
    await _storage.insertOrReplace<D>(toCompanion(miniApp));
  }

  @override
  Future<void> insertOrReplaceAll(List<MiniApp> miniApps) async {
    await _storage.batchInsertOrReplace<D>(miniApps.map(toCompanion).toList());
  }

  @override
  Future<void> update(MiniApp miniApp) async {
    await _storage.updateWhere<D, T>(
      toCompanion(miniApp),
      (t) => (t as dynamic).id.equals(miniApp.id),
    );
  }

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

  @override
  Future<void> delete(String id) async {
    await _storage.deleteWhere<D, T>((t) => (t as dynamic).id.equals(id));
  }

  @override
  Future<void> clear() async {
    await _storage.deleteAll<D>();
  }
}
