import 'dart:convert';

import 'package:flutter/services.dart';
import 'package:im_app/app/di/user_provider.dart';
import 'package:im_app/data/remote/login_request.dart';
import 'package:networks_sdk/networks_sdk.dart';
import 'package:im_app/app/di/db_provider.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:storage_sdk/storage_sdk.dart';

import '../../../app/di/app_providers.dart';
import '../di/auth_providers.dart';
import 'login_state.dart';

part 'login_view_model.g.dart';

/// 登录 ViewModel（@riverpod 自动生成 `loginViewModelProvider`）
///
/// `@riverpod` 注解 → build_runner 自动生成 `login_view_model.g.dart`，
/// 其中包含 `loginViewModelProvider`。View 层直接使用：
///
/// ```dart
/// // View 层读取状态
/// final state = ref.watch(loginViewModelProvider);
///
/// // View 层调用方法
/// ref.read(loginViewModelProvider.notifier).login(email, password);
/// ```
///
/// ## 手动 vs 自动 Provider 对比
///
/// ```
/// loginViewModelProvider                    ← @riverpod 自动生成（本文件）
///   → ref.read(loginUseCaseProvider)       ← di/ 手动装配
///     → ref.read(authRepositoryProvider)   ← di/ 手动装配
///       → ref.read(apiClientProvider)      ← app/di/ 手动装配
/// ```
///
/// ## 数据流位置
///
/// ```
/// View: ref.read(loginViewModelProvider.notifier).login(email, password)
///   → ★ LoginViewModel.login() ★                  ← 你在这里
///     → LoginUseCase.execute()                     ← 格式校验 + 调 Repository
///       → AuthRepository.login()
///         → _client.executeRequest(LoginRequest)
///       ← LoginData → User
///     ← User
///   → state = state.copyWith(user: user)           ← 更新状态
/// View: ref.watch → 自动 rebuild                    ← UI 刷新
/// ```
@riverpod
class LoginViewModel extends _$LoginViewModel {
  @override
  LoginState build() => const LoginState();

  /// Demo 登录（跳过 API，直接设置登录状态）
  ///
  /// 仅用于演示路由守卫行为，正式 UI 就绪后删除此方法，改用 [login]。
  /// 正式 [login] 成功后同样需要调用 [AuthNotifier.login] 更新守卫状态。
  Future<void> demoLogin() async {
    final storageApi = ref.read(storageSdkProvider);
    final storageLifeCycle = storageApi as StorageSdkLifecycle;
    final repositoryProvider = ref.read(userRepositoryProvider);
    final provider = ref.read(authNotifierProvider);

    // Read mock response from assets
    final String raw = await rootBundle.loadString('assets/loginData.json');
    final Map<String, dynamic> json = jsonDecode(raw);

    // Parse → Domain User directly
    final loginResponse = LoginResponse.fromJson(json);
    final user = loginResponse.data.toEntity();

    // Open database for the user
    await storageLifeCycle.openDatabase(user.uid);

    // Save user to DB via repository
    await repositoryProvider.saveUser(user);

    // Trigger auth state
    provider.login();
  }

  /// 执行登录
  ///
  /// 1. 设置 loading 状态（UI 显示加载指示器、禁用按钮）
  /// 2. 调 UseCase（格式校验 → 登录 → 返回 User）
  /// 3. 成功：写入 user；失败：写入 error
  Future<void> login(String email, String password) async {
    state = state.copyWith(isLoading: true, error: null);

    try {
      final user = await ref
          .read(loginUseCaseProvider)
          .execute(email: email, password: password);

      state = state.copyWith(user: user, isLoading: false);
    } on FormatException catch (e) {
      // 格式校验失败（UseCase 层抛出）
      state = state.copyWith(error: e.message, isLoading: false);
    } on ApiError catch (e) {
      // 网络 / 服务端错误（Repository → SDK 透传）
      state = state.copyWith(error: e.displayMessage, isLoading: false);
    } catch (e) {
      // 兜底：防止未预期的异常导致 isLoading 死锁
      state = state.copyWith(error: e.toString(), isLoading: false);
    }
  }
}
