"use client";

import { useState } from "react";
import {
  useReactTable,
  getCoreRowModel,
  getFilteredRowModel,
  getPaginationRowModel,
  getSortedRowModel,
  flexRender,
  type ColumnDef,
  type SortingState,
} from "@tanstack/react-table";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import {
  Pagination,
  PaginationContent,
  PaginationEllipsis,
  PaginationItem,
  PaginationLink,
  PaginationNext,
  PaginationPrevious,
} from "@/components/ui/pagination";
import { SearchInput } from "./search-input";
import { cn } from "@/lib/utils";

interface DataTableProps<TData> {
  data: TData[];
  columns: ColumnDef<TData, any>[];
  searchPlaceholder?: string;
  pageSize?: number;
  enableSorting?: boolean;
  emptyMessage?: string;
  onRowClick?: (row: TData) => void;
  summaryText?: (totalCount: number, filteredCount: number) => string;
  filterSlot?: React.ReactNode;
}

export function DataTable<TData>({
  data,
  columns,
  searchPlaceholder,
  pageSize,
  enableSorting = true,
  emptyMessage = "Tidak ada data ditemukan.",
  onRowClick,
  summaryText,
  filterSlot,
}: DataTableProps<TData>) {
  const [globalFilter, setGlobalFilter] = useState("");
  const [sorting, setSorting] = useState<SortingState>([]);

  const table = useReactTable({
    data,
    columns,
    state: { globalFilter, sorting },
    onGlobalFilterChange: setGlobalFilter,
    onSortingChange: setSorting,
    getCoreRowModel: getCoreRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    ...(pageSize ? { getPaginationRowModel: getPaginationRowModel() } : {}),
    ...(enableSorting ? { getSortedRowModel: getSortedRowModel() } : {}),
    ...(pageSize ? { initialState: { pagination: { pageSize } } } : {}),
  });

  const showSearch = !!searchPlaceholder;
  const showFilters = showSearch || !!filterSlot;
  const showPagination = !!pageSize;
  const totalCount = data.length;
  const filteredCount = table.getFilteredRowModel().rows.length;
  const currentPage = table.getState().pagination.pageIndex;
  const totalPages = table.getPageCount();

  /** Hasilkan daftar halaman dengan ellipsis */
  function getPageRange(current: number, total: number): (number | "...")[] {
    if (total <= 7) return Array.from({ length: total }, (_, i) => i);
    if (current <= 3) return [0, 1, 2, 3, "...", total - 1];
    if (current >= total - 4) return [0, "...", total - 4, total - 3, total - 2, total - 1];
    return [0, "...", current - 1, current, current + 1, "...", total - 1];
  }

  return (
    <>
      {/* Filters row */}
      {showFilters && (
        <div className="flex flex-col sm:flex-row gap-3">
          {showSearch && (
            <SearchInput
              value={globalFilter}
              onChange={setGlobalFilter}
              placeholder={searchPlaceholder}
              className={filterSlot ? "flex-1 max-w-sm" : undefined}
            />
          )}
          {filterSlot}
        </div>
      )}

      {/* Table + Pagination dalam satu card */}
      <div className="rounded-xl border bg-card overflow-hidden">
        <Table>
          <TableHeader>
            {table.getHeaderGroups().map((headerGroup) => (
              <TableRow key={headerGroup.id}>
                {headerGroup.headers.map((header) => (
                  <TableHead key={header.id}>
                    {header.isPlaceholder
                      ? null
                      : flexRender(
                          header.column.columnDef.header,
                          header.getContext()
                        )}
                  </TableHead>
                ))}
              </TableRow>
            ))}
          </TableHeader>
          <TableBody>
            {table.getRowModel().rows.length ? (
              table.getRowModel().rows.map((row) => (
                <TableRow
                  key={row.id}
                  onClick={onRowClick ? () => onRowClick(row.original) : undefined}
                  className={cn(onRowClick && "cursor-pointer")}
                >
                  {row.getVisibleCells().map((cell) => (
                    <TableCell key={cell.id}>
                      {flexRender(
                        cell.column.columnDef.cell,
                        cell.getContext()
                      )}
                    </TableCell>
                  ))}
                </TableRow>
              ))
            ) : (
              <TableRow>
                <TableCell
                  colSpan={columns.length}
                  className="h-24 text-center text-muted-foreground"
                >
                  {emptyMessage}
                </TableCell>
              </TableRow>
            )}
          </TableBody>
        </Table>

        {/* Footer pagination — menyatu di dalam card */}
        {(summaryText || showPagination) && (
          <div className="flex items-center justify-between px-4 py-3 d-border-t">
            {/* Summary */}
            <p className="d-text-caption">
              {summaryText
                ? summaryText(totalCount, filteredCount)
                : showPagination
                ? `${filteredCount} data · Halaman ${currentPage + 1} dari ${totalPages}`
                : null}
            </p>

            {/* Pagination */}
            {showPagination && (
              <Pagination>
                <PaginationContent>
                  <PaginationItem>
                    <PaginationPrevious
                      onClick={() => table.previousPage()}
                      disabled={!table.getCanPreviousPage()}
                    />
                  </PaginationItem>

                  {getPageRange(currentPage, totalPages).map((page, i) =>
                    page === "..." ? (
                      <PaginationItem key={`ellipsis-${i}`}>
                        <PaginationEllipsis />
                      </PaginationItem>
                    ) : (
                      <PaginationItem key={page}>
                        <PaginationLink
                          isActive={page === currentPage}
                          onClick={() => table.setPageIndex(page)}
                        >
                          {page + 1}
                        </PaginationLink>
                      </PaginationItem>
                    )
                  )}

                  <PaginationItem>
                    <PaginationNext
                      onClick={() => table.nextPage()}
                      disabled={!table.getCanNextPage()}
                    />
                  </PaginationItem>
                </PaginationContent>
              </Pagination>
            )}
          </div>
        )}
      </div>
    </>
  );
}
