import 'package:flutter/foundation.dart';
import '../network/api_client.dart';

/// SMS 验证码类型
enum SmsCodeType {
  register('REGISTER'),
  login('LOGIN'),
  resetPassword('RESET_PASSWORD'),
  changePhone('CHANGE_PHONE');

  final String value;
  const SmsCodeType(this.value);
}

/// 认证结果
class AuthResult {
  final Map<String, dynamic> user;
  final String accessToken;
  final String refreshToken;
  final int expiresIn;

  AuthResult({
    required this.user,
    required this.accessToken,
    required this.refreshToken,
    required this.expiresIn,
  });

  factory AuthResult.fromJson(Map<String, dynamic> json) {
    final tokens = json['tokens'] as Map<String, dynamic>;
    return AuthResult(
      user: json['user'] as Map<String, dynamic>,
      accessToken: tokens['accessToken'] as String,
      refreshToken: tokens['refreshToken'] as String,
      expiresIn: tokens['expiresIn'] as int,
    );
  }
}

/// Auth Service — 对接后端 auth-service API
class AuthService {
  static final AuthService _instance = AuthService._();
  static AuthService get instance => _instance;
  AuthService._();

  final _api = ApiClient.instance;

  // 登录状态
  final ValueNotifier<AuthResult?> authState = ValueNotifier(null);
  bool get isLoggedIn => authState.value != null;

  /* ── SMS 验证码 ── */

  /// 发送短信验证码
  /// 返回 expiresIn (秒)
  Future<int> sendSmsCode(String phone, SmsCodeType type) async {
    final resp = await _api.post('/api/v1/auth/sms/send', data: {
      'phone': phone,
      'type': type.value,
    });
    final data = resp.data['data'] as Map<String, dynamic>;
    return data['expiresIn'] as int;
  }

  /* ── 注册 ── */

  /// 手机号注册 (需先获取 REGISTER 类型验证码)
  Future<AuthResult> register({
    required String phone,
    required String smsCode,
    required String password,
    String? nickname,
  }) async {
    final resp = await _api.post('/api/v1/auth/register', data: {
      'phone': phone,
      'smsCode': smsCode,
      'password': password,
      if (nickname != null) 'nickname': nickname,
    });
    final result = AuthResult.fromJson(resp.data['data']);
    _setAuth(result);
    return result;
  }

  /* ── 登录 ── */

  /// 密码登录
  Future<AuthResult> loginByPassword({
    required String identifier,
    required String password,
    String? deviceInfo,
  }) async {
    final resp = await _api.post('/api/v1/auth/login', data: {
      'identifier': identifier,
      'password': password,
      if (deviceInfo != null) 'deviceInfo': deviceInfo,
    });
    final result = AuthResult.fromJson(resp.data['data']);
    _setAuth(result);
    return result;
  }

  /// 短信验证码登录 (需先获取 LOGIN 类型验证码)
  Future<AuthResult> loginByPhone({
    required String phone,
    required String smsCode,
    String? deviceInfo,
  }) async {
    final resp = await _api.post('/api/v1/auth/login-phone', data: {
      'phone': phone,
      'smsCode': smsCode,
      if (deviceInfo != null) 'deviceInfo': deviceInfo,
    });
    final result = AuthResult.fromJson(resp.data['data']);
    _setAuth(result);
    return result;
  }

  /* ── 密码管理 ── */

  /// 重置密码 (需先获取 RESET_PASSWORD 类型验证码)
  Future<void> resetPassword({
    required String phone,
    required String smsCode,
    required String newPassword,
  }) async {
    await _api.post('/api/v1/auth/reset-password', data: {
      'phone': phone,
      'smsCode': smsCode,
      'newPassword': newPassword,
    });
  }

  /// 修改密码 (需登录)
  Future<void> changePassword({
    required String oldPassword,
    required String newPassword,
  }) async {
    await _api.post('/api/v1/auth/change-password', data: {
      'oldPassword': oldPassword,
      'newPassword': newPassword,
    });
    // 修改密码后强制重新登录
    logout();
  }

  /* ── 手机号管理 ── */

  /// 换绑手机号 (需登录 + CHANGE_PHONE 类型验证码)
  Future<void> changePhone({
    required String newPhone,
    required String newSmsCode,
  }) async {
    await _api.post('/api/v1/auth/change-phone', data: {
      'newPhone': newPhone,
      'newSmsCode': newSmsCode,
    });
  }

  /* ── Token 管理 ── */

  /// 刷新 Token
  Future<void> refreshToken() async {
    final current = authState.value;
    if (current == null) return;

    final resp = await _api.post('/api/v1/auth/refresh', data: {
      'refreshToken': current.refreshToken,
    });
    final tokens = resp.data['data'] as Map<String, dynamic>;
    final newResult = AuthResult(
      user: current.user,
      accessToken: tokens['accessToken'] as String,
      refreshToken: tokens['refreshToken'] as String,
      expiresIn: tokens['expiresIn'] as int,
    );
    _setAuth(newResult);
  }

  /// 登出
  Future<void> logout() async {
    try {
      await _api.post('/api/v1/auth/logout');
    } catch (_) {
      // 即使请求失败也清除本地状态
    }
    _clearAuth();
  }

  /* ── Private ── */

  void _setAuth(AuthResult result) {
    authState.value = result;
    _api.setToken(result.accessToken);
  }

  void _clearAuth() {
    authState.value = null;
    _api.setToken(null);
  }
}
