import { Ref, onMounted, ref } from 'vue'

import type { PaginationData } from '@/types/api'

export interface UsePageListOptions<T> {
  query: (
    currentPage: number,
    pageSize: number,
    statusCode?: number,
  ) => Promise<PaginationData<T>>
  initPageSize?: number
  statistics?: boolean
  initLoad?: boolean
}

export default function usePageList<T>(options: UsePageListOptions<T>) {
  const loading = ref(true)
  const currentPage = ref(1)
  const pageSize = ref(options.initPageSize || 100)
  const total = ref(0)
  const data = ref<T[]>([]) as Ref<T[]>
  const statistics = ref(options.statistics || false)
  const totalData = ref({
    sumShipmentNum: 0,
    sumPassNum: 0,
    sumTotalPrice: 0,
    sumNotPassNum: 0,
  })
  /** 防止快速切换查询条件时，旧请求晚返回覆盖新数据 */
  const loadRequestId = ref(0)
  const loadData = async () => {
    const { query } = options
    const myId = ++loadRequestId.value
    try {
      loading.value = true
      const res = await query(currentPage.value, pageSize.value)
      if (myId !== loadRequestId.value) return
      if (statistics.value) {
        totalData.value = res as never
        total.value = res.page!.total
        currentPage.value = res.page!.current
        pageSize.value = res.page!.size
        data.value = res.page!.records
      } else {
        total.value = res.total
        currentPage.value = res.current
        pageSize.value = res.size
        data.value = res.records
      }
    } catch (error) {
      if (myId !== loadRequestId.value) return
      console.error(error)
      // showError(error)
    } finally {
      if (myId === loadRequestId.value) {
        loading.value = false
      }
    }
  }

  const onCurrentPageChange = (page: number) => {
    currentPage.value = page
    loadData()
  }

  const refresh = (reset?: boolean) => {
    if (reset) {
      data.value = []
      total.value = 0
    }
    currentPage.value = 1
    loadData()
  }

  const onPageSizeChange = (newPageSize: number) => {
    pageSize.value = newPageSize
    refresh()
  }

  onMounted(() => {
    if (options.initLoad !== false) {
      refresh()
    }
  })

  return {
    loading,
    currentPage,
    totalData,
    pageSize,
    total,
    data,
    onCurrentPageChange,
    onPageSizeChange,
    refresh,
  }
}
