import { useState, useCallback } from 'react'
import type { PageParam, PageResult } from '@/api/index'

interface UsePaginationOptions<T> {
  api: (params: PageParam) => Promise<PageResult<T>>
  defaultParams?: Partial<PageParam>
  pageSize?: number
  immediate?: boolean
}

interface UsePaginationReturn<T> {
  list: T[]
  loading: boolean
  refreshing: boolean
  loadingMore: boolean
  finished: boolean
  total: number
  params: PageParam
  run: (extraParams?: Record<string, any>) => Promise<void>
  refresh: () => Promise<void>
  loadMore: () => Promise<void>
  reset: () => void
  setParams: (params: Partial<PageParam>) => void
}

export function usePagination<T>(options: UsePaginationOptions<T>): UsePaginationReturn<T> {
  const { api, defaultParams = {}, pageSize = 10, immediate = false } = options

  const [list, setList] = useState<T[]>([])
  const [loading, setLoading] = useState(false)
  const [refreshing, setRefreshing] = useState(false)
  const [loadingMore, setLoadingMore] = useState(false)
  const [finished, setFinished] = useState(false)
  const [total, setTotal] = useState(0)
  const [params, setParamsState] = useState<PageParam>({
    page: 1,
    limit: pageSize,
    ...defaultParams,
  })

  const setParams = (newParams: Partial<PageParam>) => {
    setParamsState(prev => ({ ...prev, ...newParams }))
  }

  const fetchData = useCallback(async (page: number, extraParams?: Record<string, any>) => {
    const result = await api({ ...params, ...extraParams, page, limit: pageSize })
    setList(result?.list || [])
    setTotal(result?.count || 0)
    setFinished((result?.list || []).length < pageSize)
    return result
  }, [api, params, pageSize])

  const run = useCallback(async (extraParams?: Record<string, any>) => {
    setLoading(true)
    try {
      await fetchData(1, extraParams)
      setParamsState(prev => ({ ...prev, page: 1 }))
    } catch (error) {
      console.error('Pagination run error:', error)
    } finally {
      setLoading(false)
    }
  }, [fetchData])

  const refresh = useCallback(async () => {
    if (refreshing) return
    setRefreshing(true)
    setFinished(false)
    try {
      await fetchData(1)
      setParamsState(prev => ({ ...prev, page: 1 }))
    } catch (error) {
      console.error('Refresh error:', error)
    } finally {
      setRefreshing(false)
    }
  }, [fetchData, refreshing])

  const loadMore = useCallback(async () => {
    if (loadingMore || finished) return
    setLoadingMore(true)
    try {
      const nextPage = (params.page || 1) + 1
      const result = await api({ ...params, page: nextPage, limit: pageSize })
      const newList = result?.list || []
      setList(prev => [...prev, ...newList])
      setTotal(result?.count || 0)
      setFinished(newList.length < pageSize)
      setParamsState(prev => ({ ...prev, page: nextPage }))
    } catch (error) {
      console.error('LoadMore error:', error)
    } finally {
      setLoadingMore(false)
    }
  }, [api, params, pageSize, loadingMore, finished])

  const reset = useCallback(() => {
    setList([])
    setFinished(false)
    setTotal(0)
    setParamsState(prev => ({ ...prev, page: 1 }))
  }, [])

  // 立即执行
  if (immediate && list.length === 0 && !loading && !refreshing) {
    run()
  }

  return { list, loading, refreshing, loadingMore, finished, total, params, run, refresh, loadMore, reset, setParams }
}
