import Taro from "@tarojs/taro";

interface Method {
  /** HTTP 请求 OPTIONS */
  OPTIONS
  /** HTTP 请求 GET */
  GET
  /** HTTP 请求 HEAD */
  HEAD
  /** HTTP 请求 POST */
  POST
  /** HTTP 请求 PUT */
  PUT
  /** HTTP 请求 PATCH */
  PATCH
  /** HTTP 请求 DELETE */
  DELETE
  /** HTTP 请求 TRACE */
  TRACE
  /** HTTP 请求 CONNECT */
  CONNECT
}


/** 请求不成功各种状态的错误 */
export const ERROR_STATUS: Record<number | string, string> = {
  '400': '400: 语法错误~',
  '401': '401: 未授权~',
  '403': '403: 拒绝访问~',
  '404': '404: 资源不存在~',
  '405': '405: 未允许~',
  '429': '请求过于频繁',
  '408': '408: 请求超时~',
  '500': '500: 服务器错误',
  '501': '501: 无请求功能~',
  '502': '502: 错误网关~',
  '503': '503: 服务不可用~',
  '504': '504: 网关超时~',
  '505': '505: http版本错误~',
  'DEFAULT': '请求错误~',
  'request:fail timeout': '请求超时~',
  'NETWORK_ERROR': '网络不可用~',
  'INVALID_DATA': '服务器响应异常~',
  'OVERSTEP': '请求越界~'
}

let notLoging = false

export function request<T = unknown>(
  url: string,
  method: keyof Method,
  data?: Record<string, any>
): Promise<T> {
  const option: Taro.request.Option<T> = {
    url: process.env.TARO_APP_API + url,
    method: method,
    dataType: 'json',
    timeout: 30000,
    header: {
      'Content-Type': 'application/json;charset=UTF-8',
    }
  }

  const token = JSON.parse(Taro.getStorageSync('profile') || '{}')?.token
  if (token) {
    option.header ??= {}
    option.header['Authorization'] = `Bearer ${token}`
  }
  if (method === 'GET' && data) {
    let parameter = ''
    Object.entries(data).forEach(([key, value], index) => {
      if (parameter.indexOf(key) !== -1) {
        parameter += (index === 0 ? '?' : '&') + key + '=' + JSON.stringify(value)
      }
    })
    option.url += parameter
  }
  data && (option.data = data)
  return new Promise<T>((resolve, reject) => {
    Taro.request<T>({
      ...option,
      success(res) {
        try {
          const data = res?.data as any
          if (data?.code === 0 && res?.statusCode === 200) {
            resolve(data?.data)
            notLoging = false
          } else if (res.statusCode === 401) {
            if (notLoging || !token) return
            notLoging = true
            Taro.showModal({
              title: "登录过期",
              confirmText: "登录",
              showCancel: false,
              success() {
                Taro.clearStorage()
                Taro.navigateTo({url: '/pages/login/login'})
              }
            })
          } else {
            reject(null)
            Taro.showToast({
              title: data?.msg || data?.message || ERROR_STATUS[res.statusCode] || '请求错误~',
              icon: 'error'
            })
          }
        } catch (e) {
          reject(null)
        }
      },
      fail(err) {
        const errMsg = err?.errMsg
        Taro.showToast({title: ERROR_STATUS[errMsg] || ERROR_STATUS['DEFAULT'], icon: 'error'})
        reject(null)
      }
    })
  })
}
