/**
 * 全站http配置
 *
 * axios参数说明
 * isSerialize是否开启form表单提交
 * isToken是否需要token
 */
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'
// import store from '@/store/user'
import { useMyStore } from '@/store'
import router from '@/router';
import { serialize } from '@/utils/common'
import { getToken } from '@/utils/auth';
import { showNotify } from 'vant';
import website from '@/config/website';
import { Base64 } from 'js-base64'
// import NProgress from 'nprogress';
// import 'nprogress/nprogress.css';
import { ELocalStorageKey } from '@/utils/enums';
export * from './type'

// 自定义响应类型
interface CustomAxiosResponse<T = any> extends AxiosResponse<T> {
  data: T
}

// 定义你的请求类型
interface CustomAxiosRequestConfig extends AxiosRequestConfig {
  // 是否开启鉴权
  authorization?: boolean
}

type CustomAxiosConfig = {
  [x: string]: any
  <T = any, R = CustomAxiosResponse<T>, D = CustomAxiosRequestConfig>(config: D): Promise<R>
}

const REQUEST_ID = 'X-Request-Id'

const getAuthToken = () => {
  return localStorage.getItem(ELocalStorageKey.Token)
}

const instance: CustomAxiosConfig = axios.create({
  // withCredentials: true,
  headers: {
    'Content-Type': 'application/json',
  },
  baseURL: '/api',
  // timeout: 12000,
  withCredentials: true,
})

instance.interceptors.request.use(
  (config: {
    data: any
    method: string
    token: any
    text: boolean
    json: boolean
    meta: {
      isSerialize: boolean
      isToken: boolean
      noCookie: boolean
    }
    headers: { [x: string]: string | null }
    url: string
    authorization: boolean
  }) => {
    if (!config.url.includes('/blade-') && !config.url.includes('https://') && !config.url.includes('http://')) {
      config.url = '/drone-device-core' + config.url
    }
    const authorization = config.authorization === false
    if (!authorization) {
      config.headers.Authorization = `Basic ${Base64.encode(`${website.clientId}:${website.clientSecret}`)}`
    }
    // 让每个请求携带token
    const meta = config.meta || {}
    const isToken = meta.isToken === false
    if (getToken() && !isToken) {
      config.headers[website.tokenHeader] = 'bearer ' + getToken()
    } else {
      // 为了兼容分享页面
      config.headers[website.tokenHeader] = 'bearer ' + getAuthToken()
    }
    if (meta.noCookie) {
      delete config.headers.cookie
    }
    // headers中配置text请求
    if (config.text === true) {
      config.headers['Content-Type'] = 'text/plain'
    }
    // headers配置JSON请求
    if (config.json === true) {
      config.headers['Content-Type'] = 'application/json'
    }
    // 水情预报接口调用
    if (config.token) {
      config.headers.Authorization = config.token
    }
    // headers中配置serialize为true开启序列化
    if (config.method === 'post' && meta.isSerialize === true) {
      config.data = serialize(config.data)
    }
    return config
  },
  (error: any) => {
    return Promise.reject(error)
  },
)

instance.interceptors.response.use(
  (res: { data: { code: any; msg: any; message: any; error_description: any }; status: any; config: { url: string; meta: { noCookie: boolean } } }) => {
    const status = res.data.code || res.status
    const message = res.data.msg || res.data.message || res.data.error_description || '未知错误'
    // 如果是401则跳转到登录页面
    if (status == 401) {
      router.push({ path: '/login' })
    }
    // 如果请求为非200否者默认统一处理
    if (status !== 200) {
      // 排除海康 code 为 0  情况
      if (status === 0) {
        return res
      }
      if ('meta' in res.config && 'noCookie' in res.config.meta && res.config.meta.noCookie === true) {
        return Promise.reject(new Error(message))
      }
      if (message === '缺失令牌,鉴权失败') {
        showNotify({ type: 'warning', message: '登录信息已过期，请重新登录' })
      }
      if (
        ![
          '没有收到消息回复。',
          '未知消息',
          '设备端退出drc模式',
          '未能恢复航路作业。错误码：: 319042',
          'success',
          '缺失令牌,鉴权失败',
        ].includes(message)
      ) {
        showNotify({ type: 'warning', message: message })
      }
      return Promise.reject(new Error(message))
    }
    return res
  },
  (err: {
    config: { headers: { [x: string]: any }; url: any; method: any }
    response: { data: { message: string; result: { message: string } }; status: number }
  }) => {
    const requestId = err?.config?.headers && err?.config?.headers[REQUEST_ID]
    if (requestId) {
      console.info(REQUEST_ID, '：', requestId)
    }
    console.info('url: ', err?.config?.url, `【${err?.config?.method}】 \n>>>> err: `, err)

    let description = '-'
    if (err.response?.data && err.response.data.message) {
      description = err.response.data.message
    }
    if (err.response?.data && err.response.data.result) {
      description = err.response.data.result.message
    }
    if (!err.response || !err.response.status) {
      showNotify({ type: 'danger', message: '网络异常，请检查后端服务后重试' })
      return
    }
    if (err.response?.status !== 200) {
      if (err.response.data?.msg) {
        showNotify({ type: 'danger', message: err.response.data?.msg })
      } else if (err.response.data?.error_description) {
        showNotify({ type: 'danger', message: err.response.data?.error_description })
      } else {
        showNotify({ type: 'danger', message: `错误码: ${err.response?.status}` })
      }
    }
    if (err.response?.status == 401) {
      router.push({ path: '/login' })
    }
    return Promise.reject(err)
  },
)

export default instance
