// ============================================================
// SessionStorage — 认证令牌安全持久化存储
//
// 存储后端：flutter_secure_storage
//   Android : EncryptedSharedPreferences（AES-256-GCM，Keystore 托管密钥）
//   iOS     : Keychain（AccessibilityFirstUnlock — 首次解锁后可读）
//
// 存储键（全部带 "genex_" 前缀，避免与其他 App 数据冲突）：
//   genex_access_token  — JWT Access Token（短期，通常 15 min～2 h）
//   genex_refresh_token — JWT Refresh Token（长期，通常 7～30 天）
//   genex_user_json     — 用户基本信息 JSON（昵称、头像 URL、userId 等）
//
// 调用时机：
//   save()         — 登录/注册/Token 刷新成功后，AuthService._setAuth() 调用
//   load()         — App 冷启动时，AuthService.restoreSession() 调用
//   updateTokens() — Token 刷新成功后，ApiClient 拦截器调用（不覆盖用户 JSON）
//   clear()        — 登出/Token 彻底过期时，AuthService._clearAuth() 调用
// ============================================================

import 'dart:convert';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';

/// 从安全存储加载的已保存会话
class SavedSession {
  /// 上次保存的 Access Token（可能已过期，由 ApiClient 拦截器自动刷新）
  final String accessToken;

  /// Refresh Token（用于无感刷新 Access Token）
  final String refreshToken;

  /// 上次保存的用户信息（离线可用，不保证最新）
  final Map<String, dynamic> user;

  const SavedSession({
    required this.accessToken,
    required this.refreshToken,
    required this.user,
  });
}

/// 认证令牌安全存储 — 单例
class SessionStorage {
  static final SessionStorage _instance = SessionStorage._();
  static SessionStorage get instance => _instance;
  SessionStorage._();

  // ── 平台配置 ──────────────────────────────────────────────────────────────

  static const _storage = FlutterSecureStorage(
    // Android: 使用 EncryptedSharedPreferences，密钥由 Android Keystore 管理
    aOptions: AndroidOptions(encryptedSharedPreferences: true),
    // iOS: 首次设备解锁后即可访问（兼顾安全性与后台可用性）
    iOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock),
  );

  // ── 存储键 ─────────────────────────────────────────────────────────────────

  static const _kAccessToken = 'genex_access_token';
  static const _kRefreshToken = 'genex_refresh_token';
  static const _kUserJson = 'genex_user_json';

  // ── 公开 API ───────────────────────────────────────────────────────────────

  /// 保存完整会话（登录 / 注册成功后调用）
  ///
  /// 三个键并发写入以减少等待时间。
  Future<void> save({
    required String accessToken,
    required String refreshToken,
    required Map<String, dynamic> user,
  }) async {
    await Future.wait([
      _storage.write(key: _kAccessToken, value: accessToken),
      _storage.write(key: _kRefreshToken, value: refreshToken),
      _storage.write(key: _kUserJson, value: jsonEncode(user)),
    ]);
  }

  /// 加载已保存的会话（App 冷启动时调用）
  ///
  /// 返回 null 表示用户从未登录或已手动登出。
  /// 返回的 [SavedSession.accessToken] 可能已过期——
  /// 不做主动校验，首次 API 调用若收到 401 则由 ApiClient 拦截器自动刷新。
  Future<SavedSession?> load() async {
    final accessToken = await _storage.read(key: _kAccessToken);
    if (accessToken == null || accessToken.isEmpty) return null;

    final refreshToken = await _storage.read(key: _kRefreshToken);
    if (refreshToken == null || refreshToken.isEmpty) return null;

    final userJson = await _storage.read(key: _kUserJson);
    Map<String, dynamic> user = {};
    if (userJson != null) {
      try {
        user = jsonDecode(userJson) as Map<String, dynamic>;
      } catch (_) {
        // JSON 损坏时降级为空 Map，不影响 Token 有效性
      }
    }

    return SavedSession(
      accessToken: accessToken,
      refreshToken: refreshToken,
      user: user,
    );
  }

  /// 仅更新双 Token（Token 静默刷新后调用，不覆盖用户 JSON）
  Future<void> updateTokens(String accessToken, String refreshToken) async {
    await Future.wait([
      _storage.write(key: _kAccessToken, value: accessToken),
      _storage.write(key: _kRefreshToken, value: refreshToken),
    ]);
  }

  /// 读取 Refresh Token（ApiClient 拦截器执行刷新时调用）
  Future<String?> getRefreshToken() => _storage.read(key: _kRefreshToken);

  /// 清空所有会话数据（登出 / Token 彻底过期时调用）
  Future<void> clear() async {
    await Future.wait([
      _storage.delete(key: _kAccessToken),
      _storage.delete(key: _kRefreshToken),
      _storage.delete(key: _kUserJson),
    ]);
  }
}
