import 'dart:convert';
import 'package:flutter/foundation.dart';
import '../storage/secure_storage.dart';
import '../storage/local_storage.dart';
import '../storage/storage_keys.dart';
import '../telemetry/telemetry_service.dart';
import '../telemetry/storage/telemetry_storage.dart';
import '../sentry/sentry_service.dart';

/// 账号信息摘要（用于账号列表显示）
class AccountSummary {
  final String userSerialNum;  // 用户序列号，作为唯一标识
  final String username;       // 用户名
  final String? avatarSvg;     // SVG 头像
  final String? avatarUrl;     // 自定义头像 URL
  final DateTime createdAt;    // 创建时间

  AccountSummary({
    required this.userSerialNum,
    required this.username,
    this.avatarSvg,
    this.avatarUrl,
    required this.createdAt,
  });

  Map<String, dynamic> toJson() => {
    'userSerialNum': userSerialNum,
    'username': username,
    'avatarSvg': avatarSvg,
    'avatarUrl': avatarUrl,
    'createdAt': createdAt.toIso8601String(),
  };

  factory AccountSummary.fromJson(Map<String, dynamic> json) {
    return AccountSummary(
      userSerialNum: json['userSerialNum'] as String,
      username: json['username'] as String,
      avatarSvg: json['avatarSvg'] as String?,
      avatarUrl: json['avatarUrl'] as String?,
      createdAt: DateTime.parse(json['createdAt'] as String),
    );
  }

  @override
  String toString() => 'AccountSummary(userSerialNum: $userSerialNum, username: $username)';
}

/// 多账号管理服务
/// 负责管理多个账号的存储和切换
class MultiAccountService {
  static const String _tag = '[MultiAccountService]';

  final SecureStorage _secureStorage;
  final LocalStorage _localStorage;
  final TelemetryStorage _telemetryStorage;

  MultiAccountService(
    this._secureStorage,
    this._localStorage,
    this._telemetryStorage,
  );

  /// 切换中标志位：在整个切换流程期间为 true
  /// 用于防止切换过程中 in-flight API 请求收到 401 后触发 tokenExpired → logoutCurrentAccount()
  /// 把刚恢复的新账号数据全部清掉
  bool _isSwitchingAccount = false;

  /// 是否正在切换账号（供外部读取，如 app.dart 的 _handleTokenExpired）
  bool get isSwitchingAccount => _isSwitchingAccount;

  // ===== 账号数据键列表（统一定义，确保一致性） =====

  /// 需要按账号隔离保存的 SecureStorage 键
  /// 这些数据在切换账号时会保存到账号专用存储，并在切换回来时恢复
  static const List<String> _accountSecureKeys = [
    // Token
    StorageKeys.accessToken,
    StorageKeys.refreshToken,
    // 账号基本信息
    StorageKeys.userSerialNum,
    StorageKeys.username,
    StorageKeys.avatarSvg,
    StorageKeys.avatarUrl,
    StorageKeys.referralCode,
    StorageKeys.inviterSequence,
    StorageKeys.inviterReferralCode,
    StorageKeys.isAccountCreated,
    StorageKeys.phoneNumber,
    StorageKeys.isPasswordSet,
    // 钱包信息
    StorageKeys.walletAddressBsc,
    StorageKeys.walletAddressKava,
    StorageKeys.walletAddressDst,
    StorageKeys.mnemonic,
    StorageKeys.isWalletReady,
    StorageKeys.isMnemonicBackedUp,
    // 安全设置
    StorageKeys.biometricEnabled,
  ];

  /// 需要按账号隔离保存的 LocalStorage 键（缓存数据）
  static const List<String> _accountLocalKeys = [
    StorageKeys.lastSyncTime,
    StorageKeys.cachedRankingData,
    StorageKeys.cachedMiningStatus,
    // 种植省市选择
    StorageKeys.plantingProvinceName,
    StorageKeys.plantingProvinceCode,
    StorageKeys.plantingCityName,
    StorageKeys.plantingCityCode,
    // 非敏感缓存（仍需隔离以保证干净环境）
    StorageKeys.cachedAppAssets,
    StorageKeys.cachedCustomerServiceContacts,
  ];

