import type { Paginator } from 'masto'
import type { PaginatorState } from '~/types'

export function usePaginator<T>(paginator: Paginator<any, T[]>) {
  const state = ref<PaginatorState>('idle')
  const items = ref<T[]>([])
  const newItems = ref<T[]>([])

  const endAnchor = ref<HTMLDivElement>()
  const bound = reactive(useElementBounding(endAnchor))
  const isInScreen = $computed(() => bound.top < window.innerHeight * 2)
  const error = ref<unknown | undefined>()

  async function loadNext() {
    if (state.value !== 'idle')
      return

    state.value = 'loading'
    try {
      const result = await paginator.next()

      if (result.value?.length) {
        newItems.value = result.value
        items.value.push(...newItems.value)
        state.value = 'idle'
      }
      else {
        state.value = 'done'
      }
    }
    catch (e) {
      error.value = e
      state.value = 'error'
    }

    await nextTick()
    bound.update()
  }

  useIntervalFn(() => {
    bound.update()
  }, 1000)

  watch(
    () => isInScreen,
    () => {
      if (isInScreen && state.value === 'idle')
        loadNext()
    },
    { immediate: true },
  )

  return {
    items,
    newItems,
    state,
    error,
    endAnchor,
  }
}