import axios, {
  type AxiosInstance,
  type AxiosRequestConfig,
  type AxiosResponse,
  type InternalAxiosRequestConfig
} from 'axios'
import { ElMessage } from 'element-plus'
import NProgress from 'nprogress'
import { useUserStore } from '@/stores/modules/user'

NProgress.configure({ showSpinner: false })

/**
 * 后端统一响应结构
 */
export interface ApiResponse<T = unknown> {
  code: number
  message: string
  data: T
}

/**
 * baseURL 处理：
 * - 开发/测试：VITE_API_BASE_URL 留空 → baseURL = '' → 请求走相对路径
 *   浏览器同源，Vite server.proxy 在 Node 端转发到后端
 * - 生产：VITE_API_BASE_URL 设为真实后端域名
 */
const baseURL = (import.meta.env.VITE_API_BASE_URL || '').replace(/\/+$/, '')

const service: AxiosInstance = axios.create({
  baseURL,
  timeout: 15000,
  withCredentials: false
})

// 请求拦截器
service.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    NProgress.start()
    const userStore = useUserStore()
    if (userStore.token) {
      config.headers.Authorization = `Bearer ${userStore.token}`
    }
    return config
  },
  (error) => {
    NProgress.done()
    return Promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  (response: AxiosResponse<ApiResponse>) => {
    NProgress.done()
    const { code, message, data } = response.data

    if (code === 200) {
      return data as any
    }

    // Token 过期 / 未登录
    if (code === 401) {
      const userStore = useUserStore()
      userStore.clearAuth()
      import('@/router').then(({ default: router }) => {
        router.push('/login')
      })
      return Promise.reject(new Error(message || '未登录或Token已过期'))
    }

    ElMessage.error(message || '请求失败')
    return Promise.reject(new Error(message || 'Error'))
  },
  (error) => {
    NProgress.done()
    const status = error.response?.status
    let message = error.message

    if (status === 401) {
      message = '登录已过期，请重新登录'
      const userStore = useUserStore()
      userStore.clearAuth()
      import('@/router').then(({ default: router }) => {
        router.push('/login')
      })
    } else if (status === 403) {
      message = '无权限访问'
    } else if (status === 404) {
      message = '资源不存在'
    } else if (status === 500) {
      message = '服务器内部错误'
    }

    ElMessage.error(message)
    return Promise.reject(error)
  }
)

/**
 * 统一请求方法封装
 */
export function request<T = unknown>(config: AxiosRequestConfig): Promise<T> {
  return service.request<unknown, T>(config) as unknown as Promise<T>
}

export default service
