import {useRuntimeConfig} from '#app'
import {ofetch} from 'ofetch'
import {message} from '@/components/x-message/useMessage.js'
import {authStore} from "@/stores/auth/index.js"

let httpStatusErrorHandler
let http

// HTTP 状态码映射
const HTTP_STATUS_MAP = {
  400: '请求参数错误',
  401: '未授权或登录过期',
  403: '访问被禁止',
  404: '请求的资源不存在',
  500: '服务器内部错误',
  502: '网关错误',
  503: '服务暂时不可用',
  504: '网关超时'
}

export function setupHttp() {
  if (http) return http

  const config = useRuntimeConfig()
  const baseURL = config.public.NUXT_PUBLIC_API_BASE
  const { token } = authStore()
  const router = useRouter()

  const defaultOptions = {
    baseURL,
    headers: { 'Content-Type': 'application/json' },
    timeout: 15000, // 15秒超时
    retry: 3,
    retryDelay: 1000,
  }

  http = ofetch.create({
    ...defaultOptions,

    // 请求拦截
    async onRequest({ options, request }) {
      // 添加 token
      options.headers = {
        ...options.headers,
        Authorization: token.value
      }

      // GET 请求添加时间戳防止缓存
      if (request.toLowerCase().includes('get')) {
        options.params = {
          ...options.params,
          _t: Date.now()
        }
      }
    },

    // 响应拦截
    async onResponse({ response }) {
      const data = response._data

      // 处理业务错误
      if (data.status === 1) {
        message.error(data.msg || '操作失败')
      }

      // 处理登录失效
      if (data.status === 401) {
        message.error('登录已过期,请重新登录')
        token.value = '' // 清除 token
        router.replace('/login')
      }

      return response
    },

    // 响应错误处理
    async onResponseError({ response, request }) {
      // 网络错误
      if (!response) {
        message.error('网络连接失败,请检查网络设置')
        return Promise.reject(new Error('网络错误'))
      }
      const status = response.status
      const data = response._data

      // 处理 HTTP 状态错误
      const errorMessage = data.msg || HTTP_STATUS_MAP[status] || '请求失败'

      if (Array.isArray(data.msg)) {
        data.msg.forEach(item => {
          httpStatusErrorHandler?.(item, status)
        })
      } else {
        httpStatusErrorHandler?.(errorMessage, status)
      }

      message.error(errorMessage)
      return Promise.reject(data)
    },
  })

  return http
}

export function createAbortController() {
  return new AbortController()
}

export function injectHttpStatusErrorHandler(handler) {
  httpStatusErrorHandler = handler
}

export function getHttp() {
  if (!http) {
    throw new Error('HTTP client not initialized. Call setupHttp first.')
  }
  return http
}

// 导出请求工具函数
export async function request({url,...options}) {
  const http = getHttp()
  try {
    return await http(url, {...options,body:options.data})
  } catch (error) {
    throw error
  }
}