import { Checkbox } from '@/components/ui/checkbox';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import { useColumnVisibility } from '@/hooks/use-column-visibility';
import { BulkAction, PaginatedData } from '@/types';
import { Column, ColumnDef, flexRender, getCoreRowModel, getPaginationRowModel, useReactTable } from '@tanstack/react-table';
import { DataTableColumnHeader } from './datatable-column-header';
import { DataTablePagination } from './datatable-pagination';
import DataTableToolbar, { FilterConfig } from './datatable-toolbar';

interface DataTableProps<TData, TValue> {
    columns: (ColumnDef<TData, TValue> & { sorting?: boolean })[];
    data: TData[];
    paginatedData?: PaginatedData<TData>;
    bulkActions?: BulkAction<TData>[];
    tableKey?: string;
    filters?: FilterConfig[];
    onRowClick?: (row: TData) => void;
    enableRowClick?: boolean;
    showToolbar?: boolean;
    loading?: boolean;
    fullHeight?: boolean;
    selectAllActive?: boolean;
    onSelectAllAcrossPages?: () => void;
    onClearSelectAllAcrossPages?: () => void;
    onNavigate?: (params: Record<string, any>) => void;
    handleActivitySidebar?: any;
}

export function DataTable<TData, TValue>({
    columns,
    data,
    paginatedData,
    bulkActions = [],
    tableKey = 'default',
    filters = [],
    onRowClick,
    enableRowClick = false,
    showToolbar = true,
    loading = false,
    fullHeight = true,
    selectAllActive = false,
    onSelectAllAcrossPages,
    onClearSelectAllAcrossPages,
    onNavigate,
    handleActivitySidebar,
}: DataTableProps<TData, TValue>) {
    // Initialize column visibility hook
    const { columnVisibility, setColumnVisibility, resetColumnVisibility } = useColumnVisibility(tableKey);

    // Add checkbox column if bulk actions exist
    const allColumns = [...columns];
    if (bulkActions.length > 0) {
        const checkboxColumn: ColumnDef<TData, TValue> & { sorting?: boolean } = {
            id: 'select',
            header: ({ table }) => (
                <Checkbox
                    checked={table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate')}
                    onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
                    aria-label="Select all"
                />
            ),
            cell: ({ row }) => (
                <Checkbox checked={row.getIsSelected()} onCheckedChange={(value) => row.toggleSelected(!!value)} aria-label="Select row" />
            ),
            enableSorting: false,
            enableHiding: false,
            sorting: false,
        };
        allColumns.unshift(checkboxColumn);
    }

    // Process columns to add sorting headers if sorting is true (default: false)
    const processedColumns = allColumns.map((column) => {
        // Default sorting to false if not specified
        const isSortingEnabled = column.sorting === true;

        if (!isSortingEnabled || !paginatedData) return column;

        if (typeof column.header === 'function') return column;

        if ('accessorKey' in column) {
            const columnWithAccessor = column as ColumnDef<TData, TValue> & { accessorKey: string; sorting?: boolean; header?: string };
            const headerTitle = typeof columnWithAccessor.header === 'string' ? columnWithAccessor.header : columnWithAccessor.accessorKey;
            return {
                ...column,
                header: ({ column: col }: { column: Column<TData, unknown> }) => (
                    <DataTableColumnHeader column={col} title={headerTitle} queryParams={paginatedData.queryParams} navigate={onNavigate} />
                ),
            };
        }

        return column;
    });

    const table = useReactTable({
        data,
        columns: processedColumns,
        getCoreRowModel: getCoreRowModel(),
        manualPagination: true,
        getPaginationRowModel: getPaginationRowModel(),
        manualSorting: true,
        state: {
            columnVisibility,
        },
        onColumnVisibilityChange: setColumnVisibility,
    });

    return (
        <>
            <div className={`rounded-lg border bg-card${fullHeight ? ' flex h-[calc(99vh-10rem)] flex-col' : ''}`}>
                {paginatedData && showToolbar && (
                    <DataTableToolbar
                        table={table}
                        paginatedData={paginatedData}
                        className=""
                        bulkActions={bulkActions}
                        resetColumnVisibility={resetColumnVisibility}
                        filters={filters}
                        loading={loading}
                        selectAllActive={selectAllActive}
                        onSelectAll={onSelectAllAcrossPages}
                        onClearSelectAll={onClearSelectAllAcrossPages}
                        navigate={onNavigate}
                        handleActivitySidebar={handleActivitySidebar}
                    />
                )}

                <div className={`w-full overflow-x-auto${fullHeight ? ' flex-1' : ''}`}>
                    <Table className="w-full min-w-max">
                        <TableHeader className="sticky top-0 z-10 bg-card">
                            {table.getHeaderGroups().map((headerGroup) => (
                                <TableRow key={headerGroup.id} className="border-b">
                                    {/* Add #SL column header manually */}
                                    {/* {bulkActions.length > 0 && headerGroup.headers[0]?.id === 'select' && (
                                    <TableHead className="w-16 px-4 py-3 text-left text-xs font-medium tracking-wider text-gray-500 uppercase">
                                        #SL
                                    </TableHead>
                                )} */}
                                    {headerGroup.headers.map((header, index) => (
                                        <TableHead
                                            key={header.id}
                                            className="px-4 py-3 text-left text-xs font-medium tracking-wider text-gray-500 uppercase"
                                        >
                                            {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}
                                        </TableHead>
                                    ))}
                                </TableRow>
                            ))}
                        </TableHeader>
                        <TableBody className="divide divide-y bg-card">
                            {table.getRowModel().rows?.length ? (
                                table.getRowModel().rows.map((row, rowIndex) => (
                                    <TableRow
                                        key={row.id}
                                        data-state={row.getIsSelected() && 'selected'}
                                        className={`${enableRowClick ? 'cursor-pointer transition-colors hover:bg-gray-50' : ''}`}
                                        onClick={(e) => {
                                            if (!enableRowClick || !onRowClick) return;

                                            // Don't navigate if clicking on interactive elements
                                            if (
                                                e.target instanceof HTMLElement &&
                                                (e.target.closest('button') ||
                                                    e.target.closest('a') ||
                                                    e.target.closest('[role="checkbox"]') ||
                                                    e.target.closest('.dropdown-menu') ||
                                                    e.target.closest('[data-radix-collection-item]'))
                                            ) {
                                                return;
                                            }

                                            // Call the provided row click handler
                                            onRowClick(row.original);
                                        }}
                                    >
                                        {row.getVisibleCells().map((cell) => (
                                            <TableCell key={cell.id} className="px-4 py-4">
                                                {flexRender(cell.column.columnDef.cell, cell.getContext())}
                                            </TableCell>
                                        ))}
                                    </TableRow>
                                ))
                            ) : (
                                <TableRow>
                                    <TableCell
                                        colSpan={processedColumns.length + (bulkActions.length > 0 ? 1 : 0)}
                                        className="h-24 text-center text-gray-600"
                                    >
                                        No results.
                                    </TableCell>
                                </TableRow>
                            )}
                        </TableBody>
                    </Table>
                </div>

                {paginatedData && (
                    <div className="mt-auto bg-card p-3">
                        <DataTablePagination table={table} paginatedData={paginatedData} navigate={onNavigate} />
                    </div>
                )}
            </div>
        </>
    );
}
