import axios from 'axios'
import { showFullScreenLoading, tryHideFullScreenLoading } from './loading'
import { resetMessage } from './resetMessage'
import { ElMessage } from 'element-plus'
import { Base64 } from 'js-base64'
import { getToken, setAccessToken } from '@/utils/jsCookie'

const service = axios.create({
  baseURL: '',
  timeout: 60000
})

service.interceptors.request.use(
  config => {
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    if (config.loading) {
      showFullScreenLoading()
    }
    const headers = config.headers
    if(config.url.indexOf('/oauth2/token') > -1){   
      let encodeString = Base64.encode(`${import.meta.env.VITE_APP_KEY}:${import.meta.env.VITE_APP_SECRET}`)
      headers['Authorization'] = `Basic ${encodeString}`
      headers['content-type'] = 'application/json'
    } else {
      if(getToken()){
        headers['Authorization'] = `Bearer ${getToken()}`
      }
    }
    return config
  },
  error => {
    showFullScreenLoading()
    return Promise.reject(error)
  }
)

service.interceptors.response.use(
  response => {
    const res = response.data
    const headers = response.headers
    tryHideFullScreenLoading()
    // 直接下载的时候判断请求头处理下载
    if (
      headers &&
      (headers['content-type'] === 'application/pdf' ||
        headers['content-type'] === 'application/octet-stream' ||
        headers['content-type'] === 'application/x-msdownload' ||
        headers['content-type'] ===
          'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||
        headers['content-type'] === 'application/vnd.ms-excel')
    ) {
      downloadBlob(response)
      return response // 是为了后面
    }
    // if the custom code is not 20000, it is judged as an error.
    if (res.code && res.code !== 'success') {
      resetMessage({
        message: res.message || 'Error',
        type: 'error',
        duration: 5 * 1000
      })
      // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
      if(res.code === 'authentication.failed'){
        setAccessToken()
      }
      return Promise.reject(new Error(res.msg || 'Error'))
    } else {
      return response
    }
  },
  error => {
    tryHideFullScreenLoading()
    if (error.response) {
      switch (error.response.status) {
        case 401:
          /*  MessageBox.confirm(`${error.response.data.msg}`, '登录超时', {
                        confirmButtonText: '登录',
                        type: 'warning'
                    }).then(() => {
                        store.dispatch('user/resetToken').then(() => {
                            // location.reload();
                        });
                    });*/
          break
        case 500:
          resetMessage({
            message: '服务器错误，请联系管理员！',
            type: 'error',
            duration: 5 * 1000
          })
          break
        case 404:
          resetMessage({
            message: '资源不存在！',
            type: 'error',
            duration: 5 * 1000
          })
          break
        case 503:
          resetMessage({
            message: '服务当前无法处理请求！',
            type: 'error',
            duration: 5 * 1000
          })
          break
        default:
          ElMessage.error('其他错误，请联系管理员！')
          break
      }
    } else {
      resetMessage({
        message: error.message,
        type: 'error',
        duration: 5 * 1000
      })
    }
    return Promise.reject(error)
  }
)

/**
 * fetch，对应get请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 * @param {Object} config [请求时axios的额外配置]
 */

export function fetch(url: string, params?: any, config = { loading: true }) {
  return service({
    ...{
      method: 'get',
      url,
      params
    },
    ...config
  })
}

/**
 * post方法，对应post请求
 * @param {String} url [请求的url地址]
 * @param {Object} data [请求时携带的参数]
 * @param {Object} config [请求时axios的额外配置]
 */

export function post(url: string, data?: any, config = { loading: true }) {
  return service({
    ...{
      method: 'post',
      url,
      data
    },
    ...config
  })
}

/**
 * delet，对应delete请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 * @param {Object} config [请求时axios的额外配置]
 */

export function DELETE(url: string, params?: any, config = { loading: true }) {
  return service({
    ...{
      method: 'delete',
      url,
      params
    },
    ...config
  })
}

export const downloadBlob = (res: any) => {
  const blob = new Blob([res.data], { type: 'application/vnd.ms-excel' })
  // @ts-ignore
  if (window.navigator.msSaveOrOpenBlob) {
    // @ts-ignore
    navigator.msSaveBlob(blob, res.headers.filename)
  } else {
    const link = document.createElement('a')
    const evt = document.createEvent('HTMLEvents')
    evt.initEvent('click', false, false)
    link.href = URL.createObjectURL(blob)
    link.download = decodeURI(res.headers.filename)
    link.style.display = 'none'
    document.body.appendChild(link)
    link.click()
    window.URL.revokeObjectURL(link.href)
  }
}

export default service
