"use client"

import type { ComponentProps } from "react"
import { useMemo } from "react"
import { useTranslations } from "next-intl"

import {
  Pagination,
  PaginationContent,
  PaginationEllipsis,
  PaginationItem,
  PaginationLink,
  PaginationNext,
  PaginationPrevious,
} from "@/components/ui/pagination"
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
import { Field, FieldLabel } from "@/components/ui/field"
import { getPaginationRange } from "@/lib/pagination-range"
import { cn } from "@/lib/utils"

const DEFAULT_PER_PAGE_OPTIONS = [10, 15, 25, 50, 100] as const

export type DataTablePaginationProps = {
  page: number
  lastPage: number
  perPage: number
  onPageChange: (page: number) => void
  onPerPageChange: (perPage: number) => void
  disabled?: boolean
  perPageOptions?: readonly number[]
  showRowsPerPage?: boolean
  className?: string
}

function pageLinkProps(
  disabled: boolean,
  onNavigate: () => void
): Pick<
  ComponentProps<typeof PaginationLink>,
  "href" | "onClick" | "aria-disabled" | "tabIndex"
> {
  if (disabled) {
    return {
      href: "#",
      "aria-disabled": true,
      tabIndex: -1,
      onClick: (e) => e.preventDefault(),
    }
  }
  return {
    href: "#",
    onClick: (e) => {
      e.preventDefault()
      onNavigate()
    },
  }
}

export function DataTablePagination({
  page,
  lastPage,
  perPage,
  onPageChange,
  onPerPageChange,
  disabled = false,
  perPageOptions = DEFAULT_PER_PAGE_OPTIONS,
  showRowsPerPage = true,
  className,
}: DataTablePaginationProps) {
  const tc = useTranslations("Common")
  const safeLastPage = Math.max(1, lastPage)
  const pageItems = useMemo(
    () => getPaginationRange(page, safeLastPage),
    [page, safeLastPage]
  )

  const perPageValue = String(perPage)

  return (
    <div
      className={cn(
        "flex flex-wrap items-center justify-end gap-3",
        className
      )}
    >
      {showRowsPerPage ? (
        <Field orientation="horizontal" className="w-fit">
          <FieldLabel htmlFor="data-table-rows-per-page">
            {tc("labels.rowsPerPage")}
          </FieldLabel>
          <Select
            value={perPageValue}
            disabled={disabled}
            onValueChange={(value) => onPerPageChange(Number(value))}
          >
            <SelectTrigger className="w-20" id="data-table-rows-per-page">
              <SelectValue />
            </SelectTrigger>
            <SelectContent align="start">
              <SelectGroup>
                {perPageOptions.map((option) => (
                  <SelectItem key={option} value={String(option)}>
                    {option}
                  </SelectItem>
                ))}
              </SelectGroup>
            </SelectContent>
          </Select>
        </Field>
      ) : null}

      <Pagination className="mx-0 w-auto">
        <PaginationContent>
          <PaginationItem>
            <PaginationPrevious
              text={tc("actions.previous")}
              {...pageLinkProps(disabled || page <= 1, () =>
                onPageChange(Math.max(1, page - 1))
              )}
              className={cn(disabled || page <= 1 ? "pointer-events-none opacity-50" : undefined)}
            />
          </PaginationItem>

          {pageItems.map((item, index) =>
            item === "ellipsis" ? (
              <PaginationItem key={`ellipsis-${index}`}>
                <PaginationEllipsis />
              </PaginationItem>
            ) : (
              <PaginationItem key={item}>
                <PaginationLink
                  isActive={item === page}
                  {...pageLinkProps(disabled, () => onPageChange(item))}
                  className={cn(disabled ? "pointer-events-none opacity-50" : undefined)}
                >
                  {item}
                </PaginationLink>
              </PaginationItem>
            )
          )}

          <PaginationItem>
            <PaginationNext
              text={tc("actions.next")}
              {...pageLinkProps(disabled || page >= safeLastPage, () =>
                onPageChange(Math.min(safeLastPage, page + 1))
              )}
              className={cn(
                disabled || page >= safeLastPage ? "pointer-events-none opacity-50" : undefined
              )}
            />
          </PaginationItem>
        </PaginationContent>
      </Pagination>
    </div>
  )
}
