'use client';

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

import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from '@/Components/ui/table';

import { router, usePage } from '@inertiajs/react';
import React, { useState } from 'react';

import { DataTablePagination } from '@/Components/DataTablePagination';
import ReminderCreateForm from '@/Pages/Reminder/ReminderCreateForm';
import ReminderEditForm from '@/Pages/Reminder/ReminderEditForm';
import ReminderSearchInput from '@/Pages/Reminder/ReminderSearchInput';
import { PageProps, Reminder } from '@/types';

interface DataTableProps<TData, TValue> {
    columns: ColumnDef<TData, TValue>[];
    data: TData[];
}

interface RemindersTableProps<TData, TValue>
    extends DataTableProps<TData, TValue> {
    rowCount: number;
    pageSize: number;
    pageCount: number;
    availableScheduleTypes: string[];
    availableIntervalUnits: string[];
}

export function RemindersTable<TData, TValue>({
    columns,
    data,
    rowCount,
    pageSize,
    pageCount,
    availableScheduleTypes,
    availableIntervalUnits,
}: RemindersTableProps<TData, TValue>) {
    const { filters } =
        usePage<PageProps<{ filters?: { search?: string } }>>().props;
    const [search, setSearch] = useState(filters?.search || '');
    const [page, setPage] = useState(1);
    const [columnFilters, setColumnFilters] =
        React.useState<ColumnFiltersState>([]);

    const table = useReactTable({
        data,
        columns,
        getRowId: (row) => String((row as Reminder).id),
        getCoreRowModel: getCoreRowModel(),
        onColumnFiltersChange: setColumnFilters,
        manualPagination: true,
        manualFiltering: true,
        rowCount,
        initialState: {
            pagination: { pageSize, pageIndex: 0 },
        },
        state: { columnFilters },
    });

    const handlePageChange = (pageIndex: number) => {
        setPage(pageIndex);

        router.get(
            route('reminders.index'),
            { search, page: pageIndex },
            {
                preserveState: true,
                preserveScroll: true,
                replace: true,
            },
        );
    };

    return (
        <div>
            <div className="flex w-full items-baseline justify-between gap-4 py-4">
                <ReminderSearchInput search={search} setSearch={setSearch} />
                <ReminderCreateForm
                    availableScheduleTypes={availableScheduleTypes}
                    availableIntervalUnits={availableIntervalUnits}
                />
            </div>

            <div className="rounded-md border bg-white">
                <Table>
                    <TableHeader>
                        {table.getHeaderGroups().map((headerGroup) => (
                            <TableRow key={headerGroup.id}>
                                {headerGroup.headers.map((header) => (
                                    <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) => (
                                <ReminderEditForm
                                    key={row.id}
                                    reminder={row.original as Reminder}
                                    availableScheduleTypes={
                                        availableScheduleTypes
                                    }
                                    availableIntervalUnits={
                                        availableIntervalUnits
                                    }
                                >
                                    <TableRow
                                        className="hover:cursor-pointer"
                                        data-state={
                                            row.getIsSelected() && 'selected'
                                        }
                                    >
                                        {row.getVisibleCells().map((cell) => (
                                            <TableCell key={cell.id}>
                                                {flexRender(
                                                    cell.column.columnDef.cell,
                                                    cell.getContext(),
                                                )}
                                            </TableCell>
                                        ))}
                                    </TableRow>
                                </ReminderEditForm>
                            ))
                        ) : (
                            <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>
    );
}
