import axios from 'axios'
import { useUserStore } from '@/store'
import storage from 'store'
import { Notification, Message } from '@arco-design/web-vue';
import { VueAxios } from './axios'
import { v4 as uuidv4 } from 'uuid'
import { LRUCache } from 'lru-cache'
import { generateAesKey, aesEncrypt, aesDecrypt, rsaEncryptKey } from './encrypt'
import { isElectron } from './electron'

const electron = isElectron()

const request = axios.create({
  baseURL: import.meta.env.VITE_APP_API_BASE_URL,
  timeout: 20000
})

const aesKeyCache = new LRUCache({
  max: 200,
  ttl: 1000 * 60 * 5
})

const errorHandler = (error) => {
  const userStore = useUserStore()
  const user = storage.get('user')
  console.log(error.stack)

  if (error.response) {
    if (error.response.status === 401) {
      Message.error('登录失效,请重新登录')
      if (user) {
        userStore.logout()  // 调用 Pinia store 中的 logout 方法
        setTimeout(() => {
          window.location.reload()
        }, 1500)
      }
    }
  } else {
    console.error('无法连接到服务器，请检查网络')

    Notification.error({
      title: '请求失败',
      content: '网络不畅或服务器停机维护中，请稍后再试'
    })
  }
}

request.interceptors.request.use(config => {
  const userStore = useUserStore()

  const user = userStore.$state
  if (config.headers['Content-Type'] !== 'multipart/form-data') {

    const data = {
      ...(config.method === 'get' ? config.params : config.data),
      time: Date.now(),
      uuid: user?.uuid,
      session: user?.session
    }

    const aesKey = generateAesKey()
    const encryptedData = aesEncrypt(data, aesKey)
    const encryptedKey = rsaEncryptKey(aesKey)

    const requestId = uuidv4()
    config.headers['X-Request-ID'] = requestId
    aesKeyCache.set(requestId, aesKey)

    if (config.method === 'get')
      config.params = {
        a: encryptedData,
        b: encryptedKey
      }
    else
      config.data = {
        a: encryptedData,
        b: encryptedKey
      }
  }

  if (electron)
    config.headers["Device-Type"] = 'RunForge Desktop Client'

  return config
}, errorHandler)

request.interceptors.response.use(async (response) => {
  if (response.data.b) {
    const requestId = response.config.headers['X-Request-ID']
    const aesKey = aesKeyCache.get(requestId)

    response.data.data = aesDecrypt(response.data.b, aesKey)
    aesKeyCache.delete(requestId)
  }

  if (response.data?.code === -403) {
    Message.error(response.data.msg || '权限不足')
  }

  return response.data
}, errorHandler)

const installer = {
  vm: {},
  install(Vue) {
    Vue.use(VueAxios, request)
  }
}

export default request

export {
  installer as VueAxios,
  request as axios
}
