import {
    flexRender,
    getCoreRowModel,
    useReactTable,
} from '@tanstack/react-table';
import type { ColumnDef, RowSelectionState } from '@tanstack/react-table';
import { useEffect, useMemo, useState } from 'react';
import { TableEmptyState } from '@/components/common/TableEmptyState';
import { TablePagination } from '@/components/common/TablePagination';
import { Spinner } from '@/components/ui/spinner';
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableHeaderRow,
    TableRow,
} from '@/components/ui/table';
import { ExpandedDocumentSummary } from '@/features/documents/components/expanded-document-summary';
import { DocumentsBulkDeleteBar } from '@/features/documents/table/documents-bulk-delete-bar';
import type { DocumentListItem, DocumentsPaginationMeta } from '@/features/documents/types';
import { useI18n } from '@/hooks/use-i18n';

type DocumentsTableProps = {
    columns: ColumnDef<DocumentListItem>[];
    data: DocumentListItem[];
    pagination: DocumentsPaginationMeta;
    onPageChange: (page: number) => void;
    isLoading: boolean;
    expandedDocumentId: number | null;
    canDelete?: boolean;
};

export function DocumentsTable({
    columns,
    data,
    pagination,
    onPageChange,
    isLoading,
    expandedDocumentId,
    canDelete = false,
}: DocumentsTableProps) {
    const { t } = useI18n();
    const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
    const expandedState =
        expandedDocumentId != null ? { [String(expandedDocumentId)]: true } : {};

    useEffect(() => {
        setRowSelection({});
    }, [data, pagination.current_page]);

    const table = useReactTable({
        data,
        columns,
        getRowId: (row) => String(row.id),
        enableRowSelection: canDelete,
        onRowSelectionChange: setRowSelection,
        state: {
            expanded: expandedState,
            rowSelection,
        },
        getCoreRowModel: getCoreRowModel(),
    });

    const selectedIds = useMemo(
        () => table.getSelectedRowModel().rows.map((row) => row.original.id),
        [table, rowSelection],
    );

    return (
        <div className="space-y-4">
            {canDelete ? (
                <DocumentsBulkDeleteBar
                    selectedIds={selectedIds}
                    onClearSelection={() => setRowSelection({})}
                />
            ) : null}

            <Table variant="embedded" className="min-w-[52rem]">
                <TableHeader>
                    {table.getHeaderGroups().map((headerGroup) => (
                        <TableHeaderRow key={headerGroup.id}>
                            {headerGroup.headers.map((header) => (
                                <TableHead key={header.id}>
                                    {header.isPlaceholder
                                        ? null
                                        : flexRender(
                                              header.column.columnDef.header,
                                              header.getContext(),
                                          )}
                                </TableHead>
                            ))}
                        </TableHeaderRow>
                    ))}
                </TableHeader>
                <TableBody>
                    {isLoading ? (
                        <TableRow>
                            <TableCell colSpan={columns.length} className="h-20 text-center">
                                <div className="inline-flex items-center gap-2 text-muted-foreground">
                                    <Spinner className="h-4 w-4" />
                                    {t('documents.admin_index.table.loading')}
                                </div>
                            </TableCell>
                        </TableRow>
                    ) : table.getRowModel().rows.length > 0 ? (
                        table.getRowModel().rows.map((row) => {
                            const isExpanded = row.getIsExpanded();

                            return [
                                <TableRow
                                    key={`${row.id}-main`}
                                    data-state={isExpanded ? 'expanded' : undefined}
                                >
                                    {row.getVisibleCells().map((cell) => (
                                        <TableCell key={cell.id}>
                                            {flexRender(
                                                cell.column.columnDef.cell,
                                                cell.getContext(),
                                            )}
                                        </TableCell>
                                    ))}
                                </TableRow>,
                                isExpanded ? (
                                    <TableRow
                                        key={`${row.id}-expanded`}
                                        className="bg-primary-soft/70 hover:bg-primary-soft dark:bg-muted/30 dark:hover:bg-muted/40"
                                    >
                                        <TableCell
                                            colSpan={columns.length}
                                            className="px-3 py-2.5 text-start last:text-start"
                                        >
                                            <ExpandedDocumentSummary document={row.original} />
                                        </TableCell>
                                    </TableRow>
                                ) : null,
                            ];
                        })
                    ) : (
                        <TableRow>
                            <TableCell colSpan={columns.length} className="last:text-center">
                                <TableEmptyState label={t('documents.admin_index.table.empty')} />
                            </TableCell>
                        </TableRow>
                    )}
                </TableBody>
            </Table>
            <TablePagination meta={pagination} onPageChange={onPageChange} isLoading={isLoading} />
        </div>
    );
}
