import { $fetch } from 'ofetch'
import { ElMessage } from 'element-plus'
import cache from '@/utils/cache'
import settings from '~/settings'
import { useUserStore } from '@/stores/user'

// 定义请求选项类型
export interface CustomRequestOptions {
  withToken?: boolean
  isParamsToData?: boolean
  urlPrefix?: string
  isTransformResponse?: boolean
  isReturnDefaultResponse?: boolean
  showErrorMessage?: boolean
  timeout?: number
  retry?: number
  headers?: Record<string, string>
}

// 默认配置
const DEFAULT_CONFIG: Required<CustomRequestOptions> = {
  withToken: true,
  isParamsToData: true,
  urlPrefix: '',
  isTransformResponse: true,
  isReturnDefaultResponse: false,
  showErrorMessage: true,
  timeout: 30000,
  retry: 2,
  headers: {
    'Content-Type': 'application/json;charset=UTF-8'
  }
}

// 定义导出方法的选项类型
export interface FetchMethodOptions {
  params?: Record<string, any>
  headers?: Record<string, string>
  body?: any
  requestOptions?: CustomRequestOptions
}

// 定义请求配置类型
type RequestConfig = {
  method: string
  params?: Record<string, any>
  headers?: Record<string, string>
  body?: any
  requestOptions?: CustomRequestOptions
  [key: string]: any
}

// 处理接口前缀
function handleUrlPrefix(url: string, urlPrefix?: string): string {
  const prefix = urlPrefix || settings.urlPrefix || ''
  if (prefix && !url.startsWith('http') && !url.startsWith(prefix)) {
    return `${prefix}${url}`
  }
  return url
}

// 创建请求类
class Request {
  private fetchInstance: ReturnType<typeof $fetch.create> | null = null

  createInstance(options?: { timeout?: number; retry?: number; headers?: Record<string, string> }) {
    if (!this.fetchInstance) {
      const runtimeConfig = useRuntimeConfig()
      this.fetchInstance = $fetch.create({
        // 基础接口地址
        baseURL: runtimeConfig.public.VITE_API_BASE_URL,
        // 接口超时时间
        timeout: options?.timeout || 30000,
        // 重试次数
        retry: options?.retry || 2,
        // 请求头
        headers: {
          'Content-Type': 'application/json;charset=UTF-8',
          ...options?.headers
        },
        // 请求拦截器
        onRequest({ request, options }) {
          const requestOptions = options as typeof options & {
            requestOptions?: CustomRequestOptions
            params?: Record<string, any>
            body?: any
            headers?: Record<string, string>
            method?: string
          }
          const mergedOptions: Required<CustomRequestOptions> = {
            ...DEFAULT_CONFIG,
            ...requestOptions.requestOptions
          }
          const { withToken, isParamsToData } = mergedOptions
          const params = requestOptions.params || {}
          const headers = {
            ...DEFAULT_CONFIG.headers,
            ...requestOptions.headers
          }
          if (withToken) {
            const token = cache.get('token')
            if (token && typeof headers === 'object') {
              headers.token = String(token)
            }
          }
          if (requestOptions.params) {
            for (const [key, value] of Object.entries(requestOptions.params)) {
              if (value === undefined || value === null) {
                delete requestOptions.params[key]
              }
            }
          }
          if (isParamsToData && !Reflect.has(requestOptions, 'body') && requestOptions.method?.toUpperCase() === 'POST') {
            requestOptions.body = params
            requestOptions.params = {}
          }
          requestOptions.headers = headers
        },
        // 响应拦截器
        onResponse({ response, options }) {
          const requestOptions = options as typeof options & {
            requestOptions?: CustomRequestOptions
          }
          const mergedOptions: Required<CustomRequestOptions> = {
            ...DEFAULT_CONFIG,
            ...requestOptions.requestOptions
          }
          const { isTransformResponse, isReturnDefaultResponse, showErrorMessage } = mergedOptions
          if (isReturnDefaultResponse) {
            return response
          }
          if (!isTransformResponse) {
            return response
          }
          const responseData = response._data
          if (responseData && typeof responseData === 'object') {
            const { code, data, msg } = responseData
            switch (code) {
              case 1:
                response._data = data
                break
              case 0:
                if (showErrorMessage) {
                  ElMessage.error(msg || '请求失败')
                }
                const error = new Error(msg || '请求失败')
                  ; (error as any).data = data
                return Promise.reject(error)
              default:
                response._data = data
                break
            }
          }
          return response as any
        },
        // 响应错误拦截器
        onResponseError({ error }) {
          if (error && error.name !== 'AbortError') {
            const status = (error as any).response?.status
            const message = (error as any).message || '网络错误'
            if (status === 401) {
              ElMessage.error('未授权，请重新登录')
              setTimeout(() => {
                const userStore = useUserStore()
                userStore.logout()
              }, 500)
            } else if (status >= 500) {
              ElMessage.error('服务器错误，请稍后重试')
            } else if (status >= 400) {
              ElMessage.error('请求错误：' + message)
            } else {
              ElMessage.error(message)
            }

            const nuxtError = useError()
            if (nuxtError) {
              nuxtError.value = createError({
                statusCode: status || 500,
                message: message
              })
            }
          }
          return Promise.reject(error)
        }
      })
    }
    return this.fetchInstance
  }

  // 创建通用请求方法
  createRequestMethod(method: string) {
    return (url: string, options?: FetchMethodOptions) => {
      const requestConfig: RequestConfig = {
        method,
        ...options
      }
      const fullUrl = handleUrlPrefix(url, requestConfig.requestOptions?.urlPrefix)
      const instance = this.createInstance({
        timeout: requestConfig.requestOptions?.timeout,
        retry: requestConfig.requestOptions?.retry,
        headers: requestConfig.requestOptions?.headers
      })
      return instance(fullUrl, requestConfig)
    }
  }
}

// 创建请求实例
const request = new Request()

export function useRequest() {
  return {
    get: request.createRequestMethod('GET'),
    post: request.createRequestMethod('POST'),
    put: request.createRequestMethod('PUT'),
    delete: request.createRequestMethod('DELETE'),
    patch: request.createRequestMethod('PATCH'),
  }
}

export default {
  get: request.createRequestMethod('GET'),
  post: request.createRequestMethod('POST'),
  put: request.createRequestMethod('PUT'),
  delete: request.createRequestMethod('DELETE'),
  patch: request.createRequestMethod('PATCH'),
}
