import {useFocusEffect} from 'expo-router'
import {useCallback, useEffect} from 'react'

// the consumer face of a paged store: keyed stores match it directly,
// global ones (whose hooks ignore the id) match it structurally
export type PagedListResource<T> = {
  useItems: (id: string) => T[]
  useLoading: (id: string) => boolean
  useLoadingMore: (id: string) => boolean
  useReachedEnd: (id: string) => boolean
  useError: (id: string) => string | null
  useLoad: () => (id: string) => Promise<void>
  useLoadMore: () => (id: string) => Promise<void>
}

// adapts a paged store into a list screen's moving parts: the mount load
// (or a refetch on every focus, for screens that push editors on top),
// the raw list flags, and ready-to-spread ModalListScreen props
export const usePagedListScreen = <T>(
  resource: PagedListResource<T>,
  id = '',
  {refetchOnFocus = false} = {},
) => {
  const items = resource.useItems(id)
  const loading = resource.useLoading(id)
  const loadingMore = resource.useLoadingMore(id)
  const reachedEnd = resource.useReachedEnd(id)
  const error = resource.useError(id)
  const load = resource.useLoad()
  const loadMore = resource.useLoadMore()

  useEffect(() => {
    if (!refetchOnFocus) void load(id)
  }, [refetchOnFocus, load, id])

  useFocusEffect(
    useCallback(() => {
      if (refetchOnFocus) void load(id)
    }, [refetchOnFocus, load, id]),
  )

  return {
    items,
    loading,
    loadingMore,
    reachedEnd,
    error,
    retry: () => void load(id),
    screenProps: {
      loading,
      itemCount: items.length,
      reachedEnd,
      onRefresh: () => void load(id),
      onEndReached: () => void loadMore(id),
    },
  }
}