  /// 获取账号列表
  Future<List<AccountSummary>> getAccountList() async {
    debugPrint('$_tag getAccountList() - 获取账号列表');
    try {
      final jsonStr = await _secureStorage.read(key: StorageKeys.accountList);
      if (jsonStr == null || jsonStr.isEmpty) {
        debugPrint('$_tag getAccountList() - 账号列表为空');
        return [];
      }
      final List<dynamic> jsonList = jsonDecode(jsonStr);
      final accounts = jsonList
          .map((e) => AccountSummary.fromJson(e as Map<String, dynamic>))
          .toList();
      debugPrint('$_tag getAccountList() - 找到 ${accounts.length} 个账号');
      return accounts;
    } catch (e) {
      debugPrint('$_tag getAccountList() - 解析失败: $e');
      return [];
    }
  }

  /// 保存账号列表
  Future<void> _saveAccountList(List<AccountSummary> accounts) async {
    final jsonStr = jsonEncode(accounts.map((e) => e.toJson()).toList());
    await _secureStorage.write(key: StorageKeys.accountList, value: jsonStr);
    debugPrint('$_tag _saveAccountList() - 保存 ${accounts.length} 个账号');
  }

  /// 添加账号到列表
  Future<void> addAccount(AccountSummary account) async {
    debugPrint('$_tag addAccount() - 添加账号: ${account.userSerialNum}');
    final accounts = await getAccountList();

    // 检查是否已存在
    final existingIndex = accounts.indexWhere(
      (a) => a.userSerialNum == account.userSerialNum,
    );

    if (existingIndex >= 0) {
      // 更新现有账号
      accounts[existingIndex] = account;
      debugPrint('$_tag addAccount() - 更新现有账号');
    } else {
      // 添加新账号
      accounts.add(account);
      debugPrint('$_tag addAccount() - 添加新账号');
    }

    await _saveAccountList(accounts);
  }

  /// 更新账号列表中的账号信息（如头像变更时调用）
  /// 仅更新指定字段，保留其他字段不变
  Future<void> updateAccountInList({
    required String userSerialNum,
    String? username,
    String? avatarSvg,
    String? avatarUrl,
  }) async {
    debugPrint('$_tag updateAccountInList() - 更新账号: $userSerialNum');
    final accounts = await getAccountList();

    final existingIndex = accounts.indexWhere(
      (a) => a.userSerialNum == userSerialNum,
    );

    if (existingIndex < 0) {
      debugPrint('$_tag updateAccountInList() - 账号不存在');
      return;
    }

    final existing = accounts[existingIndex];
    accounts[existingIndex] = AccountSummary(
      userSerialNum: existing.userSerialNum,
      username: username ?? existing.username,
      avatarSvg: avatarSvg ?? existing.avatarSvg,
      avatarUrl: avatarUrl ?? existing.avatarUrl,
      createdAt: existing.createdAt,
    );

    await _saveAccountList(accounts);
    debugPrint('$_tag updateAccountInList() - 更新成功');
  }

  /// 从列表中移除账号
  Future<void> removeAccount(String userSerialNum) async {
    debugPrint('$_tag removeAccount() - 移除账号: $userSerialNum');
    final accounts = await getAccountList();
    accounts.removeWhere((a) => a.userSerialNum == userSerialNum);
    await _saveAccountList(accounts);
  }

  /// 获取当前活跃账号ID
  Future<String?> getCurrentAccountId() async {
    return await _secureStorage.read(key: StorageKeys.currentAccountId);
  }

  /// 设置当前活跃账号ID
  Future<void> setCurrentAccountId(String? accountId) async {
    if (accountId == null) {
      await _secureStorage.delete(key: StorageKeys.currentAccountId);
    } else {
      await _secureStorage.write(key: StorageKeys.currentAccountId, value: accountId);
    }
    debugPrint('$_tag setCurrentAccountId() - 设置为: $accountId');
  }

