import {Stack} from 'expo-router'
import {type ReactNode} from 'react'
import {RefreshControl} from 'react-native'

import {ErrorState} from '@/components/error-state'
import {ListEnd} from '@/components/list-end'
import {Card} from '@/components/ui/card'
import {Layout} from '@/components/ui/layout'
import {infiniteScroll} from '@/lib/scroll'

// the shell for a modal screen that is one framed list: header title +
// scrollable framed card (+ optional paging, pull-to-refresh, toolbar,
// trailing error/footer). the list element (and its props) stays with
// the caller; the shell derives the refresh spinner and end-of-list
// gates from raw loading + itemCount so no caller repeats the formulas
export function ModalListScreen({
  title,
  onEndReached,
  onRefresh,
  loading = false,
  itemCount = 0,
  reachedEnd = false,
  toolbar,
  error,
  footer,
  children,
}: {
  title: string
  onEndReached?: () => void
  onRefresh?: () => void
  loading?: boolean
  itemCount?: number
  reachedEnd?: boolean
  toolbar?: ReactNode
  error?: string | null
  footer?: ReactNode
  children: ReactNode
}) {
  // first load renders the list's own spinner, not the pull-down one
  const refreshing = loading && itemCount > 0
  return (
    <>
      <Stack.Screen options={{title}} />
      {toolbar}
      <Layout.ModalContent
        {...(onEndReached ? infiniteScroll(onEndReached) : {})}
        refreshControl={
          onRefresh ? (
            <RefreshControl
              refreshing={refreshing}
              onRefresh={onRefresh}
            />
          ) : undefined
        }
      >
        <Card>{children}</Card>
        {reachedEnd && itemCount > 0 && <ListEnd />}
        {error != null && <ErrorState message={error} />}
        {footer}
      </Layout.ModalContent>
    </>
  )
}
