/** @format */

// MyRequest.ts
import { ElMessage } from 'element-plus'
import { useFetch, useRequestHeaders, useRuntimeConfig } from '#app'
import { ResultEnum } from '@/enums/httpEnum'
import { useUserStore } from '@/stores/modules/user'

type UrlType =
  | string
  | Request
  | Ref<string | Request>
  | (() => string | Request)
export interface RequestOptions {
  method?: any
  params?: any
  headers?: any
  server?: boolean
  [key: string]: any
}

export function useMyRequest() {
  const request = async (
    url: UrlType,
    params: any,
    opt: RequestOptions = {},
  ) => {
    const headers = useRequestHeaders(['cookie'])
    const { apiBase: baseURL } = useRuntimeConfig().public
    let { method = (opt?.method || 'GET') as string } = opt
    method = method.toUpperCase()

    // 处理请求体
    let requestBody: any
    if (method === 'POST') {
      // 如果参数是 FormData 类型(文件上传),直接使用,不要 JSON.stringify
      if (params instanceof FormData) {
        requestBody = params
        // 删除 Content-Type header,让浏览器自动设置正确的 boundary
        delete headers['Content-Type']
      }
      else {
        requestBody = JSON.stringify(params)
        headers['Content-Type'] = 'application/json'
      }
    }
    const isProduction = process.env.NODE_ENV === 'production'

    // eslint-disable-next-line no-async-promise-executor
    return new Promise(async (resolve, reject) => {
      await useFetch(url as string, {
        default: () => [],
        baseURL,
        method,
        params: { ...params },
        headers,
        server: opt.server || false,
        credentials: 'include',
        body: requestBody,
        onRequest: ({ request, options }) => {
          // console.log('onResponseError--------aaaa:', options)
          const userStore = useUserStore()
          const { token } = storeToRefs(userStore)
          if (token.value) {
            options.headers = {
              ...opt.headers,
              'Authorization': token.value,
              'X-Access-Token': token.value,
            }
          }
        },
        onRequestError: ({ request, options, error }) => {
          ElMessage.closeAll()
          error
          && ElMessage({
            message: 'Sorry, The Data Request Failed',
            type: 'error',
            plain: true,
          })
        },
        // 响应成功+异常处理
        onResponse: ({ request, response, options }) => {
          // console.log('onResponseError--------1:', request, response, options, opt)
          const data = response._data
          const { code, result, message } = data
          const hasSuccess
              = data && Reflect.has(data, 'code') && code === ResultEnum.SUCCESS
          if (hasSuccess)
            return resolve(result)
          let msg = ''
          switch (code) {
            case ResultEnum.TIMEOUT:
              msg = 'Login timeout, please login again.'
              // 超时,自动推出
              useUserStore().logout()
              break
            default:
              if (message)
                msg = message
          }
          msg && !opt.isErrorPrompt
          && ElMessage({
            message: msg,
            type: 'error',
            plain: true,
          })
          return reject(response._data)
        },
        // 服务错误响应处理
        onResponseError: (error: any) => {
          const { response, code, message } = error || {}
          const msg: string = response?.data?.message ?? ''
          const err: string = error?.toString?.() ?? ''
          let errMessage = ''
          if (code === 'ECONNABORTED' && message.includes('timeout')) {
            errMessage
                = 'The interface request timed out. Please refresh the page and try again.'
          }
          if (err?.includes('Network Error')) {
            errMessage
                = 'The network is abnormal. Please check whether your network connection is normal.'
          }
          const status = error?.response?.status
          switch (status) {
            case 400:
              errMessage = `${msg}`
              break
            // 401: Not logged in
            case 401:
              errMessage = msg || '用户没有权限'
              // 被动登出,带redirect地址
              useUserStore().logout()
              break
            case 403:
              errMessage = '用户得到授权,但是访问是被禁止的'
              break
            case 404:
              errMessage = '网络请求错误,未找到该资源'
              break
            case 405:
              errMessage = '网络请求错误,请求方法未允许'
              break
            case 408:
              errMessage = '网络请求超时'
              break
            case 500:
              errMessage = '服务器错误,请联系管理员'
              break
            case 501:
              errMessage = '网络未实现'
              break
            case 502:
              errMessage = '网络错误'
              break
            case 503:
              errMessage = '服务器不可用,服务器暂时过载或维护'
              break
            case 504:
              errMessage = '网络超时'
              break
            case 505:
              errMessage = 'http版本不支持该请求'
              break
            default:
          }
          if (errMessage) {
            ElMessage({
              message: errMessage,
              type: 'error',
              plain: true,
            })
          }
          return reject(error)
        },
      })
    })
  }

  return {
    get: (url: UrlType, params?: any, option?: RequestOptions) => {
      return request(url, params, { method: 'GET', ...option })
    },
    post: (url: UrlType, params?: any, option?: RequestOptions) => {
      return request(url, params, { method: 'POST', ...option })
    },
    put: (url: UrlType, params?: any, option?: RequestOptions) => {
      return request(url, params, { method: 'GET', ...option })
    },
    delete: (url: UrlType, params?: any, option?: RequestOptions) => {
      return request(url, params, { method: 'POST', ...option })
    },
  }
}