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

/// 收藏详情仓储实现
///
/// ## 注意
/// - id 为 autoIncrement — insert 时不传 id，由 DB 自动生成
/// - insertOrReplace 时若 id 为 null 则作为新增处理
class FavoriteDetailRepositoryImpl implements FavoriteDetailRepository {
  final StorageSdkApi _storage;

  FavoriteDetailRepositoryImpl(this._storage);

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

  FavoriteDetail _toEntity(DriftFavoriteDetail row) => FavoriteDetail(
    id: row.id,
    relatedId: row.relatedId,
    content: row.content,
    typ: row.typ,
    messageId: row.messageId,
    sendId: row.sendId,
    chatId: row.chatId,
    sendTime: row.sendTime,
  );

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

  FavoriteDetailsCompanion _toCompanion(FavoriteDetail detail) =>
      FavoriteDetailsCompanion(
        // id is autoIncrement — omit if null so DB generates it
        id: detail.id != null ? Value(detail.id!) : const Value.absent(),
        relatedId: Value(detail.relatedId),
        content: Value(detail.content),
        typ: Value(detail.typ),
        messageId: Value(detail.messageId),
        sendId: Value(detail.sendId),
        chatId: Value(detail.chatId),
        sendTime: Value(detail.sendTime),
      );

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

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

  @override
  Stream<List<FavoriteDetail>> watchByRelatedId(String relatedId) {
    return _storage
        .watchWhere<DriftFavoriteDetail, $FavoriteDetailsTable>(
          (t) => t.relatedId.equals(relatedId),
        )
        .map((rows) => rows.map(_toEntity).toList());
  }

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

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

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

  @override
  Future<List<FavoriteDetail>> getByRelatedId(String relatedId) async {
    final rows = await _storage
        .selectWhere<DriftFavoriteDetail, $FavoriteDetailsTable>(
          (t) => t.relatedId.equals(relatedId),
        );
    return rows.map(_toEntity).toList();
  }

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

  @override
  Future<void> insert(FavoriteDetail favoriteDetail) async {
    await _storage.insert<DriftFavoriteDetail>(_toCompanion(favoriteDetail));
  }

  @override
  Future<void> insertAll(List<FavoriteDetail> favoriteDetails) async {
    for (final detail in favoriteDetails) {
      await _storage.insert<DriftFavoriteDetail>(_toCompanion(detail));
    }
  }

  @override
  Future<void> insertOrReplace(FavoriteDetail favoriteDetail) async {
    await _storage.insertOrReplace<DriftFavoriteDetail>(
      _toCompanion(favoriteDetail),
    );
  }

  @override
  Future<void> update(FavoriteDetail favoriteDetail) async {
    if (favoriteDetail.id == null) return;
    await _storage.updateWhere<DriftFavoriteDetail, $FavoriteDetailsTable>(
      _toCompanion(favoriteDetail),
      (t) => t.id.equals(favoriteDetail.id!),
    );
  }

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

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

  @override
  Future<void> deleteByRelatedId(String relatedId) async {
    await _storage.deleteWhere<DriftFavoriteDetail, $FavoriteDetailsTable>(
      (t) => t.relatedId.equals(relatedId),
    );
  }

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