"use client"

import * as React from "react"
import { useMemo, useState } from "react"
import { cn } from "@/lib/utils"

export function usePagination<T>(
  items: T[],
  defaultPageSize = 10,
) {
  const [page, setPageRaw]    = useState(1)
  const [pageSize, setPageSizeRaw] = useState(defaultPageSize)

  const totalPages = Math.max(1, Math.ceil(items.length / pageSize))

  function setPage(p: number) {
    setPageRaw(Math.max(1, Math.min(p, totalPages)))
  }

  function setPageSize(n: number) {
    setPageSizeRaw(n)
    setPageRaw(1)
  }

  function resetPage() { setPageRaw(1) }

  function paginate(list: T[]): T[] {
    return list.slice((page - 1) * pageSize, page * pageSize)
  }

  return { page, pageSize, setPage, setPageSize, resetPage, totalPages, paginate }
}

// ─── types ────────────────────────────────────────────────────────────────────

export interface TablePaginationProps {
  /** Total number of items across all pages */
  total: number
  page: number
  pageSize: number
  totalPages: number
  onPageChange: (page: number) => void
  onPageSizeChange: (size: number) => void
  /** Available page-size options. Defaults to [10, 20, 50] */
  pageSizeOptions?: number[]
  className?: string
}

// ─── TablePagination ──────────────────────────────────────────────────────────

export function TablePagination({
  total,
  page,
  pageSize,
  totalPages,
  onPageChange,
  onPageSizeChange,
  pageSizeOptions = [10, 20, 50],
  className,
}: TablePaginationProps) {
  const from = total === 0 ? 0 : (page - 1) * pageSize + 1
  const to   = Math.min(page * pageSize, total)

  return (
    <div
      className={cn(
        "flex flex-wrap items-center justify-between gap-3 rounded-b-xl border-t bg-card px-4 py-2.5",
        className,
      )}
    >
      {/* left: rows-per-page + range */}
      <div className="flex items-center gap-3">
        <div className="flex items-center gap-1.5">
          <span className="text-xs text-muted-foreground">Rows per page</span>
          <select
            value={pageSize}
            onChange={(e) => onPageSizeChange(Number(e.target.value))}
            className="h-7 rounded-md border border-input bg-background px-2 text-xs font-medium shadow-sm focus:outline-none focus:ring-2 focus:ring-primary/20"
          >
            {pageSizeOptions.map((n) => (
              <option key={n} value={n}>{n}</option>
            ))}
          </select>
        </div>

        <div className="h-4 w-px bg-border" />

        <span className="text-xs text-muted-foreground tabular-nums">
          {from}–{to} of {total}
        </span>
      </div>

      {/* right: nav buttons */}
      <div className="flex items-center gap-1">
        <NavButton onClick={() => onPageChange(1)} disabled={page === 1} label="First page">
          {/* double-chevron left */}
          <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
            <polyline points="11 17 6 12 11 7" /><polyline points="18 17 13 12 18 7" />
          </svg>
        </NavButton>

        <NavButton onClick={() => onPageChange(page - 1)} disabled={page === 1} label="Previous page">
          <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
            <polyline points="15 18 9 12 15 6" />
          </svg>
        </NavButton>

        <PagePills page={page} totalPages={totalPages} onSelect={onPageChange} />

        <NavButton onClick={() => onPageChange(page + 1)} disabled={page === totalPages} label="Next page">
          <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
            <polyline points="9 18 15 12 9 6" />
          </svg>
        </NavButton>

        <NavButton onClick={() => onPageChange(totalPages)} disabled={page === totalPages} label="Last page">
          <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
            <polyline points="13 17 18 12 13 7" /><polyline points="6 17 11 12 6 7" />
          </svg>
        </NavButton>
      </div>
    </div>
  )
}

// ─── NavButton ────────────────────────────────────────────────────────────────

function NavButton({
  onClick, disabled, label, children,
}: { onClick: () => void; disabled: boolean; label: string; children: React.ReactNode }) {
  return (
    <button
      onClick={onClick}
      disabled={disabled}
      aria-label={label}
      className="flex h-7 w-7 items-center justify-center rounded-md border border-input bg-background text-muted-foreground hover:bg-muted hover:text-foreground disabled:pointer-events-none disabled:opacity-40 transition-colors"
    >
      {children}
    </button>
  )
}

// ─── PagePills ────────────────────────────────────────────────────────────────

function PagePills({ page, totalPages, onSelect }: {
  page: number; totalPages: number; onSelect: (p: number) => void
}) {
  const pages = useMemo(() => {
    if (totalPages <= 7) return Array.from({ length: totalPages }, (_, i) => i + 1)
    const set = new Set(
      [1, totalPages, page, page - 1, page + 1].filter((p) => p >= 1 && p <= totalPages)
    )
    const sorted = Array.from(set).sort((a, b) => a - b)
    const result: (number | "…")[] = []
    for (let i = 0; i < sorted.length; i++) {
      if (i > 0 && sorted[i] - sorted[i - 1] > 1) result.push("…")
      result.push(sorted[i])
    }
    return result
  }, [page, totalPages])

  return (
    <>
      {pages.map((p, i) =>
        p === "…" ? (
          <span
            key={`ellipsis-${i}`}
            className="flex h-7 w-6 items-center justify-center text-xs text-muted-foreground select-none"
          >
            …
          </span>
        ) : (
          <button
            key={p}
            onClick={() => onSelect(p)}
            className={cn(
              "flex h-7 min-w-[28px] items-center justify-center rounded-md border px-1.5 text-xs font-medium transition-colors",
              p === page
                ? "border-primary bg-primary text-primary-foreground shadow-sm"
                : "border-input bg-background text-muted-foreground hover:bg-muted hover:text-foreground",
            )}
          >
            {p}
          </button>
        )
      )}
    </>
  )
}