import axios from 'axios'
import store from '@/store'
import router from '@/router'
// import { isSubFlow, queryParentUpbrNo } from '@/utils'
import { getRefreashToken, getToken, removeSessionStorage } from '@/utils/auth'
// import { ProMessage as Message } from '@/components'
import settings from '../settings.js'
const { systemPrefix, isMock, frontApp, passwordEncrypt } = settings


import Qs from "qs"
// import { alarmWarnMessageBox } from "@/utils/util"
function setAuth (config) {
  if (config.url.indexOf('oauth/token') < 0) {
    // let each request carry token
    // ['Authorization'] is a custom headers key
    // please modify it according to the actual situation
    config.headers['Authorization'] = `Bearer ${getToken()}`
    config.headers['Refresh-Token'] = `${getRefreashToken()}`
  }
  return config
}
// create an axios instance
const service = axios.create({
  // baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  withCredentials: false, // send cookies when cross-domain requests
  // widthCredentials: true,
  timeout: 500000, // request timeout
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  }
})

// request interceptor
service.interceptors.request.use(
  config => {
    const method = config.method.toLowerCase()
    const contextType = config.headers["Content-Type"]
    // 页面流水号
    if (config.data && config.data.pageTraceNo) {
      config.headers['Page-Trace-No'] = config.data.pageTraceNo
    }
    if (config.params && config.params.pageTraceNo) {
      config.headers['Page-Trace-No'] = config.params.pageTraceNo
    }
    if (config.data?.uploadFilename || config.params?.uploadFilename) {
      config.headers['File-Trace-No'] = config.data?.uploadFilename || config.params?.uploadFilename
    }
    // if (isSubFlow()) {
    //   config.headers['workflowSubProcess'] = 'Y'
    //   config.headers['workflowSubUpbrno'] = queryParentUpbrNo()
    // }
    switch (method) {
      case "get":
        if (!config.params) {
          config.params = {}
        }
        break
      case "post":
        if (!config.data) {
          config.data = {}
        }
        //requestType: form / json
        if (isMock) {
          config.headers["Content-Type"] = "application/json"
        } else {
          if (contextType && contextType === 'multipart/form-data') {

          } else {
            if (config.requestType === "json") {
              config.headers["Content-Type"] = "application/json" //配套application/json使用
            } else {
              let data = config.data
              //规则预警再次执行的请求，不进行此操作
              if (config.headers?.ignoreAlarm != true) {
                if (typeof data == "string") {
                  data = Qs.parse(data)
                }
                config.data = Qs.stringify(data) //配套application/x-www-form-urlencoded使用
              }
              config.headers["Content-Type"] = "application/x-www-form-urlencoded"
            }
          }
        }
        break
      default:
    }
    //暂时添加token 满足工作流获取信息
    const user = JSON.parse(sessionStorage.getItem('user') || '{}')
    const depart = JSON.parse(sessionStorage.getItem('depart') || '{}')
    const role = JSON.parse(sessionStorage.getItem('role') || '{}')
    const AccessToken = sessionStorage.getItem('AccessToken')
    let httpHeaders = JSON.stringify({
      userId: user.no || user.userId,
      depNo: depart.no || user.depNo,
      roleNo: role.no || user.roleNo,
      upBrNo: depart.upBrNo || user.upBrNo,
      tenantId: depart.upBrNo || user.upBrNo
    })
    config.headers['token'] = httpHeaders
    // do something before request is sent
    if (config.url.indexOf('oauth/token') < 0) {
      // let each request carry token
      // ['Authorization'] is a custom headers key
      // please modify it according to the actual situation
      config.headers['Authorization'] = `Bearer ${getToken()}`
      config.headers['Refresh-Token'] = `${getRefreashToken()}`
    }
    return config
  },
  error => {
    // do something with request error
    console.log(error) // for debug
    return Promise.reject(error)
  }
)
// 是否正在刷新的标记
let isRefreshing = false
// 重试队列，每一项将是一个待执行的函数形式
let requests = []
// response interceptor
service.interceptors.response.use(
  /**
   * If you want to get http information such as headers or status
   * Please return  response => response
  */

  /**
   * Determine the request status by custom code
   * Here is just an example
   * You can also judge the status by HTTP Status Code
   */
  async response => {
    //如果response返回头中包含
    // if (response.headers && (response.headers.authorization || response.headers['refresh-token'])) {
    //   let refreashData = { access_token: response.headers.authorization, refresh_token: response.headers['refresh-token'] }
    //   store.dispatch('user/refreashToken', refreashData)
    // }
    let res = response.data
    const headers = response.headers
    //如果类型为Blob类型，且数据格式为json，说明请求出错，转换为对象类型
    if (res instanceof Blob && res.type === 'application/json') {
      let data = await res.text()
      let resTemp = JSON.parse(data)
      if (resTemp.errCode === 'A0105' || resTemp.errCode === 'A0108') {
        res = resTemp
      }
    }
    if (response.status == 200) {
      // A0105: Illegal token; Actively refresh the token once;
      if (res?.errCode === 'A0105') {
        const config = response.config
        let frontApp2 = "front-app"
        if (passwordEncrypt) {
          frontApp2 = frontApp
        }
        //判断是否正在刷新Token
        if (!isRefreshing) {
          //更新正在刷新标记
          isRefreshing = true
          let refreshData = {
            client_id: "front-app",
            client_secret: frontApp2,
            refresh_token: getRefreashToken(),
            grant_type: 'refresh_token',
          }
          return service({
            url: `${systemPrefix}/oauth/token`,
            method: 'post',
            data: refreshData,
          }).then((ret) => {
            if(ret.success){
              //刷新token成功，重新发送请求
              store.dispatch('user/refreashToken', ret.data)
              // 已经刷新了token，将所有队列中的请求进行重试
              requests.forEach(cb => cb())
              // 重试完了清空这个队列
              requests = []
              // 重试当前请求并返回promise
              return service(config)
            }else{
              //刷新Token失败
              console.error('刷新Token失败 =>', res)
              //删除token
              removeSessionStorage()
              store.dispatch('user/resetToken')
              //跳转至登录
              window.app._router.push('/login')
            }
          }).catch(res => {
            //刷新Token失败
            console.error('刷新Token失败 =>', res)
            //删除token
            removeSessionStorage()
            store.dispatch('user/resetToken')
            //跳转至登录
            window.app._router.push('/login')
          }).finally(() => {
            //更新正在刷新标记
            isRefreshing = false
          })
        } else {
          //刷新token亦然失败,则提示错误调转至工作台
          if (config.url.indexOf('oauth/token') != -1) {
            isRefreshing = false
            // Message({
            //   message: '抱歉，您的登录状态已失效，请重新登录！',
            //   type: 'error',
            //   duration: 5 * 1000
            // })
            //删除token
            removeSessionStorage()
            store.dispatch('user/resetToken')
            //跳转至登录
            window.app._router.push('/login')
          } else {
            // 正在刷新token，返回一个未执行resolve的promise
            return new Promise((resolve) => {
              // 将resolve放进队列，用一个函数形式来保存，等token刷新后直接执行
              requests.push(() => {
                resolve(service(config))
              })
            })
          }
        }
      } else if (res?.errCode === 'A0108') {
        // Message({
        //   message: '您已在其他设备登录！',
        //   type: 'error',
        //   duration: 5 * 1000
        // })
        //删除token
        removeSessionStorage()
        store.dispatch('user/resetToken')
        //跳转至登录
        window.app._router.push('/login')

      } else if (res?.errCode === 'A0301') {//预警警告异常
        let resp = await new Promise(resolve => {
          //生成预警异常提示框
        //   alarmWarnMessageBox("1", { ...res, resolve })
        })
        if (resp) {
          let alarmWarnConfig = response.config
          alarmWarnConfig.headers["ignoreAlarm"] = true
          return service(alarmWarnConfig)
        } else {
          res.errMessage = "预警规则校验未通过"
          return res
        }

      } else if (res?.errCode === 'A0302') {//预警阻断
        let resp = await new Promise(resolve => {
          //生成预警异常提示框
        //   alarmWarnMessageBox("2", { ...res, resolve })
        })
        if (resp) {
          res.errMessage = "预警规则校验未通过"
          return res
        }
      } else {
        // 文件下载需要获取文件名称
        if (['file-platform'].includes(headers['category'])) {
          return response
        }
        return res
      }
    } else {//非200则提示错误，并返回错误信息
    //   Message({
    //     message: res.errMessage || 'Error',
    //     type: 'error',
    //     duration: 5 * 1000
    //   })
      return Promise.reject(new Error(res.errMessage || 'Error'))
    }
  },
  error => {
    console.log('err' + error) // for debug
    // Message({
    //   message: error.message,
    //   type: 'error',
    //   duration: 5 * 1000
    // })
    return Promise.reject(error)
  }
)

export default service
