import Taro from '@tarojs/taro'
import { hc } from 'hono/client'
import { ResponsePolyfill } from './response-polyfill'

// 刷新token的函数
let isRefreshing = false
let refreshSubscribers: ((token: string) => void)[] = []

// 执行token刷新
const refreshToken = async (): Promise<string | null> => {
  if (isRefreshing) {
    // 如果已经在刷新，等待结果
    return new Promise((resolve) => {
      refreshSubscribers.push((token) => {
        resolve(token)
      })
    })
  }

  isRefreshing = true
  try {
    const refreshToken = Taro.getStorageSync('enterprise_refresh_token')
    if (!refreshToken) {
      throw new Error('未找到刷新token')
    }

    // 调用刷新token接口
    const response = await Taro.request({
      url: `${process.env.TARO_APP_API_BASE_URL || 'http://localhost:3000'}/api/v1/yongren/auth/refresh-token`,
      method: 'POST',
      header: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${refreshToken}`
      }
    })

    if (response.statusCode === 200) {
      const { token, refresh_token: newRefreshToken } = response.data
      Taro.setStorageSync('enterprise_token', token)
      if (newRefreshToken) {
        Taro.setStorageSync('enterprise_refresh_token', newRefreshToken)
      }

      // 通知所有等待的请求
      refreshSubscribers.forEach(callback => callback(token))
      refreshSubscribers = []
      return token
    } else {
      throw new Error('刷新token失败')
    }
  } catch (error) {
    console.error('刷新token失败:', error)
    // 清除token，跳转到登录页
    Taro.removeStorageSync('enterprise_token')
    Taro.removeStorageSync('enterprise_refresh_token')
    Taro.removeStorageSync('enterpriseUserInfo')

    // 跳转到登录页
    Taro.showToast({
      title: '登录已过期，请重新登录',
      icon: 'none'
    })
    setTimeout(() => {
      Taro.redirectTo({
        url: '/pages/login/index'
      })
    }, 1500)

    return null
  } finally {
    isRefreshing = false
  }
}

// API配置
const API_BASE_URL = process.env.TARO_APP_API_BASE_URL || 'http://localhost:3000'

// 完整的API地址
// const BASE_URL = `${API_BASE_URL}/api/${API_VERSION}`

// 创建自定义fetch函数，适配Taro.request，支持token自动刷新
const taroFetch: any = async (input, init) => {
  const url = typeof input === 'string' ? input : input.url
  const method = init.method || 'GET'

  const requestHeaders: Record<string, string> = init.headers;

  const keyOfContentType = Object.keys(requestHeaders).find(item => item.toLowerCase() === 'content-type')
  if (!keyOfContentType) {
    requestHeaders['content-type'] = 'application/json'
  }

  // 构建Taro请求选项
  const options: Taro.request.Option = {
    url,
    method: method as any,
    data: init.body,
    header: requestHeaders
  }

  // 添加token - 优先使用企业token，兼容mini_token
  let token = Taro.getStorageSync('enterprise_token')
  if (!token) {
    token = Taro.getStorageSync('mini_token')
  }
  if (token) {
    options.header = {
      ...options.header,
      'Authorization': `Bearer ${token}`
    }
  }

  // 发送请求
  const sendRequest = async (): Promise<any> => {
    try {
      console.log('API请求:', options.url)
      const response = await Taro.request(options)

      const responseHeaders = response.header;

      // 处理204 No Content响应，不设置body
      const body = response.statusCode === 204
        ? null
        : responseHeaders['content-type']!.includes('application/json')
          ? JSON.stringify(response.data)
          : response.data;

      return new ResponsePolyfill(
        body,
        {
          status: response.statusCode,
          statusText: response.errMsg || 'OK',
          headers: responseHeaders
        }
      )
    } catch (error) {
      console.error('API Error:', error)
      throw error
    }
  }

  try {
    let response = await sendRequest()

    // 检查是否为401错误，尝试刷新token
    if (response.status === 401 && token) {
      console.log('检测到401错误，尝试刷新token...')
      const newToken = await refreshToken()

      if (newToken) {
        // 更新请求header中的token
        options.header = {
          ...options.header,
          'Authorization': `Bearer ${newToken}`
        }

        // 重试原始请求
        response = await sendRequest()
      } else {
        // 刷新失败，返回原始401响应
        return response
      }
    }

    return response
  } catch (error) {
    console.error('API请求失败:', error)
    Taro.showToast({
      title: error.message || '网络错误',
      icon: 'none'
    })
    throw error
  }
}

// 创建Hono RPC客户端
export const rpcClient = <T extends any>(apiBasePath?: string) => {
  // @ts-ignore
  return hc<T>(`${API_BASE_URL}${apiBasePath}`, {
    fetch: taroFetch
  })
}