import Box from '../box'
import { useStyleConfig, vui, VuiComponent } from '../core'
import { cs, isJsx, runIfFn } from '../utils'
import { PaginationProvider } from './context'
import { PaginationProps } from './pagination.types'
import PaginationButton from './paginationButton'
import PaginationEllipsis from './paginationEllipsis'
import PaginationGoToPage from './paginationGoToPage'
import PaginationNavigation from './paginationNavigation'
import PaginationPrevNext from './paginationPrevNext'
import PaginationResults from './paginationResults'
import usePagination from './usePagination'

/**
 * Displays page navigation buttons together with page and item count.
 * GoToPage component is shown automatically above 10 pages.
 */
export const Pagination = vui<'div', PaginationProps>((props, ref) => {
  const {
    children,
    className,
    count,
    defaultPage,
    goToPage,
    items: itemsProp = [],
    navigation,
    onPageChange,
    page: pageProp,
    pageSize,
    results,
    size,
    variant,
    ...rest
  } = props
  const styles = useStyleConfig('Pagination', props)
  const { items = itemsProp, ...paginationProps } = usePagination({
    count,
    defaultPage,
    onPageChange,
    page: pageProp,
    pageSize,
  })

  const context = { ...paginationProps, items, size, variant }

  return (
    <PaginationProvider value={context}>
      <Box
        centerV
        className={cs('vui-pagination', className)}
        gap={3}
        ref={ref}
        w={1}
        wrap
        {...styles.container}
        {...rest}
      >
        {runIfFn(children, context) ?? (
          <>
            {isJsx(results) ? results : <PaginationResults />}

            {isJsx(navigation) ? navigation : <PaginationNavigation ml="auto" />}

            {isJsx(goToPage) ? goToPage : paginationProps.pageCount > 10 && <PaginationGoToPage />}
          </>
        )}
      </Box>
    </PaginationProvider>
  )
}) as VuiComponent<'div', PaginationProps> & {
  Button: typeof PaginationButton
  Ellipsis: typeof PaginationEllipsis
  GoToPage: typeof PaginationGoToPage
  Navigation: typeof PaginationNavigation
  PrevNext: typeof PaginationPrevNext
  Results: typeof PaginationResults
}

Pagination.Button = PaginationButton
Pagination.Ellipsis = PaginationEllipsis
Pagination.GoToPage = PaginationGoToPage
Pagination.Navigation = PaginationNavigation
Pagination.PrevNext = PaginationPrevNext
Pagination.Results = PaginationResults
Pagination.displayName = 'Pagination'

export default Pagination
