import axios, { AxiosError, type InternalAxiosRequestConfig } from "axios";

const http = axios.create({ baseURL: "/api/admin", timeout: 20000 });
let refreshPromise: Promise<string> | null = null;

http.interceptors.request.use((config) => {
  const token = localStorage.getItem("admin_access_token");
  if (token) config.headers.Authorization = `Bearer ${token}`;
  return config;
});

http.interceptors.response.use(
  (response) => response,
  async (error: AxiosError) => {
    const request = error.config as (InternalAxiosRequestConfig & { _retried?: boolean }) | undefined;
    const canRefresh = !request?.url?.includes("/auth/");
    if (error.response?.status === 401 && request && !request._retried && canRefresh) {
      request._retried = true;
      try {
        const token = await refreshAccessToken();
        request.headers.Authorization = `Bearer ${token}`;
        return http(request);
      } catch {
        clearAuth();
        if (!location.pathname.endsWith("/login")) location.href = "/admin/login";
      }
    }
    return Promise.reject(error);
  },
);

async function refreshAccessToken() {
  if (!refreshPromise) {
    refreshPromise = axios
      .post("/api/admin/auth/refresh", { refresh_token: localStorage.getItem("admin_refresh_token") })
      .then(({ data }) => {
        saveTokens(data.data);
        return data.data.access_token as string;
      })
      .finally(() => {
        refreshPromise = null;
      });
  }
  return refreshPromise;
}

export function saveTokens(data: { access_token: string; refresh_token: string; admin?: unknown }) {
  localStorage.setItem("admin_access_token", data.access_token);
  localStorage.setItem("admin_refresh_token", data.refresh_token);
  if (data.admin) localStorage.setItem("admin_profile", JSON.stringify(data.admin));
}

export function clearAuth() {
  localStorage.removeItem("admin_access_token");
  localStorage.removeItem("admin_refresh_token");
  localStorage.removeItem("admin_profile");
}

export function apiError(error: unknown) {
  const axiosError = error as AxiosError<{ code?: string; message?: string; trace_id?: string }>;
  const body = axiosError.response?.data;
  const message = body?.message || axiosError.message || "请求失败";
  const copyText = `错误码：${body?.code || "request_failed"}\n错误描述：${message}\n请求追踪 ID：${body?.trace_id || axiosError.response?.headers?.["x-request-id"] || "无"}`;
  return { message, copyText };
}

export default http;
