import React from 'react'
import { cn } from '../../utils/cn'
import {
  getPaginationControlsState,
  getPaginationDisplayState,
  type PaginationPageControlMode,
} from './pagination.shared'
import { PaginationControls } from './PaginationControls'
import { PaginationDisplay } from './PaginationDisplay'

export interface PaginationProps {
  /** Zero-based page index for navigation and the `Page N` label. */
  pageIndex: number
  /** Called when the user moves to a different page. */
  onPageChange: (pageIndex: number) => void

  /** Needed when totalCount is unknown so the next arrow can still be enabled. */
  canNextPage?: boolean
  /** Temporarily disables pagination interaction while data is loading. */
  isLoading?: boolean

  /** Needed with currentPageCount to render `Showing X to Y`, and with totalCount to derive select options. */
  pageSize?: number
  /** Needed with pageSize to render `Showing X to Y` when totalCount is unknown. */
  currentPageCount?: number
  /** Enables `of Z` in the range display and page selection when paired with pageSize. */
  totalCount?: number
  /** `select` shows a dropdown when possible; `display` keeps a static `Page N` label. */
  pageControlMode?: PaginationPageControlMode
  /** Hides the left-side `Showing X to Y` text while preserving pagination layout. */
  showPaginationDisplay?: boolean
  className?: string
}

export function Pagination({
  pageIndex,
  pageSize,
  totalCount,
  currentPageCount,
  canNextPage: canNextPageProp,
  isLoading = false,
  onPageChange,
  pageControlMode: pageControlModeProp,
  showPaginationDisplay = true,
  className,
}: PaginationProps) {
  const currentResolvedProps = {
    pageIndex,
    pageSize,
    totalCount,
    currentPageCount,
    canNextPage: canNextPageProp,
    pageControlMode: pageControlModeProp,
  }
  const stableResolvedPropsRef = React.useRef(currentResolvedProps)

  React.useEffect(() => {
    if (!isLoading) {
      stableResolvedPropsRef.current = currentResolvedProps
    }
  }, [
    isLoading,
    pageIndex,
    pageSize,
    totalCount,
    currentPageCount,
    canNextPageProp,
    pageControlModeProp,
  ])

  const resolvedProps = isLoading
    ? stableResolvedPropsRef.current
    : currentResolvedProps

  const { canRenderDisplay } = getPaginationDisplayState(resolvedProps)
  const { canRenderControls } = getPaginationControlsState(resolvedProps)

  if (!canRenderControls) return null

  return (
    <div
      className={cn(
        'mt-4 flex w-full items-center gap-2',
        showPaginationDisplay && canRenderDisplay
          ? 'justify-between'
          : 'justify-end',
        className,
      )}
    >
      {showPaginationDisplay && canRenderDisplay && (
        <PaginationDisplay
          pageIndex={resolvedProps.pageIndex}
          pageSize={resolvedProps.pageSize}
          totalCount={resolvedProps.totalCount}
          currentPageCount={resolvedProps.currentPageCount}
          isLoading={isLoading}
        />
      )}
      <PaginationControls
        pageIndex={resolvedProps.pageIndex}
        onPageChange={onPageChange}
        canNextPage={resolvedProps.canNextPage}
        pageSize={resolvedProps.pageSize}
        totalCount={resolvedProps.totalCount}
        pageControlMode={resolvedProps.pageControlMode}
        isLoading={isLoading}
      />
    </div>
  )
}
