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/SaleController';
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 { formatMoneyAmountOrDash, 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}`;
}

const SALE_BILL_CURRENCY = 'afn';

/**
 * @param {object} props
 * @param {object|null} props.sale
 * @param {boolean} props.open
 * @param {(open: boolean) => void} props.onOpenChange
 * @param {Record<string, string>} props.labels
 * @param {Record<string, string>} props.paymentLabels
 * @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 SaleRecordPaymentDialog({
    sale,
    open,
    onOpenChange,
    labels,
    paymentLabels,
    validation,
    appActions,
    locale,
    currencies,
    paymentMethods,
}) {
    const form = useForm({
        currency: paymentModeCurrency(defaultPaymentMode(SALE_BILL_CURRENCY)),
        amount: '',
        paid_at: todayYmd(),
        payment_method: 'cash',
        reference: '',
        notes: '',
        exchange_rate: '',
    });

    useEffect(() => {
        if (!open || !sale) {
            return;
        }

        form.setData((data) => ({
            ...data,
            currency: paymentModeCurrency(defaultPaymentMode(SALE_BILL_CURRENCY)),
            amount: '',
            exchange_rate: '',
        }));
        // eslint-disable-next-line react-hooks/exhaustive-deps -- reset when a different sale opens
    }, [open, sale?.id]);

    const [confirmOpen, setConfirmOpen] = useState(false);

    const schema = useMemo(
        () => buildRecordPurchasePaymentSchema(validation),
        [validation],
    );

    const maxBillAmount = Number(sale?.due_amount ?? 0);
    const hasDiscount =
        sale?.discount != null && Number(sale.discount) > 0.001;

    function fieldError(key) {
        return form.errors[key] ?? form.errors[`payment.${key}`];
    }

    function handleFieldChange(field, value) {
        form.setData(field, value);
    }

    function buildPayload() {
        return {
            bill_currency: SALE_BILL_CURRENCY,
            ...buildSupplierPaymentApiFields(form.data, SALE_BILL_CURRENCY),
        };
    }

    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 (!sale) {
            return;
        }

        form.clearErrors();
        const parsed = schema.safeParse(buildPayload());
        if (!parsed.success) {
            setConfirmOpen(false);
            return;
        }

        form.transform(() => parsed.data);
        form.post(recordPayment.url(sale.id), {
            preserveScroll: true,
            onSuccess: () => {
                setConfirmOpen(false);
                onOpenChange(false);
                form.reset();
            },
            onError: () => toast.error(appActions.requestFailed),
        });
    }

    if (!sale) {
        return null;
    }

    return (
        <>
            <ConfirmActionDialog
                open={confirmOpen}
                onOpenChange={setConfirmOpen}
                title={paymentLabels.confirmSaveTitle}
                description={paymentLabels.confirmSaveBody}
                confirmLabel={paymentLabels.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('{sale}', sale.sale_number || '—')
                                .replace(
                                    '{currency}',
                                    formatPurchaseCurrencyLabel(SALE_BILL_CURRENCY, locale),
                                )}
                        </DialogDescription>
                    </DialogHeader>

                    <div className="rounded-lg border border-border bg-muted/20 p-3">
                        <p className="text-muted-foreground mb-3 text-xs font-medium">
                            {formatPurchaseCurrencyLabel(SALE_BILL_CURRENCY, locale)}
                        </p>
                        <dl className="grid gap-3 text-sm sm:grid-cols-2">
                            {hasDiscount ? (
                                <div>
                                    <dt className="text-muted-foreground">
                                        {labels.totalAmountLabel}
                                    </dt>
                                    <dd className="font-semibold tabular-nums">
                                        {formatMoneyAmountOrDash(sale.total_amount, locale)}
                                    </dd>
                                </div>
                            ) : null}
                            <div>
                                <dt className="text-muted-foreground">{labels.netAmountLabel}</dt>
                                <dd className="font-semibold tabular-nums">
                                    {formatMoneyAmountOrDash(sale.net_amount, locale)}
                                </dd>
                            </div>
                            {hasDiscount ? (
                                <div>
                                    <dt className="text-muted-foreground">
                                        {labels.discountLabel}
                                    </dt>
                                    <dd className="font-semibold tabular-nums">
                                        {formatMoneyAmountOrDash(sale.discount, locale)}
                                    </dd>
                                </div>
                            ) : null}
                            <div>
                                <dt className="text-muted-foreground">{labels.colPaidAmount}</dt>
                                <dd className="font-semibold tabular-nums">
                                    {formatMoneyAmountOrDash(sale.paid_amount, locale)}
                                </dd>
                            </div>
                            <div className={hasDiscount ? 'sm:col-span-2' : ''}>
                                <dt className="text-muted-foreground">{labels.colDue}</dt>
                                <dd className="font-semibold tabular-nums text-amber-700 dark:text-amber-400">
                                    {formatMoneyAmountOrDash(sale.due_amount, locale)}
                                </dd>
                            </div>
                        </dl>
                    </div>

                    <form onSubmit={handleSubmit} className="space-y-4">
                        <SupplierPaymentFields
                            labels={paymentLabels}
                            locale={locale}
                            currencies={currencies}
                            paymentMethods={paymentMethods}
                            billCurrency={SALE_BILL_CURRENCY}
                            maxBillAmount={maxBillAmount}
                            data={form.data}
                            errors={{
                                amount: fieldError('amount'),
                                paid_at: fieldError('paid_at'),
                                exchange_rate: fieldError('exchange_rate'),
                            }}
                            onChange={handleFieldChange}
                            idPrefix="sale-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
                                    ? paymentLabels.savingPayment
                                    : paymentLabels.savePayment}
                            </Button>
                        </DialogFooter>
                    </form>
                </DialogContent>
            </Dialog>
        </>
    );
}
