import { type ReactElement } from "react";
import * as React from "react";
import {
  ChevronLeftIcon,
  ChevronRightIcon,
  ChevronsLeftIcon,
  ChevronsRightIcon,
  MoreHorizontalIcon,
} from "lucide-react";
import { cn } from "@/lib/utils";
import { buttonVariants, Button } from "@/components/ui/button";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";

/**
 * Pagination — WealthX Design System
 * Figma: https://www.figma.com/design/9V9F0NGVsif8LGmEhVjOcT/Design-System---shadcn?node-id=73-1981
 *
 * Base: official shadcn pagination (npx shadcn\@latest add pagination)
 * WealthX overrides: none — ghost/outline variants match design system
 */

export type PaginationProps = React.ComponentProps<"nav">;

function Pagination({ className, ...props }: PaginationProps): ReactElement {
  return (
    <nav
      aria-label="pagination"
      className={cn("mx-auto flex w-full justify-center", className)}
      data-slot="pagination"
      role="navigation"
      {...props}
    />
  );
}

export type PaginationContentProps = React.ComponentProps<"ul">;

function PaginationContent({
  className,
  ...props
}: PaginationContentProps): ReactElement {
  return (
    <ul
      className={cn("flex flex-row items-center gap-1", className)}
      data-slot="pagination-content"
      {...props}
    />
  );
}

export type PaginationItemProps = React.ComponentProps<"li">;

function PaginationItem({ ...props }: PaginationItemProps): ReactElement {
  return <li data-slot="pagination-item" {...props} />;
}

export type PaginationLinkProps = {
  isActive?: boolean;
} & Pick<React.ComponentProps<typeof Button>, "size"> &
  React.ComponentProps<"a">;

function PaginationLink({
  className,
  isActive,
  size = "icon",
  ...props
}: PaginationLinkProps): ReactElement {
  return (
    // eslint-disable-next-line jsx-a11y/anchor-has-content -- children passed via props spread
    <a
      aria-current={isActive ? "page" : undefined}
      className={cn(
        buttonVariants({
          variant: isActive ? "outline" : "ghost",
          size,
        }),
        className,
      )}
      data-active={isActive}
      data-slot="pagination-link"
      {...props}
    />
  );
}

export type PaginationPreviousProps = React.ComponentProps<
  typeof PaginationLink
>;

function PaginationPrevious({
  className,
  ...props
}: PaginationPreviousProps): ReactElement {
  return (
    <PaginationLink
      aria-label="Go to previous page"
      className={cn("gap-1 px-2.5 sm:pl-2.5", className)}
      size="default"
      {...props}
    >
      <ChevronLeftIcon />
      <span className="hidden sm:block">Previous</span>
    </PaginationLink>
  );
}

export type PaginationNextProps = React.ComponentProps<typeof PaginationLink>;

function PaginationNext({
  className,
  ...props
}: PaginationNextProps): ReactElement {
  return (
    <PaginationLink
      aria-label="Go to next page"
      className={cn("gap-1 px-2.5 sm:pr-2.5", className)}
      size="default"
      {...props}
    >
      <span className="hidden sm:block">Next</span>
      <ChevronRightIcon />
    </PaginationLink>
  );
}

export type PaginationEllipsisProps = React.ComponentProps<"span">;

function PaginationEllipsis({
  className,
  ...props
}: PaginationEllipsisProps): ReactElement {
  return (
    <span
      aria-hidden
      className={cn("flex size-9 items-center justify-center", className)}
      data-slot="pagination-ellipsis"
      {...props}
    >
      <MoreHorizontalIcon className="size-4" />
      <span className="sr-only">More pages</span>
    </span>
  );
}

export type PaginationNavButtonsProps = {
  hasPrev: boolean;
  hasNext: boolean;
  onFirst: () => void;
  onPrev: () => void;
  onNext: () => void;
  onLast: () => void;
};

function PaginationNavButtons({
  hasPrev,
  hasNext,
  onFirst,
  onPrev,
  onNext,
  onLast,
}: PaginationNavButtonsProps): ReactElement {
  return (
    <div className="flex items-center gap-1">
      <Button
        aria-label="Go to first page"
        disabled={!hasPrev}
        onClick={onFirst}
        size="icon-sm"
        variant="outline"
      >
        <ChevronsLeftIcon className="size-4" />
      </Button>
      <Button
        aria-label="Go to previous page"
        disabled={!hasPrev}
        onClick={onPrev}
        size="icon-sm"
        variant="outline"
      >
        <ChevronLeftIcon className="size-4" />
      </Button>
      <Button
        aria-label="Go to next page"
        disabled={!hasNext}
        onClick={onNext}
        size="icon-sm"
        variant="outline"
      >
        <ChevronRightIcon className="size-4" />
      </Button>
      <Button
        aria-label="Go to last page"
        disabled={!hasNext}
        onClick={onLast}
        size="icon-sm"
        variant="outline"
      >
        <ChevronsRightIcon className="size-4" />
      </Button>
    </div>
  );
}

export type TablePaginationProps = {
  page: number;
  pageCount: number;
  pageSize: number;
  pageSizeOptions?: number[];
  onPageChange: (page: number) => void;
  onPageSizeChange: (pageSize: number) => void;
  selectedCount?: number;
  totalCount?: number;
  className?: string;
};

function TablePagination({
  page,
  pageCount,
  pageSize,
  pageSizeOptions = [10, 20, 30, 50],
  onPageChange,
  onPageSizeChange,
  selectedCount,
  totalCount,
  className,
}: TablePaginationProps): ReactElement {
  return (
    <div
      className={cn("flex items-center gap-4 py-4", className)}
      data-slot="table-pagination"
    >
      {selectedCount != null && selectedCount > 0 && totalCount != null && (
        <span className="text-body-small text-muted-foreground">
          {selectedCount} of {totalCount} row(s) selected.
        </span>
      )}

      <div className="ml-auto flex items-center gap-6">
        <div className="flex items-center gap-2">
          <span className="text-body-small text-muted-foreground whitespace-nowrap">
            Rows per page
          </span>
          <Select
            onValueChange={(value) => onPageSizeChange(Number(value))}
            value={`${pageSize}`}
          >
            <SelectTrigger
              aria-label="Rows per page"
              className="w-[70px]"
              size="sm"
            >
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              {pageSizeOptions.map((size) => (
                <SelectItem key={size} value={`${size}`}>
                  {size}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>

        <span className="text-body-small text-muted-foreground whitespace-nowrap">
          Page {page} of {pageCount}
        </span>

        <PaginationNavButtons
          hasNext={page < pageCount}
          hasPrev={page > 1}
          onFirst={() => onPageChange(1)}
          onLast={() => onPageChange(pageCount)}
          onNext={() => onPageChange(page + 1)}
          onPrev={() => onPageChange(page - 1)}
        />
      </div>
    </div>
  );
}

export {
  Pagination,
  PaginationContent,
  PaginationLink,
  PaginationItem,
  PaginationPrevious,
  PaginationNext,
  PaginationEllipsis,
  PaginationNavButtons,
  TablePagination,
};
