/*
 * @Author: wyd
 * @Date: 2024-02
 * @LastEditors: wyd
 * @LastEditTime: 2024-08
 * @Description: 请求拦截
 */

import { createPinia } from 'pinia'
import { user } from '@/stores/modules/user'
import qs from 'qs'
import { useGlobal } from '@/composables'

const baseUrl = import.meta.env.VITE_BASE_URL
const pinia = createPinia()
const userStore = user(pinia)

// 添加标志变量，用于跟踪是否已经处理过401错误
let is401Handled = false

// 请求拦截
const httpInterceptor = {
  invoke(options: UniApp.RequestOptions) {
    if (options.url.indexOf('https://') === -1 && options.url.indexOf('http://') === -1) {
      options.url = baseUrl + options.url
    }
    // 超时时长
    options.timeout = 60000
    options.header = {
      ...options.header,
      Type: 'weixin'
    }

    const userInfo = uni.getStorageSync('user')
    const token = userInfo ? JSON.parse(userInfo).token : ''
    if (token) {
      options.header.Authorization = 'Bearer ' + token
    }
    options.header['content-language'] = 'zh_CN'
    const systemInfo = uni.getStorageSync('system')
    const parkIds = systemInfo ? JSON.parse(systemInfo).parkIds : ''
    const enterpriseId = userInfo ? JSON.parse(userInfo).enterpriseId : ''
    if (enterpriseId) {
      options.header.Enterpriseid = enterpriseId
    }
    if (parkIds) {
      options.header.Park = parkIds.join(',')
    }
    // GET请求序列化处理，解决传数组问题
    if (options.method === 'GET' && options.data) {
      const newData = qs.stringify(options.data, { indices: false })
      delete options.data
      if (options.url.includes('?')) {
        options.url = `${options.url}&${newData}`
      } else {
        options.url = `${options.url}?${newData}`
      }
    }
    // POST请求传数组处理
    if (options.method === 'POST' && options.header['Content-Type'] === 'application/x-www-form-urlencoded') {
      options.data = qs.stringify(options.data, { indices: false })
    }
  }
}

uni.addInterceptor('request', httpInterceptor)
uni.addInterceptor('uploadFile', httpInterceptor)

// 响应函数
type ListItem<T> = {
  /* 数据list */
  rows: EmptyArrayType<T>
  /* 当前页码 */
  current: number
  /* 每页数量 */
  size: number
  /* 总页数 */
  total: number
  /* 扩展字段 */
  extend: T
}
type Data<T> = ListItem<T> & {
  code: number
  msg: string
  data: T
}

export const http = <T>(options: UniApp.RequestOptions) => {
  return new Promise<Data<T>>((resolve, reject) => {
    uni.request({
      ...options,
      // 请求成功
      success: (res) => {
        uni.hideLoading()
        setTimeout(() => {
          if (
            ((res.data as Data<T>).code >= 200 && (res.data as Data<T>).code < 300) ||
            (res.data as Data<T>).code === 409 ||
            (res?.statusCode == 200 && !(res.data as Data<T>).code)
          ) {
            resolve(res.data as Data<T>)
          } else if ((res.data as Data<T>).code === 401 && !is401Handled) {
            // 只有当is401Handled为false时才处理401错误
            is401Handled = true
            // 登录失效，清除用户信息
            uni.clearStorageSync()
            uni.navigateTo({ url: '/base/login' })
            userStore.clearInfo()
            // 重置标志变量，以便下一次会话可以正常处理401
            setTimeout(() => {
              is401Handled = false
            }, 3000)
            reject(res)
          } else {
            // 对于已经处理过的401错误，只拒绝Promise而不执行跳转
            if ((res.data as Data<T>).code === 401) {
              reject(res)
            } else {
              uni.showToast({
                icon: 'none',
                title: (res.data as Data<T>).msg || '请求错误',
                duration: 3000
              })
              reject(res)
            }
          }
        }, 100)
      },
      // 请求失败
      fail: (err) => {
        uni.hideLoading()
        setTimeout(() => {
          uni.showToast({
            icon: 'none',
            title: '网络错误，请重试',
            duration: 3000
          })
          reject(err)
        }, 100)
      }
    })
  })
}
