import axios from 'axios'
import { router } from '../router'
import { useGlobalLoading } from '../composables/useGlobalLoading'

const { increment, decrement } = useGlobalLoading()

export const api = axios.create({
  baseURL: import.meta.env.VITE_API_BASE || '/api/v1',
  timeout: 15000,
})

// 内存级 access token（不写入任何持久存储）
let _accessToken = ''

export function setAccessToken(token: string) { _accessToken = token }
export function clearAccessToken() { _accessToken = '' }
export function getAccessToken(): string { return _accessToken }

function getCookie(name: string): string | null {
  const match = document.cookie.match(new RegExp(`(?:^|; )${name}=([^;]*)`))
  if (!match || match[1] === undefined) return null
  return decodeURIComponent(match[1])
}

// 请求拦截器：注入 JWT + CSRF Token + 计数在途请求
api.interceptors.request.use((config) => {
  increment()
  if (_accessToken) {
    config.headers.Authorization = `Bearer ${_accessToken}`
  }
  // CSRF double-submit: 对 state-changing 请求注入 csrf_token
  if (config.method && !['GET', 'HEAD', 'OPTIONS'].includes(config.method.toUpperCase())) {
    const csrfToken = getCookie('csrf_token')
    if (csrfToken) {
      config.headers['X-CSRF-Token'] = csrfToken
    }
  }
  return config
})

// ── Refresh mutex ──
// 防止并发 401 导致多条 refresh 请求竞争：同一时间只有一条 refresh 请求，
// 其余 401 排队等待其完成后再重试。
let _refreshing: Promise<boolean> | null = null

// 响应拦截器：自动刷新 token + 全局错误处理 + 递减在途请求
api.interceptors.response.use(
  (res) => { decrement(); return res },
  async (error) => {
    decrement()
    const originalRequest = error.config
    if (error.response?.status === 401 && !originalRequest._retry) {
      originalRequest._retry = true

      // refresh_token 由浏览器自动携带（HttpOnly cookie）
      // 已有 refresh 请求在进行中，等待其完成
      if (_refreshing) {
        const ok = await _refreshing
        if (ok) {
          originalRequest.headers.Authorization = `Bearer ${getAccessToken()}`
          return api(originalRequest)
        }
        return Promise.reject(error)
      }

      // 发起 refresh 请求，cookie 自动携带
      _refreshing = axios
        .post('/api/v1/auth/refresh')
        .then((res) => {
          if (!res.data.access_token) {
            clearAccessToken()
            return false
          }
          setAccessToken(res.data.access_token)
          return true
        })
        .catch(() => {
          clearAccessToken()
          if (router.currentRoute.value.meta?.requiresAuth) {
            router.push('/auth/login')
          }
          return false
        })
        .finally(() => {
          _refreshing = null
        })

      const ok = await _refreshing
      if (ok) {
        originalRequest.headers.Authorization = `Bearer ${getAccessToken()}`
        return api(originalRequest)
      }
    }
    return Promise.reject(error)
  },
)
