import { ref } from 'vue'
import { onPageScroll, onReachBottom } from '@dcloudio/uni-app'
import useMescroll from '@/uni_modules/mescroll-uni/hooks/useMescroll.js'

interface UseListLoaderOptions {
  apiFn: (params: EmptyObjectType, ...args: any[]) => Promise<any>
  initialParams?: EmptyObjectType
  getApiParams?: () => any[]
}

interface UseListLoaderReturn {
  listData: any
  params: EmptyObjectType
  totalCount: EmptyObjectType
  extend: any
  handleSearch: () => void
  upCallback: (mescroll: any) => Promise<void>
  downCallback: () => void
  mescrollInit: (mescroll: any) => void
  getMescroll: () => any
  updateApiParams: (callback: () => any[]) => void
}

export const useListLoader = ({ apiFn, initialParams = {}, getApiParams = () => [] }: UseListLoaderOptions): UseListLoaderReturn => {
  const { mescrollInit, downCallback, getMescroll } = useMescroll(onPageScroll, onReachBottom)

  const listData = ref<EmptyObjectType[]>([])
  const params = ref(initialParams)
  const apiParamsGetter = ref(getApiParams)
  const totalCount = ref(0)
  const extend = ref<any>({})

  // 获取列表数据
  const upCallback = async (mescroll: { num: number; size: number; endErr: () => void; endBySize: (length: number, total: number) => void }) => {
    const query: PageQuery = {
      pageNum: mescroll.num,
      pageSize: mescroll.size,
      ...params.value
    }

    try {
      // 调用getter函数获取最新的参数
      const apiParams = apiParamsGetter.value()
      const res = await apiFn(query, ...apiParams)
      const curPageData: any = res.rows || []

      if (mescroll.num === 1) {
        listData.value = []
      }

      listData.value = listData.value.concat(curPageData)
      totalCount.value = res.total
      extend.value = res.extend
      mescroll.endBySize(curPageData.length, res.total)
    } catch {
      mescroll.endErr() // 请求失败, 结束加载
    }
  }

  // 查询/重置搜索
  const handleSearch = () => {
    listData.value = []
    getMescroll().resetUpScroll()
  }

  // 更新apiParams的getter函数
  const updateApiParams = (callback: () => any[]) => {
    apiParamsGetter.value = callback
  }

  return {
    listData,
    extend,
    params,
    totalCount,
    handleSearch,
    upCallback,
    downCallback,
    mescrollInit,
    getMescroll,
    updateApiParams
  }
}
