
import 'network_callbacks.dart';

/// API 配置
/// 非单例，由 App 层构造并注入到 ApiClient
class ApiConfig {
  /// 基础 URL（来自 config.json → AppConfig.apiBaseUrl）
  String baseURL;

  /// 当前 token（内存持有，App 层负责持久化）
  String? token;

  /// 平台相关 headers（App 层注入：version、platform、channel 等）
  Map<String, String> platformHeaders;

  /// Token 过期时的刷新回调
  final OnTokenRefresh? onTokenRefresh;

  /// 需要强制登出时的回调
  final OnForceLogout? onForceLogout;

  /// 日志输出回调（不设置则不输出日志）
  final OnLog? onLog;

  /// 网络可用性查询（App 层注入，请求前调用）
  ///
  /// 与 [SocketConfig.onCheckNetworkAvailable] 对称。
  /// 返回 true 表示网络可用，可以发起请求；
  /// 返回 false 则直接抛 [ApiError.noNetworkConnection]，不走网络。
  final OnCheckNetworkAvailable? onCheckNetworkAvailable;

  /// App 层定义的 Token 过期错误码集合
  final Set<int> tokenExpiredCodes;

  /// App 层定义的强制登出错误码集合
  final Set<int> forceLogoutCodes;

  /// 瞬态错误最大重试次数（5xx / 超时 / 连接失败）
  ///
  /// 0 = 不重试（默认），设为 3 启用重试。
  /// 与 Token 刷新重试独立，两者可叠加。
  final int maxRetries;

  /// 重试基础延迟（指数退避起点）
  ///
  /// 实际延迟 = min(baseDelay * 2^attempt, 30s) + jitter
  final Duration retryBaseDelay;

  ApiConfig({
    required this.baseURL,
    this.token,
    this.platformHeaders = const {},
    this.onTokenRefresh,
    this.onForceLogout,
    this.onLog,
    this.onCheckNetworkAvailable,
    this.tokenExpiredCodes = const {},
    this.forceLogoutCodes = const {},
    this.maxRetries = 0,
    this.retryBaseDelay = const Duration(seconds: 1),
  });

  /// 构建默认 headers
  /// [includeToken] — 是否注入 token
  /// [customHeaders] — 单次请求自定义 header（优先级最高）
  Map<String, String> defaultHeaders({
    bool includeToken = true,
    Map<String, String>? customHeaders,
  }) {
    final headers = <String, String>{
      'Content-Type': 'application/json; charset=utf-8',
      'Accept': 'application/json',
      'Timestamp': '${DateTime.now().millisecondsSinceEpoch ~/ 1000}',
      'APP-Request-ID': _generateRequestId(),
    };

    // 合并平台 headers（App 层注入的 version、platform 等）
    headers.addAll(platformHeaders);

    // Token 注入
    if (includeToken && token != null && token!.isNotEmpty) {
      headers['token'] = token!;
    }

    // 单次请求自定义 header（覆盖默认值）
    if (customHeaders != null) {
      headers.addAll(customHeaders);
    }

    return headers;
  }

  /// 更新 token
  void updateToken(String? newToken) {
    token = newToken;
  }

  /// 更新 base URL
  void updateBaseURL(String newBaseURL) {
    baseURL = newBaseURL;
  }

  /// 生成请求 ID（用于幂等性）
  String _generateRequestId() {
    final now = DateTime.now().microsecondsSinceEpoch;
    return '$now${Object().hashCode}';
  }
}