'use client';

import * as React from 'react';
import {
  ColumnDef,
  ColumnFiltersState,
  SortingState,
  flexRender,
  getCoreRowModel,
  getFilteredRowModel,
  getPaginationRowModel,
  getSortedRowModel,
  useReactTable,
  PaginationState,
  OnChangeFn,
  Row,
  RowSelectionState,
  VisibilityState,
} from '@tanstack/react-table';

import { DataTablePagination } from './DataTablePagination';
import { DataTableToolbar, ToolbarFilterConfig, ExportConfig } from './DataTableToolbar';

interface DataTableProps<TData, TValue> {
  columns: ColumnDef<TData, TValue>[];
  data: TData[];
  loading?: boolean;
  searchPlaceholder?: string;
  filters?: ToolbarFilterConfig[];
  renderAdditionalActions?: () => React.ReactNode;
  emptyStateTitle?: string;
  emptyStateDescription?: string;

  // Opt-in toolbar features (default off — no change for existing usages)
  collapsibleFilters?: boolean;
  enableColumnVisibility?: boolean;
  exportConfig?: ExportConfig;
  compact?: boolean;
  initialColumnVisibility?: VisibilityState;
  
  // Optional pagination controls (for server-side/API support)
  pageCount?: number;
  controlledPagination?: PaginationState;
  onPaginationChange?: OnChangeFn<PaginationState>;

  // Optional sorting controls
  controlledSorting?: SortingState;
  onSortingChange?: OnChangeFn<SortingState>;

  // Optional filter controls
  controlledGlobalFilter?: string;
  onGlobalFilterChange?: (value: string) => void;
  controlledColumnFilters?: ColumnFiltersState;
  onColumnFiltersChange?: OnChangeFn<ColumnFiltersState>;

  // Optional row selection (checkboxes) — boolean, or a per-row predicate
  enableRowSelection?: boolean | ((row: Row<TData>) => boolean);
  rowSelection?: RowSelectionState;
  onRowSelectionChange?: OnChangeFn<RowSelectionState>;
  getRowId?: (row: TData, index: number) => string;
}

