/**
 * 共享的后端 envelope 解析工具
 *
 * 4 个 `*_api.ts` 文件中重复的 `interface ApiEnvelope<T>` 与 `function unwrap<T>`
 * 集中到这里。HTTP 拦截器（`http_client.ts`）已经对非 2xx 响应抛 `ApiError`；
 * 本工具处理第二种失败：2xx 但 `success: false` 的 envelope。
 *
 * 行为升级：失败时抛 `ApiError`（`ApiError extends Error`），而不是裸 `Error`。
 * 这样调用方在 `Result.err` 内能 `instanceof ApiError` 检查 `.code` / `.status`。
 *
 * 
 */
import { ApiError, ErrorCode } from "./api_result";

/** 后端统一响应包装。 */
export interface ApiEnvelope<T> {
  success: boolean;
  data?: T;
  message?: string;
  error?: string;
}

/**
 * 解包 envelope，失败时抛 `ApiError`。
 * 用于：data 字段必有（API 一定返回业务数据）的端点。
 */
export function unwrap<T>(envelope: ApiEnvelope<T>): T {
  if (!envelope.success || envelope.data === undefined) {
    throw new ApiError(
      ErrorCode.unknownError,
      envelope.message ?? envelope.error ?? "API call failed",
    );
  }
  return envelope.data;
}

/**
 * 解包 envelope，但允许 `data` 字段为 `undefined`（用于 fire-and-forget 类端点）。
 * 失败时仍抛 `ApiError`。
 */
export function unwrapOptional<T>(envelope: ApiEnvelope<T>): T | undefined {
  if (!envelope.success) {
    throw new ApiError(
      ErrorCode.unknownError,
      envelope.message ?? envelope.error ?? "API call failed",
    );
  }
  return envelope.data;
}
