/**
 * Token 拦截器
 *
 * 在请求头中注入 Authorization: Bearer <token>。
 * 跳过不需要 token 的路径（登录、注册、发送验证码、刷新等）。
 * 
 */
import type { FetchHook } from "ofetch";
import { Logger } from "@/utils";
import { ApiPath } from "../../../data/services/api/api_path";
import { AuthStorage } from "../../../data/storage/auth/auth_storage";

const log = new Logger("TokenInterceptor");

/**
 * 不需要 token 的路径
 */
const NO_TOKEN_PATHS: readonly string[] = [
  ApiPath.sendCode,
  ApiPath.emailLogin,
  ApiPath.register,
  ApiPath.guestLogin,
];

/**
 * 获取请求路径
 */
function getRequestPath(request: Request | string): string {
  if (typeof request === "string") {
    try {
      return new URL(request).pathname;
    } catch {
      return request;
    }
  }
  return new URL(request.url).pathname;
}

/**
 * 路径是否需要 token
 */
function needsToken(path: string): boolean {
  return !NO_TOKEN_PATHS.some((noTokenPath) => path.includes(noTokenPath));
}

/**
 * 获取当前可用的 auth token（登录 token 优先，其次游客 token）
 */
async function getAuthToken(): Promise<string | null> {
  const storage = AuthStorage.getInstance();
  const loginR = await storage.getLoginToken();
  if (loginR.success && loginR.data && loginR.data.length > 0) {
    log.debug({
      length: loginR.data.length,
      prefix: loginR.data.slice(0, 8),
    }, "getAuthToken: using LOGIN token");
    return loginR.data;
  }
  log.debug({
    success: loginR.success,
    hasData: loginR.success ? !!loginR.data : false,
  }, "getAuthToken: no login token");

  const guestR = await storage.getGuestToken();
  if (guestR.success && guestR.data && guestR.data.length > 0) {
    log.debug(
      {
        length: guestR.data.length,
        prefix: guestR.data.slice(0, 8),
      },
      "getAuthToken: using GUEST token (login priority, no login available)",
    );
    return guestR.data;
  }
  log.warn({
    loginAttempted: true,
    guestAttempted: true,
    loginSuccess: loginR.success,
    guestSuccess: guestR.success,
  }, "getAuthToken: NO token available (will skip Authorization)");
  return null;
}

export const onRequestToken: FetchHook = async (ctx) => {
  const path = getRequestPath(ctx.request);
  if (!needsToken(path)) {
    log.debug({ path }, "onRequestToken SKIP (no-token path)");
    return;
  }

  const token = await getAuthToken();
  if (token) {
    // ofetch 推荐：改 ctx.options.headers（不依赖 ctx.request 是 Request 实例 —— 实例类型不稳定）
    const headers = new Headers(ctx.options.headers);
    headers.set("Authorization", `Bearer ${token}`);
    ctx.options.headers = headers;
    log.debug({
      path,
      length: token.length,
      prefix: token.slice(0, 8),
    }, "onRequestToken SET Authorization header (via ctx.options.headers)");
  } else {
    log.warn({ path }, "onRequestToken NO token to set");
  }
};

/**
 * 兼容旧接口的 FetchHooks 形式
 */
export const tokenInterceptor = {
  onRequest: onRequestToken,
};
