'use client';

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

import { DataTablePagination } from '@/Components/DataTablePagination';
import PatientSelectInput from '@/Components/PatientSelectInput';
import SearchInput from '@/Components/SearchInput';
import SelectInput from '@/Components/SelectInput';
import ShowIf from '@/Components/ShowIf';
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from '@/Components/ui/table';
import { capitalize, t } from '@/lib/utils';
import DeviceCreateForm from '@/Pages/Device/DeviceCreateForm';
import DeviceEditForm from '@/Pages/Device/DeviceEditForm';
import { Device, User } from '@/types';
import { router, usePage } from '@inertiajs/react';
import React, { useState } from 'react';

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

interface DevicesTableProps<TData, TValue>
    extends DataTableProps<TData, TValue> {
    availableTypes: string[];
    rowCount: number;
    pageSize: number;
    pageCount: number;
    availableManufacturers: string[];
    canEdit: boolean;
    canCreate: boolean;
    selectedPatient?: User | null;
}

export function DevicesTable<TData, TValue>({
    columns,
    data,
    rowCount,
    pageSize,
    pageCount,
    availableTypes,
    availableManufacturers,
    canEdit,
    canCreate,
    selectedPatient,
}: DevicesTableProps<TData, TValue>) {
    const { filters } = usePage().props;
    const [search, setSearch] = useState(filters?.search || '');
    const [status, setStatus] = useState(filters?.status || 'all');
    const [manufacturer, setManufacturer] = useState(
        filters?.manufacturer || 'all',
    );
    const [type, setType] = useState(filters?.type || 'all');
    const [patient, setPatient] = useState<User | null>(
        selectedPatient ?? null,
    );
    const [page, setPage] = useState(1);
    const [columnFilters, setColumnFilters] =
        React.useState<ColumnFiltersState>([]);

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

    const navigate = (overrides: Record<string, string | number> = {}) => {
        const params: Record<string, string | number> = {
            search,
            status,
            manufacturer,
            type,
            patient_id: patient?.id ?? '',
            page: 1,
            ...overrides,
        };

        // The 'all' sentinel means "no filter" — drop it from the query.
        (['status', 'manufacturer', 'type'] as const).forEach((key) => {
            if (params[key] === 'all') {
                delete params[key];
            }
        });
        if (!params.patient_id) {
            delete params.patient_id;
        }

        router.get(route('admin-devices'), params, {
            preserveState: true,
            preserveScroll: true,
            replace: true, // Prevent duplicate history entries
        });
    };

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

    const statusOptions = [
        { value: 'all', label: t('all') },
        { value: 'assigned', label: t('assigned') },
        { value: 'available', label: t('unassigned') },
    ];

    const manufacturerOptions = [
        { value: 'all', label: t('all') },
        ...availableManufacturers.map((m) => ({ value: m, label: m })),
    ];

    const typeOptions = [
        { value: 'all', label: t('all') },
        ...availableTypes.map((ty) => ({ value: ty, label: t(ty) })),
    ];

    return (
        <div>
            <div className="flex w-full flex-wrap items-end justify-between gap-4 py-4">
                <div className="flex flex-1 flex-wrap items-end gap-3">
                    <SearchInput
                        value={search}
                        onChange={(e) => {
                            setSearch(e.target.value);
                            navigate({ search: e.target.value });
                        }}
                        className="min-w-[200px] grow"
                    />
                    <div className="w-40">
                        <label className="mb-1 block text-xs text-zinc-500">
                            {capitalize(t('status'))}
                        </label>
                        <SelectInput
                            value={status}
                            options={statusOptions}
                            onChange={(value) => {
                                setStatus(value);
                                navigate({ status: value });
                            }}
                        />
                    </div>
                    <div className="w-40">
                        <label className="mb-1 block text-xs text-zinc-500">
                            {capitalize(t('manufacturer'))}
                        </label>
                        <SelectInput
                            value={manufacturer}
                            options={manufacturerOptions}
                            onChange={(value) => {
                                setManufacturer(value);
                                navigate({ manufacturer: value });
                            }}
                        />
                    </div>
                    <div className="w-40">
                        <label className="mb-1 block text-xs text-zinc-500">
                            {capitalize(t('type'))}
                        </label>
                        <SelectInput
                            value={type}
                            options={typeOptions}
                            onChange={(value) => {
                                setType(value);
                                navigate({ type: value });
                            }}
                        />
                    </div>
                    <div className="w-56">
                        <label className="mb-1 block text-xs text-zinc-500">
                            {capitalize(t('patient'))}
                        </label>
                        <PatientSelectInput
                            value={patient}
                            onChange={(selected) => {
                                setPatient(selected);
                                navigate({ patient_id: selected?.id ?? '' });
                            }}
                        />
                        {patient && (
                            <button
                                type="button"
                                className="mt-1 text-xs text-zinc-500 underline"
                                onClick={() => {
                                    setPatient(null);
                                    navigate({ patient_id: '' });
                                }}
                            >
                                {capitalize(t('all'))}
                            </button>
                        )}
                    </div>
                </div>
                <ShowIf condition={canCreate}>
                    <DeviceCreateForm
                        availableTypes={availableTypes}
                        availableManufacturers={availableManufacturers}
                    />
                </ShowIf>
            </div>
            <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) => (
                                <DeviceEditForm
                                    key={row.id}
                                    device={row.original as Device}
                                    availableTypes={availableTypes}
                                    availableManufacturers={
                                        availableManufacturers
                                    }
                                    canEdit={canEdit}
                                >
                                    <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>
                                </DeviceEditForm>
                            ))
                        ) : (
                            <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>
    );
}
