import axios, { AxiosInstance, AxiosResponse } from 'axios'
import { RequestConfig, RequestInterceptors } from './types'
import { userStore } from '@/store/user'
import { storage } from '@/utils'
import Store from '@/store'
import { constant } from '@/config'
import router from '@/router'
let loading = '' as any;

const store = userStore(Store)

class Request {
  // axios实例
  instance: AxiosInstance

  // 拦截器对象
  interceptorsObj?: RequestInterceptors

  constructor(config: RequestConfig) {
    // 创建实例
    this.instance = axios.create(config)
    // 类请求拦截器
    this.instance.interceptors.request.use(
      (req: any) => {
        const token = localStorage.getItem('token') || `Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI4NGYwNDhjYy1mNGM2LTQzMTgtOWRiNi1mOTRhMmM3YjlkZjMiLCJpYXQiOiIwNS8yMS8yMDI0IDA5OjM4OjAwIiwiaWQiOiIzNCIsInVzZXIiOiIzNCIsIm5hbWUiOiJhZG1pbmZsc3EiLCJyb2xlIjoiNSIsInRlbmFudCI6IjEiLCJwb3NpdGlvbiI6IjQ4ODQ4NDYyNTc5MzA5MyIsInNjb3BlIjoiTGVhcm5BZG1pbiIsIm5iZiI6MTcxNjI1NTQ4MCwiZXhwIjoxNzI0MTc1NDgwLCJpc3MiOiJtay1hZCIsImF1ZCI6Ik1hcmtpbmdBZG1pbkNsaWVudCJ9.MGl5dhcUNpGyjb4R0X_ME-BrXBmljfPiagqhyITVF1g`
        if (token) {
          // 如果有token给请求头加上
          req.headers.Authorization = `${token}`
          req.timeout = constant.CONFIG_REQUEST_TIMEOUT_TIME
        }
        if (req.contentType) {
          req.headers["Content-Type"] = req.contentType;
        }
        return req
      },
      (_err: any) => {
      }
    )

    // 类响应拦截器
    this.instance.interceptors.response.use(
      (res: AxiosResponse) => {
        const { data: resData, status, config } = res
        if (status == constant.CONFIG_CODE_SUCCESS && resData && Object.prototype.toString.call(resData) == '[object Object]') {
          resData.success = false
          resData.code == constant.CONFIG_CODE_SUCCESS && (resData.success = true)
        }
        resData.headers = res.headers['content-disposition'];
        if (resData.code !== 200) {
          if (config.responseType === 'blob') {
            const reader = new FileReader() as any;
            reader.readAsText(res.data, "utf-8");
            reader.onload = function () {
              if (reader.result) {
                try {
                  ElMessage.error(JSON.parse(reader.result).message)
                } catch (error) {

                }
              }
            };
          } else {
            ElMessage.error(resData.message)
          }
        }
        return resData
      },
      (err: any) => {
        function toLogin() {
          ElMessage.error('登录信息已失效，请重新登录!')
          storage.removeItem(constant.CONFIG_TOKEN)
          store.$patch((state) => {
            state.isLogin = false
          })
          if (localStorage.getItem('token')) {
            location.href = location.origin + "/login.html";
          } else {
            router.push({ path: '/login' })
          }
        }
        // 根据自己业务/接口返回做相应调整
        if (err.response) {
          const { status, data } = err.response
          ElMessage.error(data.message || data.title)
          switch (status) {
            case 401:
              toLogin()
              break
            case 403:
              toLogin()
              break
          }
        } else {
          ElMessage.error(err.message)
        }
      }
    )
  }

  request<T>(config: RequestConfig): Promise<T> {
    return new Promise((resolve, reject) => {
      loading = ElLoading.service({
        lock: true,
        background: 'rgba(0,0, 0, 0.7)',
        text: `加载中...`,
        body: true
      })
      if (config.interceptors?.requestInterceptors) {
        config = config.interceptors.requestInterceptors(config)
      }
      this.instance
        .request<any, T>(config)
        .then((res: T) => {
          // 如果我们为单个响应设置拦截器，这里使用单个响应的拦截器
          if (config.interceptors?.responseInterceptors) {
            res = config.interceptors.responseInterceptors<T>(res)
          }
          resolve(res || { code: 0 } as any)
        })
        .catch((err: any) => {
          reject(err)
        }).finally(() => {
          if (loading) {
            loading.close()
            loading = ''
          }
        })
    })
  }
}

export default Request
