/// 网络层回调类型定义，由 App 层注入 SDK，避免 SDK 直接依赖外部实现。
library;

import 'package:networks_sdk/src/domain/entities/encrypted_request.dart';

// ── 认证 ──

/// Token 刷新回调，返回新 token；返回 null 表示刷新失败
typedef OnTokenRefresh = Future<String?> Function();

// ── Token 生命周期 ──

/// 获取 token 过期时间
///
/// App 层解析 JWT 的 `exp` claim 返回过期时间。
/// 返回 null 表示无法解析（非 JWT 或格式错误）。
typedef OnGetTokenExpiry = DateTime? Function(String token);

// ── 基础 ──

/// 日志输出回调
typedef OnLog = void Function(String message, {String? tag});

/// 网络可用性查询（App 层注入，SDK 在请求前调用）
typedef OnCheckNetworkAvailable = Future<bool> Function();

// ── 加密（预留给 cipher_guard_sdk）──

/// HTTP 请求加密回调
///
/// 接收原始路径、headers、请求体，返回 [EncryptedRequest]。
/// 拦截器根据返回值中的非 null 字段覆盖原始请求。
///
/// 参数说明：
/// - [path] — 原始请求路径（如 `/api/v1/auth/login`）
/// - [headers] — 当前请求的全部 headers（含 token、platform headers 等）
/// - [body] — 原始请求体（可能是 Map、String、null 等）
///
/// App 层实现示例（X25519 + AES-256-CBC 模式）：
/// - 加密 path → hex 编码 → 替换路径
/// - 加密 body → base64 编码 → 替换请求体
/// - 加密 token → 放入 X-Token header
/// - Ed25519 签名 → 放入 X-Signature header
/// - Content-Type → text/plain
typedef OnEncryptRequest =
    Future<EncryptedRequest> Function(
      String path,
      Map<String, String> headers,
      Object? body,
    );

/// HTTP 响应解密回调
///
/// 输入是原始响应数据（加密后可能是 String、`List<int>`、或 Map），
/// 返回解密后的 Map 供业务层使用。
///
/// [responseData] 的实际类型取决于服务端响应格式：
/// - 加密模式下通常是 base64 字符串
/// - 非加密模式下是 `Map<String, dynamic>`（拦截器会自动跳过，不调用此回调）
///
/// 实现时建议做类型判断兜底，应对非预期的响应格式：
/// ```dart
/// onDecryptResponse: (data) async {
///   if (data is! String) throw FormatException('Expected String, got ${data.runtimeType}');
///   return jsonDecode(aesDecrypt(data));
/// }
/// ```
typedef OnDecryptResponse =
    Future<Map<String, dynamic>> Function(Object responseData);

// ── 业务错误 ──

/// SDK 层收到 App 层对业务错误码的处置指令
enum BusinessErrorAction {
  /// 刷新 token 后重试原请求（原 tokenExpiredCodes 行为）
  refreshToken,

  /// 强制登出，中断当前请求（原 forceLogoutCodes 行为）
  forceLogout,

  /// App 层已处理（如全局弹窗/Toast），SDK 正常放行响应，不在 decodeResponse 中抛错
  handled,

  /// 未处理，SDK 继续正常流程，decodeResponse 会抛 ApiError 给调用方
  unhandled,
}

/// 业务错误统一回调
///
/// 所有非 0 业务码（token 过期、强制登出、踢下线、普通业务错误）全部经此入口，
/// App 层通过返回 [BusinessErrorAction] 告诉 SDK 该怎么做。
typedef OnBusinessError =
    BusinessErrorAction Function(int code, String message, String path);

/// 响应变换回调
///
/// App 层自定义响应解包逻辑（如统一解包 `{ code, data, message }` 结构）。
/// 返回 null 表示不变换，使用原始响应。
typedef OnTransformResponse =
    Map<String, dynamic>? Function(Map<String, dynamic> raw);

// ── 下载 ──

/// 下载进度回调
typedef OnDownloadProgress = void Function(int received, int total);

// ── WebSocket 加密（预留给 cipher_guard_sdk）──

/// WebSocket 连接 URL 构建回调
///
/// 建立连接前调用，接收原始 URL 和 token，返回最终的连接 URL 字符串。
/// WS 握手本质是 HTTP GET 升级请求，只需控制 URL（路径 + 查询参数）。
///
/// App 层可在此（通过调用 cipher_guard_sdk）：
/// - 加密 URL 路径（如 `/ws` → `/hex(encrypt(ws))`）
/// - 加密 token 参数（明文 token 不出现在 URL 中）
/// - 添加加密模式协商参数（如 `cipher=true&type=mode3`）
///
/// null 时使用默认行为：在 URL 后追加 `?token=xxx`。
typedef OnBuildConnectUrl = String Function(String url, String? token);

/// WebSocket 发送前加密回调
typedef OnEncryptMessage = Future<String> Function(String plainText);

/// WebSocket 收到后解密回调
typedef OnDecryptMessage = Future<String> Function(String cipherText);
