import axios from 'axios'
import { ElMessage, ElLoading } from 'element-plus'
import { getToken, removeToken } from '@/utils/auth'
import router from '../router'

var loadingInstance = null
const BASE_URL = import.meta.env.VITE_APP_REQUESTURL
const timeout = 20000
// create an axios instance
const service = axios.create({
  // baseURL: process.env.VUE_APP_BASE_API,
  baseURL: BASE_URL,
  timeout: timeout, // request timeout
})

// request interceptor
service.interceptors.request.use(
  config => {
    if (getToken()) {
      config.headers['Authorization'] =  'Bearer ' + getToken()
    }
    return config
  },
  error => {
    return Promise.reject(error)
  },
)

// response interceptor
service.interceptors.response.use(
  response => {
    const res = response.data
    // if the custom code is not 20000, it is judged as an error.
    return res
  },
  error => {
    console.log('错误：' + error) // for debug
    if (error.code !== 'ERR_CANCELED') {
      ElMessage.error({ message: error.msg || error.message })
    }
    return Promise.reject(error)
  },
)

const handleUrl = (url, params) => {
  if (params) {
    var str = ''
    var i = 0
    for (var key in params) {
      if (i === 0) {
        str += ''
      } else {
        str += '&'
      }
      str += key + '=' + params[key]
      i++
    }
    if (/\?/.test(url)) {
      url = url + '&' + str
    } else {
      url = url + '?' + str
    }
  }

  return url
}
const doRequest = (url, method = 'GET', params, opts, callback) => {
  return new Promise((resolve, reject) => {
    const defaultOpts = {
      SHOW_LOADING: true,
      headers: {},
    }
    opts = Object.assign(defaultOpts, opts)

    // 显示loading
    if (opts.SHOW_LOADING) {
      loadingInstance = ElLoading.service({
        lock: true,
        background: 'rgba(0, 0, 0, .7)',
      })
    }
    if (/get/i.test(method)) {
      url = handleUrl(url, params)
    } else if (/upload/i.test(method)) {
      opts.headers['Content-Type'] = 'multipart/form-data'
      method = 'POST'
    } else if (/export/i.test(method)) {
      url = handleUrl(url, params)
      window.open(BASE_URL + url)
      opts.SHOW_LOADING && loadingInstance && loadingInstance.close()
      return
    } else if (/post/i.test(method)) {
      opts.headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
    } else if (/blob/i.test(method)) {
      method = 'POST'
      opts.headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
      opts.responseType = 'blob'
    } else if (/json/i.test(method)) {
      method = 'POST'
      opts.headers['Content-Type'] = 'application/json'
    } else if (/qqmap/i.test(method)) {
      method = 'POST'
      opts.headers['Content-Type'] = 'application/json'
    } else if (/file/i.test(method)) {
      method = 'POST'
      opts.headers['Content-Type'] = 'application/json'
      opts.responseType = 'blob'
    }else if (/captchaImage/i.test(method)) {
      method = 'get'
      opts.headers['Content-Type'] = 'application/json'
    }
    service({
      url: url,
      method: method,
      data: params,
      headers: opts.headers,
      cancelToken: new axios.CancelToken(function executor(c) {
        // 设置 cancel token
        callback && callback(c)
      }),
      responseType: opts.responseType || '',
      timeout: opts.timeout || timeout,
      onDownloadProgress: opts.onDownloadProgress,
      onUploadProgress: opts.onUploadProgress,
    })
      .then(res => {
        if (!res) {
          opts.SHOW_LOADING && loadingInstance && loadingInstance.close()
          return
        }
        // if (opts.responseType === 'blob') {
        //   resolve(res)
        //   opts.SHOW_LOADING && loadingInstance && loadingInstance.close()
        //   return
        // }

        if (opts.responseType === 'blob') {
          const reader = new FileReader()
          reader.onload = evt => {
            try {
              const resultObj = JSON.parse(evt.target.result)
              if (resultObj?.code) {
                reject(res)
                ElMessage.error({
                  dangerouslyUseHTMLString: true,
                  message: resultObj.msg,
                })
              } else {
                // console.log(res, 'kkk')
              }
              // resultOb是解码后的数据，然后再进行提示处理
            } catch (error) {
              resolve(res)
            }
          }

          reader.readAsText(res)

          opts.SHOW_LOADING && loadingInstance && loadingInstance.close()
          return
        }
        if (res.code === 200) {
          resolve(res) //
          // resolve(res.data)
        } else if (res.code === 401) {
          if (getToken()) {
            ElMessage.error({ message: res.msg || `信息已过期，请重新登录！` })
            removeToken()
          }
          router.push({ path: '/login' })
        } else {
          ElMessage.error({
            dangerouslyUseHTMLString: true,
            message: res.msg || `异常，code: ${res.code || '无法识别'}，请联系管理员！`,
          })
          reject(res)
        }
        opts.SHOW_LOADING && loadingInstance && loadingInstance.close()
      })
      .catch(err => {
        opts.SHOW_LOADING && loadingInstance && loadingInstance.close()
        if (err.code === 'ERR_CANCELED') return
        ElMessage.error({
          dangerouslyUseHTMLString: true,
          message: err || '网络异常，请检查网络连接！',
        })
      })
  })
}

export default doRequest
