import axios from "axios"

const client = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL || "/api",
  timeout: 10000,
  headers: { "Content-Type": "application/json" },
})

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

let isRefreshing = false
let failedQueue: Array<{
  resolve: (token: string) => void
  reject: (error: unknown) => void
}> = []

const processQueue = (error: unknown, token: string | null = null) => {
  failedQueue.forEach((prom) => {
    if (error) {
      prom.reject(error)
    } else {
      prom.resolve(token!)
    }
  })
  failedQueue = []
}

const AUTH_PUBLIC_PATHS = ["/v1/auth/login", "/v1/auth/register", "/v1/auth/refresh"]

function isCommercialCode(code: unknown): boolean {
  return typeof code === "number" && code >= 6100 && code < 6200
}

export function isCommercialError(error: unknown): boolean {
  const code = (error as { response?: { data?: { code?: unknown } } })?.response?.data?.code
  return isCommercialCode(code)
}

client.interceptors.response.use(
  (response) => response,
  async (error) => {
    const originalRequest = error.config
    const url: string = originalRequest?.url || ""
    const isAuthPublic = AUTH_PUBLIC_PATHS.some((p) => url.includes(p))

    const businessCode = error.response?.data?.code
    if (isCommercialCode(businessCode)) {
      const { toast } = await import("../utils/toast")
      toast.error(error.response?.data?.message || "该站点暂不支持此功能")
      return Promise.reject(error)
    }

    // 登录/注册/refresh 自身的 401 是业务层错误（如密码错误），不要走刷新+跳转
    if (error.response?.status === 401 && !originalRequest._retry && !isAuthPublic) {
      if (isRefreshing) {
        return new Promise((resolve, reject) => {
          failedQueue.push({ resolve, reject })
        }).then((token) => {
          originalRequest.headers.Authorization = `Bearer ${token}`
          return client(originalRequest)
        })
      }

      originalRequest._retry = true
      isRefreshing = true

      try {
        const refreshToken = localStorage.getItem("refresh_token")
        if (!refreshToken) throw new Error("No refresh token")

        const { data } = await axios.post("/api/v1/auth/refresh", {
          refresh_token: refreshToken,
        })

        const newAccessToken = data.data.access_token
        const newRefreshToken = data.data.refresh_token

        localStorage.setItem("access_token", newAccessToken)
        localStorage.setItem("refresh_token", newRefreshToken)

        processQueue(null, newAccessToken)

        originalRequest.headers.Authorization = `Bearer ${newAccessToken}`
        return client(originalRequest)
      } catch (refreshError) {
        processQueue(refreshError, null)
        localStorage.removeItem("access_token")
        localStorage.removeItem("refresh_token")
        // 用事件通知 AuthContext 走 SPA 路由跳转，避免 window.location 刷页
        window.dispatchEvent(new CustomEvent("auth:unauthorized"))
        return Promise.reject(refreshError)
      } finally {
        isRefreshing = false
      }
    }

    return Promise.reject(error)
  }
)

export default client
