/**
 * HTTP 客户端工厂
 *
 * 创建配置好拦截器的 ofetch 实例。
 * 
 */
import { ofetch, type $Fetch, type FetchHook } from "ofetch";
import { ApiError, ErrorCode } from "./api_result";
import { getApiConfig } from "../../../core/net/config/api_config";
import { authRefreshInterceptor } from "../../../core/net/interceptor/auth_refresh_interceptor";
import { loggingInterceptor } from "../../../core/net/interceptor/logging_interceptor";
import { tokenInterceptor } from "../../../core/net/interceptor/token_interceptor";

/**
 * 合并多个同类型 hook 为单个 hook（按顺序执行）
 */
function chain(...fns: (FetchHook | undefined)[]): FetchHook {
  return async (ctx: unknown) => {
    for (const fn of fns) {
      if (fn) await (fn as (c: unknown) => Promise<void> | void)(ctx);
    }
  };
}

/**
 * 创建 ofetch 实例
 */
export function createHttpClient(): $Fetch {
  const config = getApiConfig();

  return ofetch.create({
    baseURL: config.baseUrl,
    timeout: config.receiveTimeout,
    retry: 0, // 401 刷新由 auth_refresh_interceptor 自定义处理
    headers: {
      "Content-Type": "application/json",
    },
    onRequest: chain(
      loggingInterceptor.onRequest,
      tokenInterceptor.onRequest
    ),
    onResponse: chain(loggingInterceptor.onResponse),
    onResponseError: chain(
      loggingInterceptor.onResponseError,
      authRefreshInterceptor.onResponseError,
      ((ctx: unknown) => {
        const c = ctx as {
          response?: { status?: number; _data?: unknown };
          error?: Error;
        };
        const status = c.response?.status;
        const code =
          status === ErrorCode.httpUnauthorized
            ? "HTTP_UNAUTHORIZED"
            : status === ErrorCode.httpServerError
              ? "HTTP_SERVER_ERROR"
              : "HTTP_ERROR";
        const data = c.response?._data;
        const message =
          (data as { message?: string; error?: string } | undefined)
            ?.message ??
          (data as { message?: string; error?: string } | undefined)
            ?.error ??
          c.error?.message ??
          "Unknown error";
        throw new ApiError(code, message, status, data);
      }) as FetchHook
    ),
    onRequestError: chain(loggingInterceptor.onResponseError),
  });
}

/**
 * 默认 HTTP 客户端实例
 */
export const httpClient = createHttpClient();
