import { router, useForm } from '@inertiajs/react';
import { Banknote, Fingerprint } from 'lucide-react';
import { useEffect, useMemo, useState } from 'react';
import { toast } from 'sonner';
import {
    AlertDialog,
    AlertDialogCancel,
    AlertDialogContent,
    AlertDialogDescription,
    AlertDialogFooter,
    AlertDialogHeader,
    AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { AppMonthInput } from '@/components/ui/app-month-input';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Spinner } from '@/components/ui/spinner';
import { formatSalaryMonth } from '@/lib/dates';
import { formatMoneyAmountOrDash } from '@/lib/dates';
import { cn } from '@/lib/utils';

/**
 * @param {object} props
 * @param {boolean} props.open
 * @param {(open: boolean) => void} props.onOpenChange
 * @param {string} [props.storeUrl]
 * @param {string} [props.payUrl]
 * @param {boolean} [props.payOnly]
 * @param {string} [props.salaryMonth]
 * @param {string} props.defaultAmount
 * @param {Record<string, string>} props.labels
 * @param {'en'|'fa'} props.locale
 * @param {() => void} [props.onSuccess]
 */
export function PermanentSalaryPaymentDialog({
    open,
    onOpenChange,
    storeUrl,
    payUrl,
    payOnly = false,
    salaryMonth: fixedSalaryMonth = '',
    defaultAmount,
    labels,
    locale,
    onSuccess,
}) {
    const [scanning, setScanning] = useState(false);
    const [paymentMode, setPaymentMode] = useState('fingerprint');
    const [prevOpen, setPrevOpen] = useState(open);
    const [prevPaymentMode, setPrevPaymentMode] = useState(paymentMode);

    if (open !== prevOpen) {
        setPrevOpen(open);
        if (open) {
            setScanning(false);
            setPaymentMode('fingerprint');
        }
    }

    if (paymentMode !== prevPaymentMode) {
        setPrevPaymentMode(paymentMode);
        if (paymentMode !== 'fingerprint') {
            setScanning(false);
        }
    }

    const form = useForm({
        salary_month: '',
        amount: defaultAmount ?? '',
        payment_method: 'fingerprint',
        fingerprint_data: '',
        manual_confirmed: false,
    });

    useEffect(() => {
        if (!open) {
            form.reset();
            form.clearErrors();
            return;
        }

        const now = new Date();
        const month = payOnly && fixedSalaryMonth
            ? fixedSalaryMonth
            : `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`;
        form.setData({
            salary_month: month,
            amount: defaultAmount ?? '',
            payment_method: 'fingerprint',
            fingerprint_data: '',
            manual_confirmed: false,
        });
        // eslint-disable-next-line react-hooks/exhaustive-deps -- Inertia form identity is unstable
    }, [open, defaultAmount, payOnly, fixedSalaryMonth]);

    useEffect(() => {
        form.setData('payment_method', paymentMode);
        if (paymentMode === 'fingerprint') {
            form.setData('manual_confirmed', false);
        } else {
            form.setData('fingerprint_data', '');
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps -- Inertia form identity is unstable
    }, [paymentMode]);

    useEffect(() => {
        function handleCaptured(data) {
            if (typeof data === 'string' && data.trim().length >= 32) {
                form.setData({
                    ...form.data,
                    fingerprint_data: data.trim(),
                    payment_method: 'fingerprint',
                });
                if (form.errors.fingerprint_data) {
                    form.clearErrors('fingerprint_data');
                }
                setScanning(false);
            }
        }

        window.__onContractFingerprintCaptured = handleCaptured;

        return () => {
            if (window.__onContractFingerprintCaptured === handleCaptured) {
                delete window.__onContractFingerprintCaptured;
            }
        };
    }, [form]);

    function requestScan() {
        setScanning(true);

        if (typeof window.__startContractFingerprintScan === 'function') {
            window.__startContractFingerprintScan();
            return;
        }

        setScanning(false);
        toast.message(labels.scannerBridgeMissing);
    }

    function canSubmit() {
        if (!payOnly && (!form.data.salary_month || form.data.amount === '')) {
            return false;
        }

        if (paymentMode === 'fingerprint') {
            return form.data.fingerprint_data.trim().length >= 32;
        }

        return form.data.manual_confirmed === true;
    }

    function submitPayment() {
        const targetUrl = payOnly ? payUrl : storeUrl;

        if (!targetUrl) {
            return;
        }

        if (!payOnly) {
            if (!form.data.salary_month) {
                form.setError('salary_month', labels.salaryMonthRequired);
                return;
            }

            if (form.data.amount === '' || Number(form.data.amount) < 0) {
                form.setError('amount', labels.amountRequired);
                return;
            }
        }

        if (paymentMode === 'fingerprint' && form.data.fingerprint_data.trim().length < 32) {
            form.setError('fingerprint_data', labels.fingerprintRequired);
            return;
        }

        if (paymentMode === 'manual' && !form.data.manual_confirmed) {
            form.setError('manual_confirmed', labels.manualConfirmationRequired);
            return;
        }

        if (payOnly) {
            router.post(
                targetUrl,
                {
                    payment_method: form.data.payment_method,
                    fingerprint_data: form.data.fingerprint_data,
                    manual_confirmed: form.data.manual_confirmed,
                },
                {
                    preserveScroll: true,
                    onSuccess: () => {
                        onOpenChange(false);
                        onSuccess?.();
                    },
                },
            );

            return;
        }

        form.post(targetUrl, {
            preserveScroll: true,
            onSuccess: () => {
                onOpenChange(false);
                onSuccess?.();
            },
        });
    }

    const hasFingerprintCapture = form.data.fingerprint_data.trim().length >= 32;

    const salaryMonthDisplay = useMemo(
        () =>
            formatSalaryMonth(
                payOnly ? fixedSalaryMonth || form.data.salary_month : form.data.salary_month,
                locale,
            ) ?? '',
        [payOnly, fixedSalaryMonth, form.data.salary_month, locale],
    );

    return (
        <AlertDialog open={open} onOpenChange={onOpenChange}>
            <AlertDialogContent
                className="max-w-lg"
                onOpenAutoFocus={(event) => event.preventDefault()}
                onCloseAutoFocus={(event) => event.preventDefault()}
            >
                <AlertDialogHeader>
                    <AlertDialogTitle>{labels.paymentDialogTitle}</AlertDialogTitle>
                    <AlertDialogDescription>{labels.paymentDialogBody}</AlertDialogDescription>
                </AlertDialogHeader>

                {payOnly ? (
                    <div className="rounded-lg border bg-muted/30 px-4 py-3 text-sm">
                        <p>
                            <span className="text-muted-foreground">{labels.salaryMonth}: </span>
                            <span className="font-medium">{salaryMonthDisplay}</span>
                        </p>
                        <p className="mt-1">
                            <span className="text-muted-foreground">{labels.paymentAmount}: </span>
                            <span className="font-semibold tabular-nums">
                                {formatMoneyAmountOrDash(defaultAmount, locale)}
                            </span>
                        </p>
                    </div>
                ) : (
                    <div className="grid gap-4 sm:grid-cols-2">
                        <div className="space-y-2">
                            <Label htmlFor="salary_month">{labels.salaryMonth}</Label>
                            <AppMonthInput
                                id="salary_month"
                                value={form.data.salary_month}
                                onChange={(month) => {
                                    form.setData('salary_month', month);
                                    if (form.errors.salary_month) {
                                        form.clearErrors('salary_month');
                                    }
                                }}
                                invalid={Boolean(form.errors.salary_month)}
                            />
                            {form.errors.salary_month ? (
                                <p className="text-destructive text-sm">{form.errors.salary_month}</p>
                            ) : null}
                        </div>
                        <div className="space-y-2">
                            <Label htmlFor="salary_amount">{labels.paymentAmount}</Label>
                            <Input
                                id="salary_amount"
                                type="number"
                                min="0"
                                step="0.01"
                                value={form.data.amount}
                                onChange={(e) => {
                                    form.setData('amount', e.target.value);
                                    if (form.errors.amount) {
                                        form.clearErrors('amount');
                                    }
                                }}
                                aria-invalid={Boolean(form.errors.amount)}
                                className={cn(form.errors.amount && 'border-destructive')}
                            />
                            <p className="text-muted-foreground text-xs tabular-nums">
                                {labels.contractSalary}:{' '}
                                {formatMoneyAmountOrDash(defaultAmount, locale)}
                            </p>
                            {form.errors.amount ? (
                                <p className="text-destructive text-sm">{form.errors.amount}</p>
                            ) : null}
                        </div>
                    </div>
                )}

                <div className="flex gap-2 rounded-lg border p-1">
                    <Button
                        type="button"
                        variant={paymentMode === 'fingerprint' ? 'default' : 'ghost'}
                        size="sm"
                        className="flex-1"
                        onClick={() => setPaymentMode('fingerprint')}
                    >
                        <Fingerprint className="size-4" />
                        {labels.paymentModeFingerprint}
                    </Button>
                    <Button
                        type="button"
                        variant={paymentMode === 'manual' ? 'default' : 'ghost'}
                        size="sm"
                        className="flex-1"
                        onClick={() => setPaymentMode('manual')}
                    >
                        <Banknote className="size-4" />
                        {labels.paymentModeManual}
                    </Button>
                </div>

                {paymentMode === 'fingerprint' ? (
                    <div className="space-y-4">
                        <div className="flex flex-col gap-2 sm:flex-row">
                            <Button
                                type="button"
                                variant="outline"
                                className="flex-1"
                                disabled={form.processing || scanning}
                                onClick={requestScan}
                            >
                                {scanning ? (
                                    <>
                                        <Spinner className="size-4" />
                                        {labels.scanningFingerprint}
                                    </>
                                ) : (
                                    <>
                                        <Fingerprint className="size-4" />
                                        {labels.captureFingerprint}
                                    </>
                                )}
                            </Button>
                        </div>
                        {hasFingerprintCapture ? (
                            <p className="text-sm text-emerald-600 dark:text-emerald-400">
                                {labels.fingerprintCaptured}
                            </p>
                        ) : (
                            <p className="text-muted-foreground text-sm">{labels.fingerprintHint}</p>
                        )}
                        {form.errors.fingerprint_data ? (
                            <p className="text-destructive text-sm">{form.errors.fingerprint_data}</p>
                        ) : null}
                    </div>
                ) : (
                    <div className="space-y-3 rounded-lg border border-border/80 p-4">
                        <p className="text-muted-foreground text-sm">{labels.manualPaymentHint}</p>
                        <div className="flex items-start gap-3">
                            <Checkbox
                                id="manual_confirmed"
                                checked={form.data.manual_confirmed}
                                onCheckedChange={(checked) => {
                                    form.setData('manual_confirmed', checked === true);
                                    if (form.errors.manual_confirmed) {
                                        form.clearErrors('manual_confirmed');
                                    }
                                }}
                            />
                            <Label htmlFor="manual_confirmed" className="cursor-pointer leading-snug">
                                {labels.manualConfirmationLabel}
                            </Label>
                        </div>
                        {form.errors.manual_confirmed ? (
                            <p className="text-destructive text-sm">{form.errors.manual_confirmed}</p>
                        ) : null}
                    </div>
                )}

                <AlertDialogFooter>
                    <AlertDialogCancel disabled={form.processing}>{labels.cancel}</AlertDialogCancel>
                    <Button type="button" disabled={form.processing || !canSubmit()} onClick={submitPayment}>
                        {form.processing ? (
                            <>
                                <Spinner className="size-4" />
                                {labels.confirmingPayment}
                            </>
                        ) : (
                            labels.confirmPayment
                        )}
                    </Button>
                </AlertDialogFooter>
            </AlertDialogContent>
        </AlertDialog>
    );
}
