import { router, useForm } from '@inertiajs/react';
import { Trash2 } from 'lucide-react';
import { useEffect, useMemo, useState } from 'react';
import { StaffSearchSelect } from '@/components/attendance/staff-search-select';
import { ConfirmActionDialog } from '@/components/confirm-action-dialog';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from '@/components/ui/table';
import { useSyncedState } from '@/hooks/use-synced-state';

/**
 * @param {object} props
 * @param {import('@inertiajs/core').Paginator<any>} props.enrollments
 * @param {object} props.filters
 * @param {Array<{id: number, name: string, serial_number: string}>} props.devices
 * @param {Array<{staff_type: string, staff_id: number, label: string}>} props.staffOptions
 * @param {Record<string, string>} props.labels
 * @param {(opts?: object) => string} props.indexUrl
 * @param {string} props.storeUrl
 * @param {(id: number) => string} props.destroyUrl
 * @param {string} props.cancelLabel
 */
export function AttendanceEnrollmentsPanel({
    enrollments,
    filters,
    devices,
    staffOptions,
    labels,
    indexUrl,
    storeUrl,
    destroyUrl,
    cancelLabel,
}) {
    const [search, setSearch] = useSyncedState(filters.search ?? '');
    const [deviceId, setDeviceId] = useSyncedState(
        filters.device_id ? String(filters.device_id) : '',
    );
    const [staffKey, setStaffKey] = useState('');
    const [removeId, setRemoveId] = useState(null);
    const [enrollConfirmOpen, setEnrollConfirmOpen] = useState(false);

    const enrollForm = useForm({
        attendance_device_id: '',
        staff_type: '',
        staff_id: '',
    });

    useEffect(() => {
        const handle = setTimeout(() => {
            router.get(
                indexUrl({
                    query: {
                        search: search.trim(),
                        device_id: deviceId,
                        per_page: filters.per_page,
                        page: 1,
                    },
                }),
                {},
                { preserveState: true, preserveScroll: true, replace: true },
            );
        }, 350);

        return () => clearTimeout(handle);
    }, [search, deviceId, filters.per_page, indexUrl]);

    const rows = enrollments?.data ?? [];
    const currentPage = enrollments?.current_page ?? 1;
    const lastPage = enrollments?.last_page ?? 1;
    const total = enrollments?.total ?? 0;
    const perPage = enrollments?.per_page ?? 10;

    const summaryText = useMemo(() => {
        if (total === 0) {
            return labels.summaryEmpty;
        }
        return labels.paginationSummary
            .replace('{from}', String(enrollments?.from ?? 0))
            .replace('{to}', String(enrollments?.to ?? 0))
            .replace('{total}', String(total));
    }, [total, enrollments?.from, enrollments?.to, labels]);

    function goToPage(page) {
        router.get(
            indexUrl({ query: { ...filters, page } }),
            {},
            { preserveState: true, preserveScroll: true },
        );
    }

    function requestEnrollment() {
        if (!staffKey || !enrollForm.data.attendance_device_id) {
            return;
        }
        setEnrollConfirmOpen(true);
    }

    function submitEnrollment() {
        const [type, id] = staffKey.split(':');
        if (!type || !id || !enrollForm.data.attendance_device_id) {
            setEnrollConfirmOpen(false);
            return;
        }
        enrollForm.transform((data) => ({
            ...data,
            staff_type: type,
            staff_id: Number(id),
        }));
        enrollForm.post(storeUrl, {
            preserveScroll: true,
            onSuccess: () => {
                enrollForm.reset();
                setStaffKey('');
            },
        });
    }

    function confirmRemove() {
        if (!removeId) {
            return;
        }
        router.delete(destroyUrl(removeId), {
            preserveScroll: true,
            onFinish: () => setRemoveId(null),
        });
    }

    return (
        <div className="space-y-8">
            <div className="rounded-lg border p-4">
                <h3 className="mb-4 font-semibold">{labels.addEnrollment}</h3>
                <p className="text-muted-foreground mb-4 text-sm">{labels.enrollmentStaffIdHint}</p>
                <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
                    <div className="space-y-2">
                        <Label>{labels.selectDevice}</Label>
                        <Select
                            value={enrollForm.data.attendance_device_id || ''}
                            onValueChange={(v) =>
                                enrollForm.setData('attendance_device_id', v)
                            }
                        >
                            <SelectTrigger>
                                <SelectValue placeholder={labels.selectDevice} />
                            </SelectTrigger>
                            <SelectContent>
                                {devices.map((d) => (
                                    <SelectItem key={d.id} value={String(d.id)}>
                                        {d.name} ({d.serial_number})
                                    </SelectItem>
                                ))}
                            </SelectContent>
                        </Select>
                    </div>
                    <div className="space-y-2">
                        <Label htmlFor="enrollment-staff">{labels.selectStaff}</Label>
                        <StaffSearchSelect
                            id="enrollment-staff"
                            value={staffKey}
                            onValueChange={setStaffKey}
                            options={staffOptions}
                            placeholder={labels.selectStaff}
                            searchPlaceholder={labels.searchStaffPlaceholder}
                            emptyLabel={labels.searchStaffEmpty}
                        />
                    </div>
                    <div className="flex items-end sm:col-span-2 lg:col-span-1">
                        <Button
                            type="button"
                            disabled={
                                !staffKey ||
                                !enrollForm.data.attendance_device_id ||
                                enrollForm.processing
                            }
                            onClick={requestEnrollment}
                        >
                            {labels.addEnrollment}
                        </Button>
                    </div>
                </div>
            </div>

            <div className="grid gap-4 sm:grid-cols-2">
                <Input
                    type="search"
                    value={search}
                    onChange={(e) => setSearch(e.target.value)}
                    placeholder={labels.searchEnrollmentsPlaceholder}
                />
                <Select
                    value={deviceId || 'all'}
                    onValueChange={(v) => setDeviceId(v === 'all' ? '' : v)}
                >
                    <SelectTrigger>
                        <SelectValue placeholder={labels.filterDevice} />
                    </SelectTrigger>
                    <SelectContent>
                        <SelectItem value="all">{labels.allDevices}</SelectItem>
                        {devices.map((d) => (
                            <SelectItem key={d.id} value={String(d.id)}>
                                {d.name}
                            </SelectItem>
                        ))}
                    </SelectContent>
                </Select>
            </div>

            <div className="overflow-x-auto rounded-md border">
                <Table>
                    <TableHeader>
                        <TableRow>
                            <TableHead className="w-14">{labels.colSerial}</TableHead>
                            <TableHead>{labels.colStaff}</TableHead>
                            <TableHead>{labels.colDevice}</TableHead>
                            <TableHead>{labels.colStaffId}</TableHead>
                            <TableHead className="w-24">{labels.colAction}</TableHead>
                        </TableRow>
                    </TableHeader>
                    <TableBody>
                        {rows.length === 0 ? (
                            <TableRow>
                                <TableCell colSpan={5} className="text-muted-foreground h-24 text-center">
                                    {labels.emptyEnrollments}
                                </TableCell>
                            </TableRow>
                        ) : (
                            rows.map((row, index) => (
                                <TableRow key={row.id}>
                                    <TableCell className="text-muted-foreground tabular-nums">
                                        {(currentPage - 1) * perPage + index + 1}
                                    </TableCell>
                                    <TableCell>
                                        <div className="font-medium">{row.staff_name}</div>
                                        <Badge variant="outline" className="mt-1">
                                            {row.staff_type === 'permanent'
                                                ? labels.staffTypePermanent
                                                : labels.staffTypeTemporary}
                                        </Badge>
                                    </TableCell>
                                    <TableCell>
                                        {row.device_name}
                                        <span className="text-muted-foreground block font-mono text-xs">
                                            {row.device_serial}
                                        </span>
                                    </TableCell>
                                    <TableCell className="font-mono tabular-nums">{row.staff_id}</TableCell>
                                    <TableCell>
                                        <Button
                                            type="button"
                                            variant="ghost"
                                            size="icon"
                                            onClick={() => setRemoveId(row.id)}
                                            aria-label={labels.removeEnrollment}
                                        >
                                            <Trash2 className="text-destructive size-4" />
                                        </Button>
                                    </TableCell>
                                </TableRow>
                            ))
                        )}
                    </TableBody>
                </Table>
            </div>

            <div className="flex flex-wrap items-center justify-between gap-2">
                <p className="text-muted-foreground text-sm">{summaryText}</p>
                <div className="flex gap-2">
                    <Button
                        type="button"
                        variant="outline"
                        size="sm"
                        disabled={currentPage <= 1}
                        onClick={() => goToPage(currentPage - 1)}
                    >
                        {labels.paginationPrevious}
                    </Button>
                    <Button
                        type="button"
                        variant="outline"
                        size="sm"
                        disabled={currentPage >= lastPage}
                        onClick={() => goToPage(currentPage + 1)}
                    >
                        {labels.paginationNext}
                    </Button>
                </div>
            </div>

            <ConfirmActionDialog
                open={enrollConfirmOpen}
                onOpenChange={setEnrollConfirmOpen}
                title={labels.confirmEnrollTitle}
                description={labels.confirmEnrollBody}
                confirmLabel={labels.addEnrollment}
                cancelLabel={cancelLabel}
                processing={enrollForm.processing}
                onConfirm={submitEnrollment}
            />

            <ConfirmActionDialog
                open={removeId !== null}
                onOpenChange={(open) => !open && setRemoveId(null)}
                title={labels.confirmRemoveEnrollmentTitle}
                description={labels.confirmRemoveEnrollmentBody}
                confirmLabel={labels.removeEnrollment}
                cancelLabel={cancelLabel}
                onConfirm={confirmRemove}
            />
        </div>
    );
}
