import axios from 'axios'
import { goLogin } from '../utils/navigate'
import {
  authStorageKeys,
  clearAuthSession,
  markActivity,
  refreshAuthSession,
  refreshIfNeeded,
} from '../auth/session'

const http = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL ?? '/api',
  timeout: 15000,
})

http.interceptors.request.use(async (config) => {
  const isAuthenticationRequest =
    config.url?.endsWith('/auth/login') ||
    config.url?.endsWith('/auth/refresh') ||
    config.url?.endsWith('/auth/logout') ||
    config.url?.endsWith('/auth/sso/exchange') ||
    config.url?.endsWith('/auth/sso/bind')
  if (!isAuthenticationRequest) {
    const activeToken = await refreshIfNeeded(true)
    if (activeToken) markActivity()
  }
  const token = localStorage.getItem(authStorageKeys.token)
  if (token) config.headers.Authorization = `Bearer ${token}`
  return config
})

http.interceptors.response.use(
  (response) => response,
  async (error) => {
    const isAuthenticationRequest =
      error.config?.url?.endsWith('/auth/login') ||
      error.config?.url?.endsWith('/auth/refresh') ||
      error.config?.url?.endsWith('/auth/logout') ||
      error.config?.url?.endsWith('/auth/sso/exchange') ||
      error.config?.url?.endsWith('/auth/sso/bind')
    const retryableConfig = error.config as
      (typeof error.config & { _jiaowuRetried?: boolean }) | undefined
    if (error.response?.status === 401 && !isAuthenticationRequest &&
      !retryableConfig?._jiaowuRetried) {
      const token = await refreshAuthSession()
      if (token && retryableConfig) {
        retryableConfig._jiaowuRetried = true
        retryableConfig.headers.Authorization = `Bearer ${token}`
        return http.request(retryableConfig)
      }
    }
    if (error.response?.status === 401 && !isAuthenticationRequest) {
      clearAuthSession()
      goLogin(location.pathname + location.search + location.hash)
    }
    return Promise.reject(error)
  },
)

export function apiErrorMessage(error: unknown) {
  if (!axios.isAxiosError(error)) return '操作失败，请稍后重试。'
  const status = error.response?.status
  const data = error.response?.data
  if (data?.errors && typeof data.errors === 'object') {
    const validationMessage = Object.values(data.errors)
      .flat()
      .map((item) => String(item).trim())
      .filter(Boolean)
      .join('；')
    if (validationMessage) return validationMessage
  }
  const detail = typeof data?.detail === 'string' ? data.detail.trim() : ''
  if (detail) return detail
  const title = typeof data?.title === 'string' ? data.title.trim() : ''
  if (title) return title
  if (status === 403) return '您没有权限执行此操作，请联系管理员。'
  if (status === 404) return '请求的资源不存在。'
  if (status === 401) return '登录已过期，请重新登录。'
  if (status && status >= 500) return '服务器繁忙，请稍后重试。'
  return '操作失败，请检查网络连接。'
}

export default http
