import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:networks_sdk/networks_sdk.dart';

/// ViewModel 请求守卫 mixin
///
/// 统一拦截 API 调用的 [ApiError]，无需在每个 ViewModel 方法内写 try-catch。
/// [ApiError.displayMessage] 自动映射为可读文案，直接写入 state。
///
/// ## 使用
///
/// ```dart
/// @riverpod
/// class LoginViewModel extends _$LoginViewModel with RequestGuard<LoginState> {
///
///   Future<void> sendOtp(String phone) async {
///     state = state.copyWith(isLoading: true, error: null);
///
///     final ok = await guard(
///       () => ref.read(loginUseCaseProvider).sendOtp(phone),
///       onError: (msg) => state = state.copyWith(isLoading: false, error: msg),
///     );
///
///     if (ok != null) {
///       state = state.copyWith(isLoading: false, step: LoginStep.otpSent);
///     }
///   }
/// }
/// ```
///
/// ## 机制
///
/// ```
/// guard()
///   └─ try: call() → 成功，返回 T
///   └─ on ApiError: onError(e.displayMessage) → 返回 null
///
/// ViewModel: ok != null → 成功路径
///            ok == null → 已由 onError 更新 state.error，无需额外处理
/// ```
mixin RequestGuard<S> on Notifier<S> {
  /// 执行 [call]，捕获 [ApiError] 后调用 [onError] 写入错误文案，返回 null。
  /// 成功时返回原始结果，ViewModel 用返回值是否为 null 判断走哪条路径。
  Future<T?> guard<T>(
    Future<T> Function() call, {
    required void Function(String message) onError,
  }) async {
    try {
      return await call();
    } on ApiError catch (e) {
      onError(e.displayMessage);
      return null;
    }
  }
}
