import { ACCESS_TOKEN_KEY } from 'constants/storage'
import Fly from 'flyio/dist/npm/wx'
import { useGlobSetting } from 'hooks/setting/env'
import {
  generateAesKey,
  encryptBase64,
  encryptWithAes
} from 'utils/encryption/crypto'
import * as encryptUtil from 'utils/encryption/jsencrypt'
import config from '@/config'

/**
 * @type {import('flyio').Fly}
 */
export const fly = new Fly()
fly.config = {
  baseURL: config.api + config.prefix,
  timeout: 60000 // 超时时间暂时设置60秒
}

const { clientId } = useGlobSetting()

// 免token白名单
const whiteList = ['/auth/login']

// fly请求拦截器
fly.interceptors.request.use((config) => {
  const authorization = uni.getStorageSync(ACCESS_TOKEN_KEY)
  const { url, encrypt, body } = config

  if (encrypt) {
    const aesKey = generateAesKey()
    config.headers['encrypt-key'] = encryptUtil.encrypt(encryptBase64(aesKey))

    if (typeof body === 'object') {
      config.body = encryptWithAes(JSON.stringify(body), aesKey)
    } else {
      config.body = encryptWithAes(config.body, aesKey)
    }
  }
  config.headers['Authorization'] = `Bearer ${authorization}`
  config.headers['Clientid'] = clientId

  if (whiteList.includes(url)) {
    return config
  }

  if (config.method === 'PUT') {
    if (config.encrypt) {
      config['headers']['Content-Type'] = 'application/json'
    }
    // if (
    //   config['headers']['Content-Type'] !== 'multipart/form-data' &&
    //   config['headers']['Content-Type'] !== 'application/json'
    // ) {
    //   config.headers['content-type'] = 'application/x-www-form-urlencoded'
    // }
  }

  return config
})

// fly响应拦截器
fly.interceptors.response.use(
  async (response) => {
    const { data, request } = response
    const { url } = request
    const { code, msg = '' } = data
    if (code === 200) {
      return Promise.resolve(data)
    } else if (code === 401) {
      fly.lock()
      uni.reLaunch({
        url: '/pages/views/login/index',
        complete: () => {
          fly.clear()
          fly.unlock()
        }
      })
      return Promise.reject(data)
    } else {
      uni.hideLoading()
      console.error('接口响应失败:', url, msg)
      return Promise.reject(data)
    }
  },
  (error) => {
    uni.hideLoading()
    const { response } = error
    if (response) {
      return Promise.reject(response)
    } else {
      throw error
    }
  }
)
