import { useForm } from '@inertiajs/react';
import { useEffect, useMemo, useState } from 'react';
import {
    defaultPaymentMode,
    paymentModeCurrency,
} from '@/lib/supplier-payment-mode';
import { toast } from 'sonner';
import { recordPayment } from '@/actions/App/Http/Controllers/PurchaseController';
import { ConfirmActionDialog } from '@/components/confirm-action-dialog';
import { SupplierPaymentFields } from '@/components/purchases/supplier-payment-fields';
import { Button } from '@/components/ui/button';
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { formatPurchaseCurrencyLabel } from '@/lib/dates';
import { buildSupplierPaymentApiFields } from '@/lib/supplier-payment-payload';
import { buildRecordPurchasePaymentSchema } from '@/validation/schemas';

function todayYmd() {
    const now = new Date();
    const y = now.getFullYear();
    const m = String(now.getMonth() + 1).padStart(2, '0');
    const d = String(now.getDate()).padStart(2, '0');
    return `${y}-${m}-${d}`;
}

/**
 * @param {object} props
 * @param {object|null} props.purchase
 * @param {boolean} props.open
 * @param {(open: boolean) => void} props.onOpenChange
 * @param {Record<string, string>} props.labels
 * @param {Record<string, string>} props.validation
 * @param {Record<string, string>} props.appActions
 * @param {'en'|'fa'} props.locale
 * @param {Array<string>} props.currencies
 * @param {Array<string>} props.paymentMethods
 */
export function PurchaseRecordPaymentDialog({
    purchase,
    open,
    onOpenChange,
    labels,
    validation,
    appActions,
    locale,
    currencies,
    paymentMethods,
}) {
    const billCurrency = purchase?.currency ?? 'afn';

    const form = useForm({
        currency: paymentModeCurrency(defaultPaymentMode(billCurrency)),
        amount: '',
        paid_at: todayYmd(),
        payment_method: 'cash',
        reference: '',
        notes: '',
        exchange_rate: '',
    });

    useEffect(() => {
        if (!open || !purchase) {
            return;
        }

        const nextBillCurrency = purchase.currency ?? 'afn';

        form.setData((data) => ({
            ...data,
            currency: paymentModeCurrency(defaultPaymentMode(nextBillCurrency)),
            amount: '',
            exchange_rate: '',
        }));
        // eslint-disable-next-line react-hooks/exhaustive-deps -- reset when a different bill opens
    }, [open, purchase?.id]);
    const [confirmOpen, setConfirmOpen] = useState(false);

    const schema = useMemo(
        () => buildRecordPurchasePaymentSchema(validation),
        [validation],
    );

    const maxBillAmount = Number(purchase?.due_amount ?? 0);

    function fieldError(key) {
        return form.errors[key] ?? form.errors[`payment.${key}`];
    }

    function handleFieldChange(field, value) {
        form.setData(field, value);
    }

    function buildPayload() {
        return {
            bill_currency: billCurrency,
            ...buildSupplierPaymentApiFields(form.data, billCurrency),
        };
    }

    function handleSubmit(e) {
        e.preventDefault();
        form.clearErrors();
        const parsed = schema.safeParse(buildPayload());
        if (!parsed.success) {
            const first = parsed.error.issues[0];
            if (first) {
                form.setError(first.path.join('.'), first.message);
            }
            return;
        }
        setConfirmOpen(true);
    }

    function commitSave() {
        if (!purchase) {
            return;
        }

        form.clearErrors();
        const parsed = schema.safeParse(buildPayload());
        if (!parsed.success) {
            setConfirmOpen(false);
            return;
        }

        form.transform(() => parsed.data);
        form.post(recordPayment.url(purchase.id), {
            preserveScroll: true,
            onSuccess: () => {
                setConfirmOpen(false);
                onOpenChange(false);
                form.reset();
            },
            onError: () => toast.error(appActions.requestFailed),
        });
    }

    if (!purchase) {
        return null;
    }

    return (
        <>
            <ConfirmActionDialog
                open={confirmOpen}
                onOpenChange={setConfirmOpen}
                title={labels.confirmSaveTitle}
                description={labels.confirmSaveBody}
                confirmLabel={labels.savePayment}
                cancelLabel={appActions.cancel}
                processing={form.processing}
                onConfirm={commitSave}
            />

            <Dialog open={open} onOpenChange={onOpenChange}>
                <DialogContent className="max-w-lg sm:max-w-xl">
                    <DialogHeader>
                        <DialogTitle>{labels.recordPaymentTitle}</DialogTitle>
                        <DialogDescription>
                            {labels.recordPaymentDescription
                                .replace('{bill}', purchase.bill_number || '—')
                                .replace(
                                    '{currency}',
                                    formatPurchaseCurrencyLabel(billCurrency, locale),
                                )}
                        </DialogDescription>
                    </DialogHeader>

                    <form onSubmit={handleSubmit} className="space-y-4">
                        <SupplierPaymentFields
                            labels={labels}
                            locale={locale}
                            currencies={currencies}
                            paymentMethods={paymentMethods}
                            billCurrency={billCurrency}
                            maxBillAmount={maxBillAmount}
                            data={form.data}
                            errors={{
                                amount: fieldError('amount'),
                                paid_at: fieldError('paid_at'),
                                exchange_rate: fieldError('exchange_rate'),
                            }}
                            onChange={handleFieldChange}
                            idPrefix="purchase-payment"
                            compact
                        />

                        <DialogFooter className="gap-2 sm:gap-0">
                            <Button
                                type="button"
                                variant="outline"
                                onClick={() => onOpenChange(false)}
                            >
                                {appActions.cancel}
                            </Button>
                            <Button type="submit" disabled={form.processing}>
                                {form.processing ? labels.savingPayment : labels.savePayment}
                            </Button>
                        </DialogFooter>
                    </form>
                </DialogContent>
            </Dialog>
        </>
    );
}
