import useUserStore from '../store/user'
import { getrefreshtoken } from '@/apis/longin'
import { getToken, setToken, removeToken } from '@/utils/auth'
import { goToPage, checkConfigFileExists, readConfigFile, createDefaultConfig } from '@/utils/util'
interface Response {
  code: number
  data: object
  msg: string
}
// let appVersion = ''
// plus.runtime.getProperty(plus.runtime.appid, (info) => {
//   appVersion = info.version
// })
// let newhttp = '' //请求ip
// let newpro = '' //请求端口
let newhttp = import.meta.env.VITE_APP_BASE_URL
let newpro = import.meta.env.VITE_APP_BASE_URLpro
let newapi = import.meta.env.VITE_APP_BASE_PRE //请求的api开头

// #ifdef APP-PLUS
const configFileName = 'app_config.json'
//const configFilePath = `${plus.io.PRIVATE_DOC}/${configFileName}`; // 私有目录
// 或
const configFilePath = `${plus.io.PUBLIC_DOWNLOADS}/${configFileName}` // 公共目录

async function handleConfigFile() {
  try {
    const exists = await checkConfigFileExists(configFilePath, configFileName)
    if (exists) {
      const config = await readConfigFile(configFilePath, configFileName)
      console.log('读取配置:', config)
      newhttp = config.url
      newpro = config.pro
      const userStore = useUserStore()
      userStore.seturlip(newhttp)
      userStore.seturlpro(newpro)
      userStore.setallurl(newhttp + ':' + newpro + newapi)
      return config
    } else {
      newhttp = import.meta.env.VITE_APP_BASE_URL
      newpro = import.meta.env.VITE_APP_BASE_URLpro
      const userStore = useUserStore()
      userStore.seturlip(newhttp)
      userStore.seturlpro(newpro)
      userStore.setallurl(newhttp + ':' + newpro + newapi)
      const defaultConfig = await createDefaultConfig(configFilePath, configFileName, { url: newhttp, pro: newpro, Version: 'appVersion' })
      console.log('生成默认配置:', defaultConfig)
      return defaultConfig
    }
  } catch (err) {
    newhttp = import.meta.env.VITE_APP_BASE_URL
    newpro = import.meta.env.VITE_APP_BASE_URLpro
    console.error('操作失败:', err)
    throw err
  }
}
// 调用示例
// handleConfigFile().then((config) => {
//   // 使用配置数据
//   //debugger
// })
// #endif

const requestObj = {
  isLock: false,
  methodstr: 'POST',
  http({ url = '', data = {}, isPost = '0', isSinglePost = false, isToken = true, timeout = 20000 }) {
    const _this = this
    const userStore = useUserStore()
    return new Promise(function (resolve, reject) {
      if (isSinglePost && _this.isLock) {
        reject({ message: '加载中' })
      }
      // debugger
      _this.isLock = true
      // #ifdef H5

      url = import.meta.env.VITE_APP_BASE_PRE + url
      // #endif
      // debugger
      // #ifndef H5
      // url = import.meta.env.VITE_APP_BASE_URL + ':' + import.meta.env.VITE_APP_BASE_URLpro + import.meta.env.VITE_APP_BASE_PRE + url
      // url = import.meta.env.VITE_APP_BASE_URL + ':' + import.meta.env.VITE_APP_BASE_URLpro + newapi + url
      // if (!userStore.allurl) {
      //   newhttp = import.meta.env.VITE_APP_BASE_URL
      //   newpro = import.meta.env.VITE_APP_BASE_URLpro
      //   userStore.seturlip(newhttp)
      //   userStore.seturlpro(newpro)
      //   userStore.setallurl(newhttp + ':' + newpro + newapi)
      // }

      userStore.seturlip(newhttp)
      userStore.seturlpro(newpro)
      userStore.setallurl(newhttp + ':' + newpro + newapi)

      url = userStore.allurl + url

      console.log('11111', url)
      // #endif
      //debugger
      // console.log('lsdfcs', userStore)
      const header = {
        'content-type': 'application/json',
        // 'content-type': 'application/x-www-form-urlencoded',
        // Authorization: ''
        Bearerauth: ''
      }
      // if (isPost == '3') {
      //   header['content-type'] = 'application/x-www-form-urlencoded'
      // }
      if (getToken() && isToken) {
        // header['Authorization'] = 'Bearer ' + userStore.token
        header['Bearerauth'] = 'Bearer ' + getToken()
      }

      let htconfig = { url: url, data: data, isPost: isPost, isSinglePost: isSinglePost, isToken: isToken, timeout: timeout, header: header }
      // debugger
      switch (isPost) {
        case '0':
          _this.methodstr = 'POST'
          break
        case '1':
          _this.methodstr = 'GET'
          break
        case '2':
          _this.methodstr = 'put'
          break
        default:
          _this.methodstr = 'DELETE'
        // 当 expression 不匹配任何 case 时执行的代码
      }
      uni.showLoading({
        title: '加载中...',
        duration: 15000 // 可根据实用场景设置时间
      })

      uni.request({
        url,
        header,
        data,
        // method: isPost ? 'POST' : 'GET',
        method: _this.methodstr,
        timeout: timeout,
        success(res) {
          // debugger
          uni.hideLoading()
          res.data.code = res.data.code == 'ok' ? 200 : res.data.code
          const data = res.data as Response
          if (res.statusCode === 200) {
            if (data.code == 200) {
              // 成功
              resolve(res.data)
            } else if (data.code == 401) {
              // uni.reLaunch({
              //   url: '/pages/login/login'
              // })
            } else if (data.code == 601) {
              // userStore.setrefreshtoken()
              // uni.showToast({ title: data.msg, icon: 'none' })
              // setTimeout(() => {
              //   goToPage({
              //     url: 'pages/login/login',
              //     mode: 'navigateTo'
              //   })
              // }, 1000)
              return handleTokenRefresh(htconfig)
                .then((result) => resolve(result))
                .catch((error) => reject(error))
            } else {
              uni.showToast({ title: data.msg, icon: 'none' })
              reject(res.data)
            }
          } else {
            uni.showToast({ title: '响应错误', icon: 'none' })
            reject({ message: '响应错误' })
          }
        },
        fail(err) {
          uni.hideLoading()
          console.log('fail', err)
          uni.showToast({ title: '网络错误', icon: 'none' })
          reject({ message: '网络错误' })
        },
        complete() {
          uni.hideLoading()
          _this.isLock = false
        }
      })
    })
  }
}

