import axios, { AxiosError, type AxiosInstance, type InternalAxiosRequestConfig } from 'axios'

const baseURL = (import.meta.env.VITE_API_BASE as string | undefined) ?? '/api'

// AR-5 (会话 45)：withCredentials=true 让后端下发的 httpOnly Cookie (simple.auth.token)
// 自动随请求带回。Platform.Server `/api/auth/login` 同时下发 Cookie 和返回 token 字段，
// 过渡期内 Authorization: Bearer header 仍然兼容（旧浏览器 / 跨进程脚本）。
const http: AxiosInstance = axios.create({
  baseURL,
  timeout: 15000,
  headers: { 'Content-Type': 'application/json' },
  withCredentials: true
})

http.interceptors.request.use((config: InternalAxiosRequestConfig) => {
  // 双轨：优先用 localStorage 里的 token（过渡期 fallback），Cookie 会自动带；
  // 后端首先看 Authorization: Bearer，没有再看 Cookie，两路任一通过即可。
  const token = localStorage.getItem('simple.auth.token')
  if (token) {
    config.headers.set('Authorization', `Bearer ${token}`)
  }
  const scope = localStorage.getItem('simple.auth.scope')
  if (scope) {
    config.headers.set('X-Scope', scope)
  }
  return config
})

/**
 * 把 axios 异常翻译成更友好的中文文案，特别是 SimpleLite 链路：
 *
 *   /api/sl/projection/**  →  Platform.Server YARP → SimpleLite EmbedIO :8222
 *
 * 如果 SimpleLite 没启动 / 端口未监听，YARP 一定回 502；超时一般是 504。把这两种
 * 情况单独识别，写成「SimpleLite 未连接，请先启动 SimpleLite (端口 8222)」之类，
 * 比直接抛 `Request failed with status code 502` 友好得多，也避免用户怀疑前端 bug。
 */
function describeError(err: AxiosError): string {
  const status = err.response?.status
  const url = err.config?.url ?? ''
  const isSimpleLite = url.startsWith('/sl/') || url.startsWith('sl/')
  if (status === 502 || status === 504 || err.code === 'ECONNABORTED' || err.code === 'ERR_NETWORK') {
    if (isSimpleLite) {
      return 'SimpleLite 未连接：请先启动 SimpleLite 后端（监听端口 8222）后重试。'
    }
    return `网关无法连接到下游服务（${status ?? err.code ?? 'network'}）。`
  }
  // 后端 envelope 模式：{ success: false, message: 'xxx' }
  const data = err.response?.data as { message?: string } | undefined
  if (data?.message) return data.message
  return err.message
}

http.interceptors.response.use(
  (resp) => resp,
  (err: AxiosError) => {
    if (err.response?.status === 401) {
      // 会话 45 HC-1：401 全量清 state，避免老 user/scope/perm 残留导致 UI 误判。
      try {
        localStorage.removeItem('simple.auth.token')
        localStorage.removeItem('simple.auth.user')
        localStorage.removeItem('simple.auth.scope')
        localStorage.removeItem('simple.auth.runMode')
        localStorage.removeItem('simple.auth.perm')
      } catch { /* 某些隐私模式 / iframe 沙箱可能禁用 localStorage */ }
      if (location.pathname !== '/login') location.assign('/login')
    }
    // 用 Object.defineProperty 覆盖 message，避免后续 `(err as Error).message` 还是看到原文。
    const friendly = describeError(err)
    try { Object.defineProperty(err, 'message', { value: friendly, configurable: true }) } catch { /* ignore */ }
    return Promise.reject(err)
  }
)

export default http
