// data-table.tsx
"use client";

import * as React from "react";
import { Funnel } from "lucide-react";
import {
  ColumnDef,
  flexRender,
  getCoreRowModel,
  getSortedRowModel,
  getPaginationRowModel,
  getFilteredRowModel,
  useReactTable,
  SortingState,
  ColumnFiltersState,
  Table as TanstackTable,
} from "@tanstack/react-table";

import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { Button } from "@/components/ui/button";

// Constants
const DEFAULT_PAGE_SIZE = 15;
const PRIMARY_COLOR = "#428B4D";

interface DataTableProps<TData> {
  columns: ColumnDef<TData, any>[];
  data: TData[];
  pageSize?: number;
}

/**
 * Hook to manage filter visibility with click-outside and scroll handling
 */
function useFilterVisibility(containerRef: React.RefObject<HTMLDivElement | null>) {
  const [visibleFilters, setVisibleFilters] = React.useState<Record<string, boolean>>({});

  const toggleFilter = React.useCallback((columnId: string) => {
    setVisibleFilters((prev) => {
      const isCurrentlyVisible = !!prev[columnId];
      return {
        ...Object.fromEntries(Object.keys(prev).map((key) => [key, false])),
        [columnId]: !isCurrentlyVisible,
      };
    });
  }, []);

  React.useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      const target = event.target as Node;
      if (containerRef.current && containerRef.current.contains(target)) {
        return;
      }
      setVisibleFilters({});
    };

    const handleScroll = () => setVisibleFilters({});

    document.addEventListener("click", handleClickOutside);
    window.addEventListener("scroll", handleScroll, { passive: true });

    return () => {
      document.removeEventListener("click", handleClickOutside);
      window.removeEventListener("scroll", handleScroll);
    };
  }, [containerRef]);

  return { visibleFilters, toggleFilter };
}

/**
 * Filter input component for table columns
 */
interface FilterInputProps {
  value: string;
  onChange: (value: string) => void;
}

function FilterInput({ value, onChange }: FilterInputProps) {
  return (
    <div
      className="absolute left-0 top-full z-20 mt-1 w-52 rounded-lg border border-gray-200 bg-white p-3 shadow-lg ring-1 ring-black/5"
      onClick={(e) => e.stopPropagation()}
    >
      <input
        className="w-full rounded-lg border border-gray-200 bg-white px-2.5 py-1.5 text-xs text-gray-700 shadow-sm placeholder:text-gray-400 focus:border-[#428B4D] focus:outline-none focus:ring-2 focus:ring-[#428B4D]/30"
        type="text"
        value={value}
        onClick={(e) => e.stopPropagation()}
        onChange={(e) => onChange(e.target.value)}
        placeholder="Search..."
      />
    </div>
  );
}

/**
 * Pagination buttons component
 */
interface PaginationButtonsProps<TData> {
  table: TanstackTable<TData>;
}

function PaginationButtons<TData>({ table }: PaginationButtonsProps<TData>) {
  return (
    <div className="flex items-center justify-end gap-2 py-2">
      <Button
        variant="outline"
        size="sm"
        onClick={() => table.previousPage()}
        disabled={!table.getCanPreviousPage()}
        className="rounded-lg border-gray-200 bg-white text-sm font-medium text-slate-600 shadow-sm transition-all hover:border-[#428B4D] hover:bg-[#428B4D]/10 hover:text-[#428B4D] disabled:cursor-not-allowed disabled:border-gray-200 disabled:bg-gray-100 disabled:text-gray-400"
      >
        Previous
      </Button>
      <Button
        variant="outline"
        size="sm"
        onClick={() => table.nextPage()}
        disabled={!table.getCanNextPage()}
        className="rounded-lg border-gray-200 bg-white text-sm font-medium text-slate-600 shadow-sm transition-all hover:border-[#428B4D] hover:bg-[#428B4D]/10 hover:text-[#428B4D] disabled:cursor-not-allowed disabled:border-gray-200 disabled:bg-gray-100 disabled:text-gray-400"
      >
        Next
      </Button>
    </div>
  );
}

export function DataTable<TData>({ columns, data, pageSize = DEFAULT_PAGE_SIZE }: DataTableProps<TData>) {
  const [sorting, setSorting] = React.useState<SortingState>([]);
  const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>([]);
  const containerRef = React.useRef<HTMLDivElement | null>(null);
  const { visibleFilters, toggleFilter } = useFilterVisibility(containerRef);

  const table = useReactTable({
    data,
    columns,
    state: {
      sorting,
      columnFilters,
    },
    onSortingChange: setSorting,
    onColumnFiltersChange: setColumnFilters,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    initialState: {
      pagination: {
        pageSize,
      },
    },
  });

  return (
    <div ref={containerRef} className="flex flex-col space-y-4">
      {/* Table wrapper */}
      <div className="overflow-x-auto rounded-lg border border-gray-200/80 bg-white shadow-sm ring-1 ring-black/5">
        <Table className="min-w-full text-sm">
          {/* Table Header */}
          <TableHeader className="bg-slate-50/80">
        {table.getHeaderGroups().map((headerGroup) => (
          <TableRow key={headerGroup.id}>
            {headerGroup.headers.map((header) => {
              const columnId = header.column.id;
              const showFilter = visibleFilters[columnId];

              return (
                <TableHead
                  key={header.id}
                  className="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-gray-600 cursor-pointer select-none transition-colors hover:bg-white/80"
                  onClick={() => toggleFilter(columnId)}
                >
                  {header.isPlaceholder ? null : (
                    <div className="relative flex flex-col gap-2">
                      {/* Header text + Funnel icon */}
                      <div className="flex items-center justify-between gap-2 text-slate-600">
                        <span className="truncate">
                          {flexRender(
                            header.column.columnDef.header,
                            header.getContext()
                          )}
                        </span>
                        {header.column.getCanFilter() && (
                          <Funnel
                            className="w-4 h-4 text-gray-400 transition-colors hover:text-[#428B4D]"
                            onClick={(e) => {
                              e.stopPropagation();
                              toggleFilter(columnId);
                            }}
                          />
                        )}
                      </div>

                      {/* Filter input */}
                      {header.column.getCanFilter() && showFilter && (
                        <FilterInput
                          value={(header.column.getFilterValue() ?? "") as string}
                          onChange={(value) => header.column.setFilterValue(value)}
                        />
                      )}
                    </div>
                  )}
                </TableHead>
              );
            })}
          </TableRow>
        ))}
      </TableHeader>

      {/* Table Body */}
      <TableBody className="bg-white">
        {table.getRowModel().rows.length > 0 ? (
          table.getRowModel().rows.map((row, rowIndex) => (
            <TableRow
              key={row.id}
              className={`transition-colors ${
                rowIndex % 2 === 0 ? "bg-white" : "bg-slate-50/80"
              } hover:bg-[#428B4D]/10`}
            >
              {row.getVisibleCells().map((cell) => (
                <TableCell
                  key={cell.id}
                  className="px-4 py-3 text-sm text-slate-700"
                >
                  {flexRender(cell.column.columnDef.cell, cell.getContext())}
                </TableCell>
              ))}
            </TableRow>
          ))
        ) : (
          <TableRow>
            <TableCell
              colSpan={columns.length}
              className="h-24 text-center text-gray-400"
            >
              No results.
            </TableCell>
          </TableRow>
        )}
      </TableBody>
    </Table>
  </div>

      {/* Pagination */}
      <PaginationButtons table={table} />
    </div>

  );
}
