import 'package:flutter_riverpod/flutter_riverpod.dart';

import 'package:im_app/app/di/network_provider.dart';
import 'package:im_app/app/di/db_provider.dart';
import 'package:im_app/data/repositories/auth_repository_impl.dart';
import 'package:im_app/domain/repositories/auth_repository.dart';
import 'package:im_app/features/login/usecases/login_usecase.dart';

/// ## DI 装配：Auth Feature 层
///
/// di/ 目录只放**需要手动装配的 Provider**（构造注入、回调组合等）。
/// ViewModel Provider 由 `@riverpod` 注解自动生成，不在此文件中。
///
/// Auth 模块的 DI 链路：Repository → UseCase（按需）。
/// app/di/ 只提供 SDK 基础设施（apiConfig / networkSdkApi / socketManager / storageApi），
/// 业务模块的 Provider 内聚在 features/{模块}/di/ 下。
///
/// ```
/// LoginViewModel                           ← @riverpod 自动生成
///   → ref.read(loginUseCaseProvider)       ← di/ 手动装配
///     → ref.read(authRepositoryProvider)   ← di/ 手动装配
///     → ref.read(socketManagerProvider)    ← app/di/ 手动装配
///     → ref.read(apiConfigProvider)        ← app/di/ 手动装配
///       → ref.read(networkSdkApiProvider)  ← app/di/ 手动装配
///     → ref.read(storageSdkProvider)       ← app/di/ 手动装配
/// ```

// ── Repository ────────────────────────────────────────────────────────────────

/// 认证 Repository Provider
///
/// 注入 domain 接口类型 [AuthRepository]，
/// ViewModel 通过此 Provider 获取依赖，不感知具体实现。
///
/// [onTokenUpdate] 是复合回调：
///   1. 写入 ApiConfig 内存 → 后续请求自动携带 token
///   2. TODO: 持久化到安全存储（crypto_sdk）→ App 重启后恢复
/// 两个 SDK 互不依赖，由 App 层在此组合。
final authRepositoryProvider = Provider<AuthRepository>((ref) {
  final apiConfig = ref.read(apiConfigProvider);
  // TODO: final secureStorage = ref.read(secureStorageProvider);

  return AuthRepositoryImpl(
    client: ref.read(networkSdkApiProvider), // 注入 Facade 接口
    onTokenUpdate: (token) {
      apiConfig.updateToken(token); // 内存（network_sdk）
      // TODO: secureStorage.saveToken(token); // 持久化（crypto_sdk）
    },
  );
});

// ── UseCase ───────────────────────────────────────────────────────────────────

/// 登录用例 Provider
///
/// 多步编排：格式校验 → 调接口 → 写 Token → 连接 WebSocket → 打开数据库
final loginUseCaseProvider = Provider<LoginUseCase>((ref) {
  return LoginUseCase(
    authRepository: ref.read(authRepositoryProvider),
    socketManager: ref.read(socketManagerProvider),
    apiConfig: ref.read(apiConfigProvider),
    storageApi: ref.read(storageSdkProvider),
  );
});
