import axios from 'axios'
import { showLoadingToast, closeToast, showFailToast } from 'vant'

// 本地服务可用性状态
let localServiceAvailable = true
// 是否已经检查过本地服务
let hasCheckedLocalService = false

// 请求模式枚举
export const RequestMode = {
  LOCAL_ONLY: 'LOCAL_ONLY', // 仅本地请求
  SERVICE_BUS_ONLY: 'SERVICE_BUS_ONLY', // 仅服务总线请求
  BOTH: 'BOTH' // 同时请求本地和服务总线
}

// 服务总线地址配置
const serviceBusConfig = {
  host: '',
  port: '',
  isConfigured: false
}

// 记录请求次数
let requestCount = 0

// 创建本地请求实例
const localRequest = axios.create({
  baseURL: import.meta.env.APP_BASE_API || '/api',
  timeout: Number(import.meta.env.APP_REQUEST_TIMEOUT) || 10000
})

// 创建服务总线请求实例
const serviceBusRequest = axios.create({
  timeout: Number(import.meta.env.APP_REQUEST_TIMEOUT) || 10000
})

// 显示加载提示
const showLoading = () => {
  if (requestCount === 0) {
    showLoadingToast({
      message: '加载中...',
      forbidClick: true,
      duration: 0,
      className: 'loading-toast'
    })
  }
  requestCount++
}

// 隐藏加载提示
const hideLoading = () => {
  requestCount--
  if (requestCount === 0) {
    closeToast()
  }
}

// 显示错误提示
const showError = message => {
  showFailToast({
    message,
    duration: 2000,
    className: 'loading-toast',
    iconSize: '36px'
  })
}

// 设置服务总线配置
export const setServiceBusConfig = (host, port) => {
  if (!host || !port) {
    return false
  }

  serviceBusConfig.host = host
  serviceBusConfig.port = port
  serviceBusConfig.isConfigured = true
  return true
}

// 获取服务总线URL
const getServiceBusUrl = () => {
  return `http://${serviceBusConfig.host}:${serviceBusConfig.port}`
}

// 检查服务总线配置
const checkServiceBusConfig = () => {
  if (!serviceBusConfig.isConfigured) {
    showError('服务总线未配置')
    return false
  }
  return true
}

// 添加本地请求拦截器
localRequest.interceptors.request.use(
  config => {
    showLoading()
    return config
  },
  error => {
    hideLoading()
    return Promise.reject(error)
  }
)

// 添加服务总线请求拦截器
serviceBusRequest.interceptors.request.use(
  config => {
    showLoading()
    // 动态设置服务总线的baseURL
    config.baseURL = getServiceBusUrl()
    return config
  },
  error => {
    hideLoading()
    return Promise.reject(error)
  }
)

// 本地请求响应拦截器
localRequest.interceptors.response.use(
  response => {
    hideLoading()
    return response.data
  },
  error => {
    hideLoading()
    return Promise.reject(error)
  }
)

// 服务总线请求响应拦截器
serviceBusRequest.interceptors.response.use(
  response => {
    hideLoading()
    return response.data
  },
  error => {
    hideLoading()
    return Promise.reject(error)
  }
)

// 处理服务总线请求
const handleServiceBusRequest = async config => {
  if (!checkServiceBusConfig()) {
    return Promise.reject(new Error('服务总线未配置'))
  }

  try {
    return await serviceBusRequest(config)
  } catch (error) {
    showError('服务总线请求失败')
    return Promise.reject(error)
  }
}

// 处理本地请求
const handleLocalRequest = async config => {
  try {
    return await localRequest(config)
  } catch (error) {
    showError('本地请求失败')
    return Promise.reject(error)
  }
}

// 处理BOTH模式请求
const handleBothRequest = async config => {
  const isProduction = import.meta.env.MODE === 'production'

  // 生产环境下，如果已检查过本地服务且不可用，直接走服务总线
  if (isProduction && hasCheckedLocalService && !localServiceAvailable) {
    return handleServiceBusRequest(config)
  }

  try {
    // 尝试本地请求
    const result = await localRequest(config)

    // 在生产环境中标记本地服务可用
    if (isProduction && !hasCheckedLocalService) {
      localServiceAvailable = true
      hasCheckedLocalService = true
    }

    return result
  } catch (error) {
    // 在生产环境中标记本地服务不可用
    if (isProduction && !hasCheckedLocalService) {
      localServiceAvailable = false
      hasCheckedLocalService = true
    }

    // 尝试服务总线
    if (serviceBusConfig.isConfigured) {
      try {
        return await serviceBusRequest(config)
      } catch (busError) {
        showError('本地和服务总线请求均失败')
        return Promise.reject(busError)
      }
    } else {
      showError('本地请求失败且服务总线未配置')
      return Promise.reject(error)
    }
  }
}

// 统一请求方法
const request = async config => {
  // 获取请求模式，默认根据环境决定
  const requestMode = config.requestMode

  // 删除自定义配置，避免传递给axios
  delete config.requestMode

  // 根据请求模式处理
  switch (requestMode) {
    case RequestMode.SERVICE_BUS_ONLY:
      return handleServiceBusRequest(config)

    case RequestMode.LOCAL_ONLY:
      return handleLocalRequest(config)

    case RequestMode.BOTH:
      return handleBothRequest(config)

    default:
      console.warn(`未知的请求模式: ${requestMode}，使用本地请求`)
      return handleLocalRequest(config)
  }
}

// 重置本地服务检查状态
export const resetLocalServiceCheck = () => {
  hasCheckedLocalService = false
  localServiceAvailable = true
}

export default request
