import 'package:im_app/domain/entities/user.dart';

/// 用户仓储接口
///
/// ## 职责
/// - StorageSdkApi ↔ Domain User 映射
/// - CRUD 操作（通过 StorageSdkApi，不直接接触 DB）
/// - 实时监听（单个 / 多个 / 全部）
/// - 所有公开接口只接受 Domain 实体，Companion 转换完全内聚在 Impl
///
/// ## 数据流
/// ```
/// 写入：Domain User → _toCompanion() → StorageSdkApi → DB
/// 读取：DB row (DriftUser) → _toEntity() → Domain User
/// 监听：DB 变化 → stream → Domain User → UI
/// ```
abstract interface class UserRepository {
  // ── 监听 ─────────────────────────────────────────────────────────────────

  /// 监听单个用户，DB 变化自动反映
  Stream<User?> watchUser(int uid);

  /// 监听指定 uid 列表，任一变化自动反映
  Stream<List<User>> watchUsers(List<int> uids);

  /// 监听所有用户，任一变化自动反映
  Stream<List<User>> watchAllUsers();

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

  /// 从 DB 读取单个用户，不存在返回 null
  Future<User?> getUser(int uid);

  /// 从 DB 读取所有用户
  Future<List<User>> getAllUsers();

  /// 分页读取用户
  ///
  /// [offset] 起始偏移量
  /// [limit] 每页数量
  ///
  /// 示例：
  /// ```dart
  /// // 第一页
  /// final page1 = await repo.getUsers(offset: 0, limit: 50);
  /// // 第二页
  /// final page2 = await repo.getUsers(offset: 50, limit: 50);
  /// ```
  Future<List<User>> getUsers({required int offset, required int limit});

  /// 统计 DB 中用户总数
  Future<int> countUsers();

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

  /// 插入或替换单个用户
  Future<void> insertOrReplaceUser(User user);

  /// 批量插入或替换用户
  Future<void> insertOrReplaceUsers(List<User> users);

  /// 更新单个用户所有字段，按 uid 匹配
  ///
  /// 示例：
  /// ```dart
  /// await repo.updateUser(user.copyWith(nickname: 'New Name'));
  /// ```
  Future<void> updateUser(User user);

  /// 批量更新用户，每条按 uid 匹配更新所有字段
  ///
  /// 示例：
  /// ```dart
  /// final updated = users.map((u) => u.copyWith(nickname: 'new')).toList();
  /// await repo.updateUsersBatch(updated);
  /// ```
  Future<void> updateUsersBatch(List<User> users);

  /// 单条 upsert
  Future<void> upsertUser(User user);

  /// 批量 upsert，走单次事务，优于循环调用 [upsertUser]
  Future<void> upsertUsers(List<User> users);

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

  /// 删除指定用户
  Future<void> deleteUser(int uid);
}
