import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/pending_friend_request_history.dart';
import 'package:im_app/domain/repositories/pending_friend_request_history_repository.dart';
import 'package:storage_sdk/storage_sdk.dart';

class PendingFriendRequestHistoryRepositoryImpl
    implements PendingFriendRequestHistoryRepository {
  final StorageSdkApi _storage;

  PendingFriendRequestHistoryRepositoryImpl(this._storage);

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

  PendingFriendRequestHistory _toEntity(DriftPendingFriendRequestHistory row) =>
      PendingFriendRequestHistory(
        id: row.id,
        uid: row.uid,
        requestTime: row.requestTime,
        remarks: row.remarks,
        source: row.source,
        rs: row.rs,
      );

  // ── Domain → DB companion (internal only) ────────────────────────────────

  PendingFriendRequestHistoriesCompanion _toCompanion(
    PendingFriendRequestHistory history,
  ) => PendingFriendRequestHistoriesCompanion(
    id: Value(history.id),
    uid: Value(history.uid),
    requestTime: Value(history.requestTime),
    remarks: Value(history.remarks),
    source: Value(history.source),
    rs: Value(history.rs),
  );

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

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

  @override
  Stream<PendingFriendRequestHistory?> watchById(int id) {
    return _storage
        .watchFirst<
          DriftPendingFriendRequestHistory,
          $PendingFriendRequestHistoriesTable
        >((t) => t.id.equals(id))
        .map((row) => row != null ? _toEntity(row) : null);
  }

  @override
  Stream<List<PendingFriendRequestHistory>> watchByUid(int uid) {
    return _storage
        .watchWhere<
          DriftPendingFriendRequestHistory,
          $PendingFriendRequestHistoriesTable
        >((t) => t.uid.equals(uid))
        .map((rows) => rows.map(_toEntity).toList());
  }

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

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

  @override
  Future<PendingFriendRequestHistory?> getById(int id) async {
    final row = await _storage
        .selectFirst<
          DriftPendingFriendRequestHistory,
          $PendingFriendRequestHistoriesTable
        >((t) => t.id.equals(id));
    return row != null ? _toEntity(row) : null;
  }

  @override
  Future<List<PendingFriendRequestHistory>> getByUid(int uid) async {
    final rows = await _storage
        .selectWhere<
          DriftPendingFriendRequestHistory,
          $PendingFriendRequestHistoriesTable
        >((t) => t.uid.equals(uid));
    return rows.map(_toEntity).toList();
  }

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

  @override
  Future<void> insertOrReplace(PendingFriendRequestHistory history) async {
    await _storage.insertOrReplace<DriftPendingFriendRequestHistory>(
      _toCompanion(history),
    );
  }

  @override
  Future<void> insertOrReplaceAll(
    List<PendingFriendRequestHistory> histories,
  ) async {
    await _storage.batchInsertOrReplace<DriftPendingFriendRequestHistory>(
      histories.map(_toCompanion).toList(),
    );
  }

  @override
  Future<void> update(PendingFriendRequestHistory history) async {
    await _storage.updateWhere<
      DriftPendingFriendRequestHistory,
      $PendingFriendRequestHistoriesTable
    >(_toCompanion(history), (t) => t.id.equals(history.id));
  }

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

  @override
  Future<void> delete(int id) async {
    await _storage.deleteWhere<
      DriftPendingFriendRequestHistory,
      $PendingFriendRequestHistoriesTable
    >((t) => t.id.equals(id));
  }

  @override
  Future<void> deleteByUid(int uid) async {
    await _storage.deleteWhere<
      DriftPendingFriendRequestHistory,
      $PendingFriendRequestHistoriesTable
    >((t) => t.uid.equals(uid));
  }

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