import axios from "axios";
import { ElMessage } from "element-plus";
import { pinia } from "../stores";
import { useAuthStore } from "../stores/auth";
import { resolveLoginPath } from "../utils/authNavigation";

const http = axios.create({
  baseURL: "/api",
  timeout: 30000,
});

const FORCE_LOGOUT_CODES = new Set([11001, 11003, 11004, 11005, 11006, 11007]);
let refreshPromise: Promise<string> | null = null;
let pendingForceLogout = false;
const getAuthStore = () => useAuthStore(pinia);

const isAuthSessionEndpoint = (url: string): boolean => {
  return /\/auth\/(login|platform-login|refresh|logout|logout-all)/.test(url);
};

const resolveLoginPathByScope = (): string => {
  const authStore = getAuthStore();
  return resolveLoginPath(authStore.scope, authStore.tenantCode);
};

const getForceLogoutMessage = (code: number): string => {
  if (code === 11003) {
    return "会话失效，请重新登录";
  }
  if (code === 11004) {
    return "账号有效期异常，请重新登录";
  }
  if (code === 11005 || code === 11006 || code === 11007) {
    return "登录状态异常，请重新登录";
  }
  return "登录状态已失效，请重新登录";
};

const forceLogoutAndRedirect = (message?: string) => {
  if (pendingForceLogout) {
    return;
  }
  pendingForceLogout = true;
  const nextLoginPath = resolveLoginPathByScope();
  if (message) {
    ElMessage.error(message);
  }
  // Delay cleanup/redirect so business catch can receive response details first.
  window.setTimeout(() => {
    getAuthStore().clearAuthStorage();
    window.location.href = nextLoginPath;
  }, 600);
};

const ensureRefreshedToken = async (): Promise<string> => {
  if (refreshPromise) {
    return refreshPromise;
  }
  refreshPromise = axios.post("/api/auth/refresh", null, { timeout: 10000 })
    .then((resp) => {
      const payload = resp?.data?.data || {};
      const token = String(payload?.token || "").trim();
      if (!token) {
        throw new Error("refresh token missing");
      }
      getAuthStore().saveAuthPayload(payload);
      return token;
    })
    .finally(() => {
      refreshPromise = null;
    });
  return refreshPromise;
};

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

http.interceptors.response.use((resp) => resp.data, (error) => {
  const requestUrl = String(error?.config?.url || "");
  const businessCode = Number(error?.response?.data?.code || 0);
  const isAuthRequest = isAuthSessionEndpoint(requestUrl);
  const originalRequest = error?.config as any;
  if (!isAuthRequest && businessCode === 11002 && !originalRequest?._retry) {
    originalRequest._retry = true;
    return ensureRefreshedToken()
      .then((token) => {
        originalRequest.headers = originalRequest.headers || {};
        originalRequest.headers.Authorization = `Bearer ${token}`;
        return http.request(originalRequest);
      })
      .catch((refreshError) => {
        forceLogoutAndRedirect("会话已过期，请重新登录");
        return Promise.reject(refreshError);
      });
  }
  if (
    !isAuthRequest &&
    FORCE_LOGOUT_CODES.has(businessCode)
  ) {
    const backendMessage = error?.response?.data?.message || error?.response?.data?.msg || error?.response?.data?.error;
    const fallbackMessage = backendMessage || getForceLogoutMessage(businessCode);
    if (!error?.response) {
      error.response = {
        status: 422,
        data: {
          code: businessCode || 11003,
          message: fallbackMessage,
        },
      };
    } else if (!error.response.data) {
      error.response.data = {
        code: businessCode || 11003,
        message: fallbackMessage,
      };
    }
    forceLogoutAndRedirect(fallbackMessage);
    return Promise.reject(error);
  }
  const backendMessage = error?.response?.data?.message || error?.response?.data?.msg || error?.response?.data?.error;
  let errorMessage = backendMessage;
  if (!errorMessage) {
    if (error?.code === "ECONNABORTED") {
      errorMessage = "请求超时，请稍后重试";
    } else if (error?.message === "Network Error") {
      errorMessage = "网络异常，请检查网络连接";
    } else if (error?.response?.status) {
      errorMessage = `请求失败（${error.response.status}）`;
    } else {
      errorMessage = "请求失败，请稍后重试";
    }
  }
  // 从响应头或响应体中解析 requestId，附加到错误提示
  const requestId = error?.response?.headers?.["x-request-id"]
    || error?.response?.data?.requestId
    || "";
  if (requestId) {
    errorMessage = `${errorMessage}（RequestId: ${requestId}）`;
  }
  ElMessage.error(errorMessage);
  return Promise.reject(error);
});

export default http;
