'use client';

import {
    ColumnDef,
    flexRender,
    getCoreRowModel,
    useReactTable,
} from '@tanstack/react-table';

import { DataTablePagination } from '@/Components/DataTablePagination';
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from '@/Components/ui/table';
import DocumentCreateForm from '@/Pages/Document/DocumentCreateForm';
import DocumentFilters from '@/Pages/Document/DocumentFilters';
import DocumentTypeManager from '@/Pages/Document/DocumentTypeManager';
import { ALL_TYPES_VALUE } from '@/Pages/Document/documentFile';
import { DocumentType } from '@/types';
import { router, usePage } from '@inertiajs/react';
import { useState } from 'react';

interface DocumentsTableProps<TData, TValue> {
    columns: ColumnDef<TData, TValue>[];
    data: TData[];
    rowCount: number;
    pageSize: number;
    pageCount: number;
    documentTypes: DocumentType[];
}

export function DocumentsTable<TData, TValue>({
    columns,
    data,
    rowCount,
    pageSize,
    pageCount,
    documentTypes,
}: DocumentsTableProps<TData, TValue>) {
    const { filters } = usePage().props;
    const [search, setSearch] = useState(filters?.search || '');
    const [typeId, setTypeId] = useState(
        filters?.document_type_id || ALL_TYPES_VALUE,
    );
    const [page, setPage] = useState(1);

    const table = useReactTable({
        data,
        columns,
        getCoreRowModel: getCoreRowModel(),
        manualPagination: true,
        manualFiltering: true,
        rowCount,
        initialState: {
            pagination: { pageSize, pageIndex: 0 },
        },
    });

    // Search, type filter and pagination all travel together, so that changing
    // one does not reset the others.
    const reload = (params: {
        search: string;
        typeId: string;
        page: number;
    }) => {
        router.get(
            route('admin-documents'),
            {
                search: params.search,
                document_type_id:
                    params.typeId === ALL_TYPES_VALUE ? '' : params.typeId,
                page: params.page,
            },
            {
                preserveState: true,
                preserveScroll: true,
                replace: true, // Prevent duplicate history entries
            },
        );
    };

    const handleSearchChange = (value: string) => {
        setSearch(value);
        setPage(1);
        reload({ search: value, typeId, page: 1 });
    };

    const handleTypeChange = (value: string) => {
        setTypeId(value);
        setPage(1);
        reload({ search, typeId: value, page: 1 });
    };

    const handlePageChange = (pageIndex: number) => {
        setPage(pageIndex);
        reload({ search, typeId, page: pageIndex });
    };

    return (
        <div>
            <DocumentFilters
                search={search}
                typeId={typeId}
                documentTypes={documentTypes}
                onSearchChange={handleSearchChange}
                onTypeChange={handleTypeChange}
            >
                <DocumentTypeManager documentTypes={documentTypes} />
                <DocumentCreateForm documentTypes={documentTypes} />
            </DocumentFilters>
            <div className="rounded-md border bg-white">
                <Table>
                    <TableHeader>
                        {table.getHeaderGroups().map((headerGroup) => (
                            <TableRow key={headerGroup.id}>
                                {headerGroup.headers.map((header) => {
                                    return (
                                        <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}>
                                    {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"
                                >
                                    Nessun risultato.
                                </TableCell>
                            </TableRow>
                        )}
                    </TableBody>
                </Table>
            </div>
            <div className="py-4">
                <DataTablePagination
                    table={table}
                    changePage={handlePageChange}
                    currentPage={page}
                    pageCount={pageCount}
                />
            </div>
        </div>
    );
}