  /// 切换到指定账号
  /// 返回 true 表示切换成功
  ///
  /// 整个切换过程中 [isSwitchingAccount] 为 true，
  /// app.dart 的 _handleTokenExpired 会检查此标志，忽略切换期间的 tokenExpired 事件，
  /// 防止 in-flight API 请求收到 401 后触发 logoutCurrentAccount() 擦除新账号数据。
  ///
  /// 调用方应在调用本方法之前先停止所有定时器和轮询（如 walletStatus、pendingAction、
  /// notificationBadge 等），确保 save 阶段不会有新的 API 请求发出。
  ///
  /// [onBeforeRestore] 可选回调，在 clear 之前调用（已弃用，建议在调用方提前停止定时器）。
  ///
  /// 切换流程：
  /// 0. 设置 isSwitchingAccount = true
  /// 1. 验证目标账号存在
  /// 2. 验证目标账号数据完整性
  /// 3. 保存当前账号数据到账号专用存储
  /// 3.5 调用 onBeforeRestore（如果提供）
  /// 4. 清除当前存储空间（确保干净环境）
  /// 5. 从账号专用存储恢复目标账号数据
  /// 6. 设置当前账号标记
  /// 7. 更新遥测和错误追踪服务的用户信息
  /// 8. 设置 isSwitchingAccount = false
  Future<bool> switchToAccount(String userSerialNum, {Future<void> Function()? onBeforeRestore}) async {
    debugPrint('$_tag switchToAccount() - 切换到账号: $userSerialNum');

    // 立即设置切换中标志，阻止 _handleTokenExpired 在切换期间触发 logoutCurrentAccount
    _isSwitchingAccount = true;
    debugPrint('$_tag switchToAccount() - ★ isSwitchingAccount = true');

    try {
      // 1. 验证账号存在于列表中
      final accounts = await getAccountList();
      final account = accounts.where((a) => a.userSerialNum == userSerialNum).firstOrNull;

      if (account == null) {
        debugPrint('$_tag switchToAccount() - 账号不在列表中');
        return false;
      }

      // 2. 验证目标账号数据完整性（至少要有 accessToken 或 mnemonic）
      final hasValidData = await _validateAccountData(userSerialNum);
      if (!hasValidData) {
        debugPrint('$_tag switchToAccount() - 账号数据不完整，无法切换');
        return false;
      }

      // 3. 保存当前账号数据（如果有）
      final currentId = await getCurrentAccountId();
      if (currentId != null && currentId != userSerialNum) {
        await saveCurrentAccountData();
        debugPrint('$_tag switchToAccount() - 已保存当前账号数据: $currentId');
      }

      // 3.5 停止所有定时器（如果有回调；建议调用方在外部提前停止）
      if (onBeforeRestore != null) {
        await onBeforeRestore();
        debugPrint('$_tag switchToAccount() - 已执行 onBeforeRestore 回调');
      }

      // 4. 清除当前存储空间（确保干净环境，避免数据残留）
      await _clearCurrentAccountData();

      // 5. 从账号专用存储恢复目标账号数据
      await _restoreAccountData(userSerialNum);

      // 6. 设置当前账号标记
      await setCurrentAccountId(userSerialNum);

      // 7. 更新遥测服务的用户ID和访问令牌（_restoreAccountData 已将 token 写入 SecureStorage）
      if (TelemetryService().isInitialized) {
        TelemetryService().setUserId(userSerialNum);
        final restoredToken = await _secureStorage.read(key: StorageKeys.accessToken);
        TelemetryService().setAccessToken(restoredToken);
        debugPrint('$_tag switchToAccount() - 设置TelemetryService userId: $userSerialNum');
      }

      // 8. 更新 Sentry 用户信息
      if (SentryService().isInitialized) {
        SentryService().setUser(userId: userSerialNum);
        debugPrint('$_tag switchToAccount() - 设置SentryService userId: $userSerialNum');
      }

      debugPrint('$_tag switchToAccount() - 切换成功');
      return true;
    } finally {
      // 无论成功或失败，都必须清除标志位，否则后续真正的 tokenExpired 也会被忽略
      _isSwitchingAccount = false;
      debugPrint('$_tag switchToAccount() - ★ isSwitchingAccount = false');
    }
  }

  /// 验证账号数据完整性
  /// 检查账号专用存储中是否有必要的数据
  Future<bool> _validateAccountData(String accountId) async {
    // 至少需要有 userSerialNum
    final userSerialNumKey = StorageKeys.withAccountPrefix(accountId, StorageKeys.userSerialNum);
    final userSerialNum = await _secureStorage.read(key: userSerialNumKey);

    if (userSerialNum == null || userSerialNum.isEmpty) {
      debugPrint('$_tag _validateAccountData() - 缺少 userSerialNum');
      return false;
    }

    // 检查是否有 token 或助记词（至少需要一个才能使用账号）
    final accessTokenKey = StorageKeys.withAccountPrefix(accountId, StorageKeys.accessToken);
    final mnemonicKey = StorageKeys.withAccountPrefix(accountId, StorageKeys.mnemonic);

    final accessToken = await _secureStorage.read(key: accessTokenKey);
    final mnemonic = await _secureStorage.read(key: mnemonicKey);

    if ((accessToken == null || accessToken.isEmpty) &&
        (mnemonic == null || mnemonic.isEmpty)) {
      debugPrint('$_tag _validateAccountData() - 缺少 accessToken 和 mnemonic');
      return false;
    }

    return true;
  }

