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

/// 聊天分类仓储实现
///
/// ## 职责
/// - 所有 DB 操作通过 [StorageSdkApi]，不直接接触 AppDatabase
/// - DriftChatCategory ↔ Domain ChatCategory 映射
/// - 所有公开接口只接受 Domain 实体，Companion 转换完全内聚在此类
///
/// ## 数据流
/// ```
/// 网络：ChatCategory.fromJson(json) → insertOrReplaceChatCategory(chatCategory) → StorageSdkApi → DB
/// 监听：StorageSdkApi.watchAll → DriftChatCategory → _toEntity() → UI
/// ```
class ChatCategoryRepositoryImpl implements ChatCategoryRepository {
  final StorageSdkApi _storage;

  ChatCategoryRepositoryImpl(this._storage);

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

  ChatCategory _toEntity(DriftChatCategory row) => ChatCategory(
    id: row.id,
    name: row.name,
    includedChatIds: row.includedChatIds,
    excludedChatIds: row.excludedChatIds,
    seq: row.seq,
    isHide: row.isHide,
    createdAt: row.createdAt,
    updatedAt: row.updatedAt,
    deletedAt: row.deletedAt,
  );

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

  ChatCategoriesCompanion _toCompanion(ChatCategory chatCategory) =>
      ChatCategoriesCompanion(
        id: Value(chatCategory.id),
        name: Value(chatCategory.name),
        includedChatIds: Value(chatCategory.includedChatIds),
        excludedChatIds: Value(chatCategory.excludedChatIds),
        seq: Value(chatCategory.seq),
        isHide: Value(chatCategory.isHide),
        createdAt: Value(chatCategory.createdAt),
        updatedAt: Value(chatCategory.updatedAt),
        deletedAt: Value(chatCategory.deletedAt),
      );

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

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

  @override
  Stream<ChatCategory?> watchChatCategory(int id) {
    return _storage
        .watchFirst<DriftChatCategory, $ChatCategoriesTable>(
          (t) => t.id.equals(id),
        )
        .map((row) => row != null ? _toEntity(row) : null);
  }

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

  @override
  Future<List<ChatCategory>> getChatCategories() async {
    final rows = await _storage.selectAll<DriftChatCategory>();
    return rows.map(_toEntity).toList();
  }

  @override
  Future<ChatCategory?> getChatCategory(int id) async {
    final row = await _storage
        .selectFirst<DriftChatCategory, $ChatCategoriesTable>(
          (t) => t.id.equals(id),
        );
    return row != null ? _toEntity(row) : null;
  }

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

  @override
  Future<void> insertOrReplaceChatCategory(ChatCategory chatCategory) async {
    await _storage.insertOrReplace<DriftChatCategory>(
      _toCompanion(chatCategory),
    );
  }

  @override
  Future<void> insertOrReplaceChatCategories(
    List<ChatCategory> chatCategories,
  ) async {
    await _storage.batchInsertOrReplace<DriftChatCategory>(
      chatCategories.map(_toCompanion).toList(),
    );
  }

  @override
  Future<void> updateChatCategory(ChatCategory chatCategory) async {
    await _storage.updateWhere<DriftChatCategory, $ChatCategoriesTable>(
      _toCompanion(chatCategory),
      (t) => t.id.equals(chatCategory.id),
    );
  }

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

  @override
  Future<void> deleteChatCategory(int id) async {
    await _storage.deleteWhere<DriftChatCategory, $ChatCategoriesTable>(
      (t) => t.id.equals(id),
    );
  }

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