import Taro, { useRouter } from '@tarojs/taro'
import { useEffect, useRef, useState } from 'react'
import qs from 'qs'
import useUserInfo from './useUserInfo'
import useLogin from './useLogin'
import useLoginRequest from './useLoginRequest'
import { BASE_URL, WX_APPID } from '@/common/constant'

interface Params {
  code: string | null
  success: boolean
  data: any
  msg: string
  loading: boolean | null
  error: any
  query: any
  filter: any
  sort: any
  total: number
  multiple: boolean // 请求多次
  count: number // 第几次请求
  token: string // token
  page?: number
  pageSize?: number
}
type OptionData = Record<string, any> | any[] | null
interface option {
  url?: string
  method?: 'get' | 'post' | 'put' | 'delete'
  type?: string
  data?: OptionData
  page?: number
  pageSize?: number
  pagination?: boolean
  base_url?: string
  apiMsgStatus?: boolean
}

/**
 * 返回状态信息，根据 http 状态错
 * @param {Number} status
 * @returns
 */
const showStatus = (status) => {
  let message = ''
  switch (status) {
    case 400:
      message = '请求错误(400)'
      break
    case 401:
      message = '未授权，请重新登录(401)'
      break
    case 403:
      message = '拒绝访问(403)'
      break
    case 404:
      message = '请求出错(404)'
      break
    case 408:
      message = '请求超时(408)'
      break
    case 500:
      message = '服务器错误(500)'
      break
    case 501:
      message = '服务未实现(501)'
      break
    case 502:
      message = '网络错误(502)'
      break
    case 503:
      message = '服务不可用(503)'
      break
    case 504:
      message = '网络超时(504)'
      break
    case 505:
      message = 'HTTP版本不受支持(505)'
      break
    default:
      message = `连接出错(${status})!`
  }
  return `${message}，请检查网络或联系管理员！`
}

/**
 * axios 请求状态封装，返回响应式数据 fetch(), loading, error, code, msg 等常用方法/状态
 * @param {Object} options 对象
 * @param {String} options.url 请求的URL
 * @param {String} options.method 请求的方法
 * @param {Object} options.data 请求的参数
 * @returns {Object} 返回fetch(), loading, error, code, msg
 */
export const useRequest = (
  options: option = {
    url: '/',
    method: 'get',
    type: 'json',
    data: {},
    page: 1,
    pageSize: 24,
    pagination: false, // 是否分页
    base_url: '',
    apiMsgStatus: true, // 是否直接弹出后端错误
  },
) => {
  options.url = `${options.base_url || BASE_URL}${options.url}`
  const params: Params = {
    code: null, // 业务码
    success: false, // 请求是否成功
    data: {},
    msg: '',
    loading: null,
    error: null,
    query: {},
    filter: null,
    sort: '',
    page: options.page || 1,
    pageSize: options.pageSize || 24,
    total: 0,
    multiple: true, // 请求多次
    count: 0, // 第几次请求
    token: '', // token
  }

  const stateRef = useRef({ ...params })
  const [state, setState] = useState({ ...stateRef.current })
  const { removeToken, removeSessionKey, removeUserInfo } = useUserInfo()
  const { login } = useLoginRequest()

  // 请求函数
  const fetchData = async(sub_options?: any) => {
    stateRef.current.loading = true
    setState(e => ({ ...e, loading: true }))
    stateRef.current.query = {
      ...sub_options,
      ...(options.pagination && {
        page: stateRef.current.page,
        size: stateRef.current.pageSize,
      }),
      ...stateRef.current.filter,
      ...stateRef.current.sort,
    }
    try {
      const token = Taro.getStorageSync('token')
      const q = {
        ...options,
        ...{
          header: {
            Platform: 3,
            // Appid: WX_APPID,
            Authorization: token || stateRef.current.token,
          },
        },
        ...(options.method?.toUpperCase() == 'GET'
          ? {
            data: stateRef.current.query,
          }
          : {
            data: options.type?.toUpperCase() == 'FORMDATA' ? qs.stringify(stateRef.current.query) : stateRef.current.query,
          }),
      }
      const result = await Taro.request(q as any)
      const { statusCode } = result
      const { code, msg, data } = result.data
      if (statusCode === 200) {
        stateRef.current.success = code === 0
        stateRef.current.code = code
        stateRef.current.msg = msg
        stateRef.current.data = data
        stateRef.current.total = data?.list ? data?.total : 0
        if (code !== 0) {
          options.apiMsgStatus !== false
            && Taro.showToast({
              title: `${msg}`,
              icon: 'none',
            })
          console.log('错误：：', msg)
        }
      }
      else {
        if (statusCode === 401) {
          removeToken()
          // removeSessionKey()
          removeUserInfo()
          // 跳转回登录页面
          Taro.reLaunch({
            url: '/pages/login/index',
          })
          // 这一步是微信授权登录的步骤，如果执行通过了就不需要重定向到login页面了
          // 但是因为现在还没有规划微信授权登录这一步所以注释掉，直接重定向到login页面
          // 2022-11-22
          // login().catch((err)=>{
          //   if (err){
          //     Taro.reLaunch({
          //       url: '/pages/login/index',
          //     })
          //   }
          // })
        }
        else {
          Taro.showToast({
            title: `错误：${showStatus(statusCode)}`,
            icon: 'none',
          })
        }
      }
    }
    catch (e) {
      stateRef.current.success = false
      stateRef.current.error = true
      stateRef.current.msg = e.errMsg
      console.log('后台错误信息：：', e.errMsg)
    }
    stateRef.current.error = false
    stateRef.current.loading = false
    setState(() => ({ ...stateRef.current }))
    return stateRef.current
  }
  return {
    fetchData,
    state,
  }
}