  /// 清除当前存储空间（不删除账号专用存储）
  /// 用于切换账号前确保干净环境
  Future<void> _clearCurrentAccountData() async {
    debugPrint('$_tag _clearCurrentAccountData() - 清除当前存储空间');

    // 清除 SecureStorage 中的账号数据
    for (final key in _accountSecureKeys) {
      await _secureStorage.delete(key: key);
    }

    // 清除 LocalStorage 中的缓存数据
    for (final key in _accountLocalKeys) {
      await _localStorage.remove(key);
    }

    // 清除遥测事件队列
    await _telemetryStorage.clearUserData();

    debugPrint('$_tag _clearCurrentAccountData() - 清除完成');
  }

  /// 保存当前账号数据到账号专用存储
  /// 包括 SecureStorage 和 LocalStorage 中的账号相关数据
  Future<void> saveCurrentAccountData() async {
    final currentId = await getCurrentAccountId();
    if (currentId == null) {
      debugPrint('$_tag saveCurrentAccountData() - 无当前账号');
      return;
    }

    debugPrint('$_tag saveCurrentAccountData() - 保存账号数据: $currentId');

    // 保存 SecureStorage 中的数据
    int secureCount = 0;
    for (final key in _accountSecureKeys) {
      final value = await _secureStorage.read(key: key);
      if (value != null) {
        final prefixedKey = StorageKeys.withAccountPrefix(currentId, key);
        await _secureStorage.write(key: prefixedKey, value: value);
        secureCount++;
      }
    }

    // 保存 LocalStorage 中的缓存数据
    int localCount = 0;
    for (final key in _accountLocalKeys) {
      final value = _localStorage.getString(key);
      if (value != null) {
        final prefixedKey = StorageKeys.withAccountPrefix(currentId, key);
        await _localStorage.setString(prefixedKey, value);
        localCount++;
      }
    }

    debugPrint('$_tag saveCurrentAccountData() - 保存完成 (Secure: $secureCount, Local: $localCount)');
  }

  /// 从账号专用存储恢复数据到当前存储
  /// 包括 SecureStorage 和 LocalStorage 中的账号相关数据
  Future<void> _restoreAccountData(String accountId) async {
    debugPrint('$_tag _restoreAccountData() - 恢复账号数据: $accountId');

    // 恢复 SecureStorage 中的数据
    int secureCount = 0;
    for (final key in _accountSecureKeys) {
      final prefixedKey = StorageKeys.withAccountPrefix(accountId, key);
      final value = await _secureStorage.read(key: prefixedKey);
      if (value != null) {
        await _secureStorage.write(key: key, value: value);
        secureCount++;
      }
      // 注意：不需要删除，因为 _clearCurrentAccountData 已经清除过了
    }

    // 恢复 LocalStorage 中的缓存数据
    int localCount = 0;
    for (final key in _accountLocalKeys) {
      final prefixedKey = StorageKeys.withAccountPrefix(accountId, key);
      final value = _localStorage.getString(prefixedKey);
      if (value != null) {
        await _localStorage.setString(key, value);
        localCount++;
      }
    }

    debugPrint('$_tag _restoreAccountData() - 恢复完成 (Secure: $secureCount, Local: $localCount)');
  }

  /// 退出当前账号（不删除账号数据）
  /// 清除当前会话状态，但保留账号在列表中
  /// 遵循大厂最佳实践，确保下次登录是干净的环境
  Future<void> logoutCurrentAccount() async {
    debugPrint('$_tag logoutCurrentAccount() - 退出当前账号');

    // 清除当前账号标记
    await setCurrentAccountId(null);

    // ===== 1. 清除 SecureStorage 中的账号数据 =====
    // 使用统一的键列表，确保一致性
    for (final key in _accountSecureKeys) {
      await _secureStorage.delete(key: key);
    }
    // inviterReferralCode 已包含在 _accountSecureKeys 中，无需额外清除
    debugPrint('$_tag logoutCurrentAccount() - 已清除 ${_accountSecureKeys.length} 个 SecureStorage 键');

    // ===== 2. 清除 LocalStorage 中的缓存数据 =====
    for (final key in _accountLocalKeys) {
      await _localStorage.remove(key);
    }
    debugPrint('$_tag logoutCurrentAccount() - 已清除 ${_accountLocalKeys.length} 个 LocalStorage 缓存');

    // ===== 3. 暂停遥测服务（停止上传、清空队列、清除用户ID） =====
    if (TelemetryService().isInitialized) {
      await TelemetryService().pauseForLogout();
      debugPrint('$_tag logoutCurrentAccount() - 已暂停 TelemetryService');
    }

    // ===== 4. 清除 Sentry 用户信息 =====
    if (SentryService().isInitialized) {
      SentryService().clearUser();
      debugPrint('$_tag logoutCurrentAccount() - 清除 SentryService userId');
    }

    final totalCleared = _accountSecureKeys.length + _accountLocalKeys.length + 1;
    debugPrint('$_tag logoutCurrentAccount() - 退出完成，共清除 $totalCleared 个存储键 + 遥测数据');
  }

