import axios from 'axios'

const service = axios.create({
  baseURL: import.meta.env.VITE_API_URL || '', // 使用环境变量配置API地址
  timeout: 5000
})

// --- Token 管理 ---
const ACCESS_TOKEN_KEY = 'token'
const REFRESH_TOKEN_KEY = 'refresh_token'
const EXPIRES_AT_KEY = 'token_expires_at' // ms 时间戳
const EXPIRY_BUFFER_MS = 60 * 1000 // 提前 60s 刷新

function getStoredTokens(){
  return {
    accessToken: localStorage.getItem(ACCESS_TOKEN_KEY) || '',
    refreshToken: localStorage.getItem(REFRESH_TOKEN_KEY) || '',
    expiresAt: Number(localStorage.getItem(EXPIRES_AT_KEY) || 0)
  }
}

function storeTokens({ accessToken, refreshToken, expiresIn }){
  if (accessToken) localStorage.setItem(ACCESS_TOKEN_KEY, accessToken)
  if (refreshToken) localStorage.setItem(REFRESH_TOKEN_KEY, refreshToken)
  if (typeof expiresIn === 'number') {
    const expiresAt = Date.now() + Math.max(0, expiresIn * 1000 - EXPIRY_BUFFER_MS)
    localStorage.setItem(EXPIRES_AT_KEY, String(expiresAt))
  }
}

function isAccessTokenExpiredSoon(){
  const { expiresAt } = getStoredTokens()
  if (!expiresAt) return false
  return Date.now() >= expiresAt
}

let isRefreshing = false
let refreshPromise = null
let requestQueue = []

async function refreshAccessToken(){
  const { refreshToken } = getStoredTokens()
  if (!refreshToken) throw new Error('No refresh token')

  // 使用裸 axios 避免拦截器递归
  const resp = await axios.post(
    `${import.meta.env.VITE_API_URL || ''}/common/auth/refresh/token`,
    { refresh_token: refreshToken },
    {
      headers: {
        'Fdesk-Language': 'zh',
        'Fdesk-System-Code': 'board',
        'Fdesk-Login-Type': 'upwd'
      }
    }
  )
  const data = resp.data?.data || resp.data || {}
  const accessToken = data.access_token || data.accessToken
  const newRefreshToken = data.refresh_token || refreshToken
  const expiresIn = Number(data.expires_in || data.expiresIn || 0)
  if (!accessToken) throw new Error('Refresh failed: no accessToken')
  storeTokens({ accessToken, refreshToken: newRefreshToken, expiresIn })
  return accessToken
}

// 请求拦截：附加通用头，并在过期时刷新 Token
service.interceptors.request.use(async (cfg) => {
  // 通用 Header
  cfg.headers['Fdesk-Language'] = 'zh'
  cfg.headers['Fdesk-System-Code'] = 'board'
  cfg.headers['Fdesk-Login-Type'] = 'upwd'

  // 刷新逻辑
  if (isAccessTokenExpiredSoon()) {
    if (!isRefreshing) {
      isRefreshing = true
      refreshPromise = refreshAccessToken().finally(() => { isRefreshing = false })
    }
    try {
      await refreshPromise
      // 唤醒队列
      requestQueue.forEach(res => res())
      requestQueue = []
    } catch (e) {
      requestQueue = []
      throw e
    }
  } else if (isRefreshing) {
    // 等待当前刷新完成
    await new Promise((resolve) => requestQueue.push(resolve))
  }

  const { accessToken } = getStoredTokens()
  if (accessToken) cfg.headers['Fdesk-Auth-Token'] = `Bearer ${accessToken}`
  return cfg
}, err => Promise.reject(err))

// 响应拦截：直出 data；401 时尝试一次刷新后重试
service.interceptors.response.use(
  (res) => res.data,
  async (error) => {
    const original = error?.config
    const status = error?.response?.status
    if (status === 401 && !original?._retried) {
      try {
        if (!isRefreshing) {
          isRefreshing = true
          refreshPromise = refreshAccessToken().finally(() => { isRefreshing = false })
        }
        await refreshPromise
        original._retried = true
        const { accessToken } = getStoredTokens()
        if (accessToken) original.headers['Fdesk-Auth-Token'] = `Bearer ${accessToken}`
        return service(original)
      } catch (e) {
        // 刷新失败，清理本地存储并重定向到登录页
        localStorage.removeItem(ACCESS_TOKEN_KEY)
        localStorage.removeItem(REFRESH_TOKEN_KEY)
        localStorage.removeItem(EXPIRES_AT_KEY)
        
        // 如果是在浏览器环境中，重定向到登录页
        if (typeof window !== 'undefined') {
          window.location.href = '/login'
        }
      }
    }
    return Promise.reject(error)
  }
)

export default service