// 请求队列与刷新状态管理
let requestQueue: any = []
let isRefreshing = false
let tokenRefreshPromise: any = null

/**
 * 处理Token刷新和请求重试的核心函数
 * @param {Object} config - 原始请求配置
 * @returns {Promise} - 返回处理结果
 */
const handleTokenRefresh = (config: any) => {
  const userStore = useUserStore()
  return new Promise((resolve, reject) => {
    // 将当前请求添加到队列
    requestQueue.push({
      resolve,
      reject,
      config
    })

    // 如果已经在刷新token，则不再重复刷新
    if (tokenRefreshPromise) {
      return
    }

    // 如果没有在刷新token，则开始刷新
    if (!isRefreshing) {
      isRefreshing = true

      const rtoken = userStore.refreshtoken
      if (!rtoken) {
        // 没有刷新token，直接跳转登录
        resetQueueAndRefreshState(new Error('未找到刷新token'))
        showLoginConfirm()
        reject(new Error('未找到刷新token'))

        return
      }

      // 创建token刷新Promise并保存引用
      tokenRefreshPromise = getrefreshtoken(rtoken)
        .then((response: any) => {
          // const { data = {} } = response;
          // const { accessToken, refreshToken: newRefreshToken } = data;
          //  debugger
          let accessToken = response.data

          if (!accessToken) {
            throw new Error('刷新token失败：未获取到新token')
          }

          // 更新存储的token
          // setToken(accessToken);
          // uni.setStorageSync(appConfig.cache_key.RefreshToken, newRefreshToken);

          setToken(accessToken)
          // userInfo.value.token = response

          // 处理队列中的所有请求
          return processQueue(accessToken)
        })
        .catch((error) => {
          console.log('token刷新失败', error)
          // 通知队列中所有请求失败
          resetQueueAndRefreshState(error || new Error('无效的会话，或者会话已过期，请重新登录'))
          // 显示登录确认对话框
          showLoginConfirm()
          throw error // 继续传递错误
        })
        .finally(() => {
          // 重置刷新状态和Promise引用
          tokenRefreshPromise = null
          isRefreshing = false
        })
    }
  })
}

/**
 * 处理队列中的所有请求
 * @param {String} newToken - 新的访问令牌
 * @returns {Promise} - 返回处理结果
 */
const processQueue = async (newToken) => {
  const currentQueue = [...requestQueue] // 复制当前队列，防止处理过程中队列变化
  requestQueue = [] // 清空队列

  try {
    // 确保token已完全保存后再处理请求
    await new Promise((resolve) => setTimeout(resolve, 50))

    // 依次处理队列中的请求
    const results = await Promise.allSettled(
      currentQueue.map(async ({ resolve, reject, config }) => {
        console.log('222222222222', config)

        try {
          // 更新请求头中的token
          config.header['Bearerauth'] = 'Bearer ' + newToken

          // 重新发起请求
          const result = await requestObj.http({
            ...config,
            retryCount: (config.retryCount || 0) + 1
          })

          // 使用setTimeout确保异步操作完成
          setTimeout(() => resolve(result), 0)
          return result
        } catch (error) {
          console.error('重试请求失败:', error)
          reject(error)
          throw error
        }
      })
    )

    return results
  } catch (error) {
    console.error('队列处理失败:', error)
    throw error
  } finally {
    isRefreshing = false
  }
}

/**
 * 重置队列和刷新状态
 * @param {Error} error - 错误信息
 */
const resetQueueAndRefreshState = (error: any) => {
  // 通知队列中所有请求失败
  requestQueue.forEach(({ reject }) => {
    reject(error)
  })

  // 重置队列和刷新状态
  requestQueue = []
  isRefreshing = false
  tokenRefreshPromise = null
}

/**
 * 显示登录确认对话框
 */
const showLoginConfirm = () => {
  // this.$modal.confirm('确定要退出系统吗？').then(() => {
  //   this.userStore.userlogOut();
  // });
  // showConfirmh('未登录或登录状态过期，您可以继续留在该页面，或者重新登录?').then((res: any) => {
  //   if (res.confirm) {
  //     uni.navigateTo({
  //       url: '/pages/login'
  //     })
  //   }
  // })

  uni.showModal({
    title: '系统提示',
    content: '登录状态过期，您可以继续留在该页面，或者重新登录?',
    cancelText: '取消',
    confirmText: '确定',
    success: function (res) {
      if (res.confirm) {
        uni.reLaunch({
          url: '/pages/login/login'
        })
      }
    }
  })
}
export const request = requestObj
