import axios from 'axios'
import { showFailToast } from 'vant'

import { user } from '~/store'

// const token = user?.token
const token = user.value?.token // ?? '1a84JbyyAnC_bLLBTSqqDttK2cM6qAsBUOqM_aAk593putHUdkOZWPnSPUVFbcyOGrb_atG6OXbOyrkDRIwHwV9brYcC2ZAal8'

declare module 'axios' {
  interface AxiosInstance {
    (config: AxiosRequestConfig): Promise<any>
  }
}

const service = axios.create({
  baseURL: window.GLOBAL_CONFIG.api,
  method: 'post',
  timeout: 60000,
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
  },
})

service.interceptors.request.use(
  (config) => {
    // do something before request is sent
    config.data = Object.assign(
      {
        token: user.value?.token,
        site: 'txwx',
        client: 'web',
        api: 'json',
        // from: 'backend',
        issubmit: (config.url.endsWith('add') || config.url.endsWith('edit')) ? 1 : undefined,
      },
      config.data || {},
    )
    if (config.method === 'get') {
      config.params = Object.assign(
        {
          token: user.value?.token,
        },
        config.params || {},
      )
    }
    // 短时间多个请求会冲突
    // console.groupCollapsed('axios: ' + config.url)
    // console.log('request', config.data)
    return config
  },
  (error) => {
    // do something with request error
    console.log(error) // for debug
    return Promise.reject(error)
  },
)

// response interceptor
let isRelogin = false
service.interceptors.response.use(
  (response) => {
    const { code, msg, data } = response.data
    if (code === '10001') {
      if (!isRelogin) {
        isRelogin = true
        showFailToast(msg)
        request({
          url: '/user/main/login',
          data: {
            token: data.token,
          },
        }).then((res) => {
          if (res.code == 1) {
            localStorage.setItem('userInfo', JSON.stringify(res.data))
            isRelogin = false
            // 视情况打开
            // location.reload()
          }
        })
      }
    }
    else if (code !== '1') {
      showFailToast(msg)
    }
    // console.log('response', response.data)
    // console.groupEnd()
    return response.data
  },
  (error) => {
    console.error(`err${error}`) // for debug
    return Promise.reject(error)
  },
)

// 上传
export const request = axios.create({
  baseURL: window.GLOBAL_CONFIG.api,
  method: 'post',
  timeout: 5000,
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
  },
})
request.interceptors.response.use(
  (response) => {
    const { code, msg } = response.data
    if (code !== '1')
      showFailToast(msg)

    return response.data
  },
  (error) => {
    console.log(`err${error}`) // for debug
    return Promise.reject(error)
  },
)

function obj2form(data) {
  const formData = new FormData()
  Object.keys(data).forEach(key => formData.append(key, data[key]))
  return formData
}
export const REQUEST = {
  empty: axios,
  default: service,
  import: c => service({
    timeout: 10 * 60 * 1000,
    transformRequest: [obj2form],
    ...c,
  }),
  upload: c => service({
    timeout: 3 * 60 * 1000,
    transformRequest: [obj2form],
    ...c,
  }),
  download: c => service({
    timeout: 1 * 60 * 1000,
    method: 'get',
    params: { token: user.value?.token, limit: 10000, page: 1, api: 'xls', ...c },
  }),
}

export function download(url, data, name) {
  const params = Object.assign({ token: user.value?.token, limit: 10000, page: 1, api: 'xls' }, data)
  const paramsStr = Object.entries(params).map(([k, v]) => `${k}=${v}`).join('&')
  const el = document.createElement('a')
  const href = `${window.GLOBAL_CONFIG.api}${url}?${paramsStr}`
  el.setAttribute('href', href)
  name && el.setAttribute('download', name)
  el.click()
}

export function download2(url, name) {
  const el = document.createElement('a')
  const href = `${window.GLOBAL_CONFIG.api}/openapi/download.php?path=${url}&name=${name}`
  el.setAttribute('href', href)
  name && el.setAttribute('download', name)
  el.click()
}

export default (...args) => {
  if (!isRelogin)
    return service(...args)
  else
    return Promise.reject({})
}
