import { ref, computed, type Ref } from 'vue'

export interface FetchOptions<T = any> {
  // 是否立即执行
  immediate?: boolean
  // 是否显示加载状态
  showLoading?: boolean
  // 加载提示文字
  loadingText?: string
  // 是否显示错误提示
  showError?: boolean
  // 错误提示文字
  errorText?: string
  // 重试次数
  retryCount?: number
  // 重试延迟
  retryDelay?: number
}

export interface FetchResult<T = any> {
  data: Ref<T | null>
  loading: Ref<boolean>
  error: Ref<string | null>
  execute: (...args: any[]) => Promise<T>
  refresh: () => Promise<T>
  reset: () => void
}

export function useDataFetch<T = any>(
  fetchFn: (...args: any[]) => Promise<T>,
  options: FetchOptions<T> = {},
): FetchResult<T> {
  const {
    immediate = false,
    showLoading = true,
    loadingText = '加载中...',
    showError = true,
    errorText = '加载失败',
    retryCount = 0,
    retryDelay = 1000,
  } = options

  const data = ref<T | null>(null) as Ref<T | null>
  const loading = ref(false)
  const error = ref<string | null>(null)
  const retryTimes = ref(0)

  // 是否正在重试
  const isRetrying = computed(() => retryTimes.value > 0)

  // 执行数据获取
  const execute = async (...args: any[]): Promise<T> => {
    if (loading.value) return data.value as T

    loading.value = true
    error.value = null

    if (showLoading) {
      uni.showLoading({
        title: loadingText,
        mask: true,
      })
    }

    try {
      const result = await fetchFn(...args)
      data.value = result
      retryTimes.value = 0
      return result
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : String(err)
      error.value = errorMessage

      if (showError) {
        uni.showToast({
          title: errorText,
          icon: 'error',
          duration: 2000,
        })
      }

      // 重试逻辑
      if (retryTimes.value < retryCount) {
        retryTimes.value++
        await new Promise((resolve) => setTimeout(resolve, retryDelay))
        return execute(...args)
      }

      throw err
    } finally {
      loading.value = false
      if (showLoading) {
        uni.hideLoading()
      }
    }
  }

  // 刷新数据
  const refresh = async (): Promise<T> => {
    return execute()
  }

  // 重置状态
  const reset = () => {
    data.value = null
    loading.value = false
    error.value = null
    retryTimes.value = 0
  }

  // 立即执行
  if (immediate) {
    execute()
  }

  return {
    data,
    loading,
    error,
    execute,
    refresh,
    reset,
  }
}