export function DataTable<TData, TValue>({
  columns,
  data,
  loading = false,
  searchPlaceholder = 'Search records...',
  filters = [],
  renderAdditionalActions,
  emptyStateTitle = 'No Records Found',
  emptyStateDescription = 'Try adjusting your filters or search terms to find what you are looking for.',

  collapsibleFilters = false,
  enableColumnVisibility = false,
  exportConfig,
  compact = false,
  initialColumnVisibility,

  pageCount,
  controlledPagination,
  onPaginationChange,
  
  controlledSorting,
  onSortingChange,

  controlledGlobalFilter,
  onGlobalFilterChange,
  controlledColumnFilters,
  onColumnFiltersChange,

  enableRowSelection = false,
  rowSelection,
  onRowSelectionChange,
  getRowId,
}: DataTableProps<TData, TValue>) {
  // Local state as fallback if not controlled from outside
  const [localSorting, setLocalSorting] = React.useState<SortingState>([]);
  const [localColumnFilters, setLocalColumnFilters] = React.useState<ColumnFiltersState>([]);
  const [localGlobalFilter, setLocalGlobalFilter] = React.useState<string>('');
  const [localRowSelection, setLocalRowSelection] = React.useState<RowSelectionState>({});
  const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>(
    initialColumnVisibility ?? {},
  );
  const [localPagination, setLocalPagination] = React.useState<PaginationState>({
    pageIndex: 0,
    pageSize: 10,
  });

  const table = useReactTable({
    data,
    columns,
    pageCount: pageCount,
    state: {
      sorting: controlledSorting ?? localSorting,
      columnFilters: controlledColumnFilters ?? localColumnFilters,
      globalFilter: controlledGlobalFilter ?? localGlobalFilter,
      pagination: controlledPagination ?? localPagination,
      rowSelection: rowSelection ?? localRowSelection,
      columnVisibility,
    },
    onColumnVisibilityChange: setColumnVisibility,
    onSortingChange: onSortingChange ?? setLocalSorting,
    onColumnFiltersChange: onColumnFiltersChange ?? setLocalColumnFilters,
    onGlobalFilterChange: onGlobalFilterChange ?? setLocalGlobalFilter,
    onPaginationChange: onPaginationChange ?? setLocalPagination,
    onRowSelectionChange: onRowSelectionChange ?? setLocalRowSelection,
    enableRowSelection,
    getRowId,

    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    manualPagination: pageCount !== undefined,
    manualSorting: onSortingChange !== undefined,
    manualFiltering: onColumnFiltersChange !== undefined || onGlobalFilterChange !== undefined,
  });

  return (
    <div className="p-4 space-y-3">
      {/* Toolbar (Search, Filter, Additional actions button slot) */}
      <DataTableToolbar
        table={table}
        searchPlaceholder={searchPlaceholder}
        filters={filters}
        renderAdditionalActions={renderAdditionalActions}
        collapsibleFilters={collapsibleFilters}
        enableColumnVisibility={enableColumnVisibility}
        exportConfig={exportConfig}
      />

      {/* Main Table View */}
      <div className="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none overflow-hidden shadow-sm">
        <div className="overflow-x-auto overflow-y-auto w-full max-h-[520px]">
          <table className="w-full text-left border-collapse">
            <thead className="sticky top-0 z-10">
              {table.getHeaderGroups().map((headerGroup) => (
                <tr
                  key={headerGroup.id}
                  className="bg-slate-50 dark:bg-slate-950/40 border-b border-slate-200 dark:border-slate-800/80"
                >
                  {headerGroup.headers.map((header) => (
                    <th
                      key={header.id}
                      colSpan={header.colSpan}
                      className={`${compact ? 'py-2 px-3' : 'py-3 px-4'} text-[10px] tracking-wider uppercase font-black text-slate-400 dark:text-slate-500 select-none whitespace-nowrap`}
                    >
                      {header.isPlaceholder ? null : (
                        <div
                          className={
                            header.column.getCanSort()
                              ? 'flex items-center gap-1.5 cursor-pointer hover:text-slate-700 dark:hover:text-slate-250 transition-colors'
                              : ''
                          }
                          onClick={header.column.getToggleSortingHandler()}
                        >
                          {flexRender(header.column.columnDef.header, header.getContext())}
                          {header.column.getCanSort() && (
                            <span className="w-3 text-slate-400 dark:text-slate-500">
                              {header.column.getIsSorted() === 'asc' ? (
                                <i className="fa-solid fa-sort-up"></i>
                              ) : header.column.getIsSorted() === 'desc' ? (
                                <i className="fa-solid fa-sort-down"></i>
                              ) : (
                                <i className="fa-solid fa-sort opacity-40"></i>
                              )}
                            </span>
                          )}
                        </div>
                      )}
                    </th>
                  ))}
                </tr>
              ))}
            </thead>
            <tbody className="divide-y divide-slate-100 dark:divide-slate-800">
              {loading ? (
                // Skeleton loading state
                Array.from({ length: 5 }).map((_, rowIndex) => (
                  <tr key={rowIndex} className="border-b border-slate-100 dark:border-slate-800">
                    {columns.map((_, colIndex) => (
                      <td key={colIndex} className="p-4">
                        <div className="h-4 bg-slate-100 dark:bg-slate-800/80 rounded-none animate-pulse w-3/4"></div>
                      </td>
                    ))}
                  </tr>
                ))
              ) : table.getRowModel().rows.length === 0 ? (
                // Empty state UI
                <tr>
                  <td colSpan={columns.length} className="py-16 px-6 text-center">
                    <div className="flex flex-col items-center justify-center max-w-sm mx-auto">
                      <div className="w-12 h-12 bg-slate-50 dark:bg-slate-950/40 rounded-none border border-slate-100 dark:border-slate-850 flex items-center justify-center text-slate-400 dark:text-slate-500 mb-4">
                        <i className="fa-solid fa-folder-open text-xl"></i>
                      </div>
                      <h3 className="font-extrabold text-slate-850 dark:text-white text-sm">{emptyStateTitle}</h3>
                      <p className="text-xs text-slate-400 dark:text-slate-500 mt-1.5 leading-relaxed">{emptyStateDescription}</p>
                    </div>
                  </td>
                </tr>
              ) : (
                // Data rows
                table.getRowModel().rows.map((row) => (
                  <tr
                    key={row.id}
                    className={`transition text-xs font-semibold text-slate-700 dark:text-slate-300 ${
                      row.getIsSelected()
                        ? 'bg-indigo-50/60 dark:bg-indigo-950/20'
                        : 'hover:bg-slate-50/50 dark:hover:bg-slate-900/30'
                    }`}
                  >
                    {row.getVisibleCells().map((cell) => (
                      <td key={cell.id} className={`${compact ? 'px-3 py-2' : 'p-4'} align-middle`}>
                        {flexRender(cell.column.columnDef.cell, cell.getContext())}
                      </td>
                    ))}
                  </tr>
                ))
              )}
            </tbody>
          </table>
        </div>

        {/* Pagination navigation controls */}
        {!loading && table.getRowModel().rows.length > 0 && (
          <DataTablePagination table={table} />
        )}
      </div>
    </div>
  );
}