  /// 完全删除账号（包括所有数据）
  Future<void> deleteAccount(String userSerialNum) async {
    debugPrint('$_tag deleteAccount() - 删除账号: $userSerialNum');

    // 如果删除的是当前账号，先执行退出逻辑
    final currentId = await getCurrentAccountId();
    if (currentId == userSerialNum) {
      // 不需要保存数据，直接清除
      await setCurrentAccountId(null);
      await _clearCurrentAccountData();

      // 清除遥测和 Sentry 用户信息
      if (TelemetryService().isInitialized) {
        TelemetryService().clearUserId();
        TelemetryService().clearAccessToken();
      }
      if (SentryService().isInitialized) {
        SentryService().clearUser();
      }
    }

    // 从列表中移除
    await removeAccount(userSerialNum);

    // 删除账号专用存储的 SecureStorage 数据
    for (final key in _accountSecureKeys) {
      final prefixedKey = StorageKeys.withAccountPrefix(userSerialNum, key);
      await _secureStorage.delete(key: prefixedKey);
    }

    // 删除账号专用存储的 LocalStorage 数据
    for (final key in _accountLocalKeys) {
      final prefixedKey = StorageKeys.withAccountPrefix(userSerialNum, key);
      await _localStorage.remove(prefixedKey);
    }

    debugPrint('$_tag deleteAccount() - 删除完成，已清除 ${_accountSecureKeys.length + _accountLocalKeys.length} 个账号专用键');
  }

  /// 迁移旧数据到多账号架构
  /// 如果存在旧的单账号数据，将其添加到账号列表
  Future<void> migrateFromSingleAccount() async {
    debugPrint('$_tag migrateFromSingleAccount() - 检查是否需要迁移');

    // 检查是否已有账号列表
    final accounts = await getAccountList();
    if (accounts.isNotEmpty) {
      debugPrint('$_tag migrateFromSingleAccount() - 已有账号列表，无需迁移');
      return;
    }

    // 检查是否存在旧的单账号数据
    final userSerialNum = await _secureStorage.read(key: StorageKeys.userSerialNum);
    final isAccountCreated = await _secureStorage.read(key: StorageKeys.isAccountCreated);

    if (userSerialNum == null || isAccountCreated != 'true') {
      debugPrint('$_tag migrateFromSingleAccount() - 无旧账号数据');
      return;
    }

    // 获取账号信息
    final username = await _secureStorage.read(key: StorageKeys.username) ?? '未知用户';
    final avatarSvg = await _secureStorage.read(key: StorageKeys.avatarSvg);
    final avatarUrl = await _secureStorage.read(key: StorageKeys.avatarUrl);

    // 创建账号摘要
    final account = AccountSummary(
      userSerialNum: userSerialNum,
      username: username,
      avatarSvg: avatarSvg,
      avatarUrl: avatarUrl,
      createdAt: DateTime.now(), // 旧数据没有创建时间，使用当前时间
    );

    // 添加到账号列表
    await addAccount(account);

    // 设置为当前账号
    await setCurrentAccountId(userSerialNum);

    // 保存当前账号数据到账号专用存储
    await saveCurrentAccountData();

    debugPrint('$_tag migrateFromSingleAccount() - 迁移完成: $userSerialNum');
  }

  /// 检查是否有任何已登录的账号
  Future<bool> hasAnyAccount() async {
    final accounts = await getAccountList();
    return accounts.isNotEmpty;
  }

  /// 获取账号数量
  Future<int> getAccountCount() async {
    final accounts = await getAccountList();
    return accounts.length;
  }
}
