import { FrDateInput } from '@/components/fr-date-input';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { useTranslation } from '@/hooks/use-translation';
import { useForm } from '@inertiajs/react';
import * as React from 'react';
import { fmtMillimes, libellePaiement, MODES_PAIEMENT } from './format';
import type { RetenueLigne } from './types';

interface Props {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    declarationId: number;
    ligne: RetenueLigne | null;
    /** Déclaration déposée : le suivi de paiement est figé lui aussi. */
}

/**
 * Suivi du paiement du net (« VT UIB LE 12/02/2026 »).
 *
 * Ces champs restent modifiables après la clôture — le virement de janvier est
 * saisi en février — et ne se figent qu'une fois la déclaration déposée.
 */
export function PaymentDialog({ open, onOpenChange, declarationId, ligne }: Props) {
    const { t } = useTranslation();

    // Type alias explicite : sans lui, `useForm` infère `est_paye: false`
    // (type littéral) et la case à cocher ne peut plus être remise à `true`.
    type PaiementForm = {
        est_paye: boolean;
        date_paiement: string;
        mode_paiement: string;
        banque: string;
        reference_paiement: string;
    };

    const form = useForm<PaiementForm>({
        est_paye: false,
        date_paiement: '',
        mode_paiement: '',
        banque: '',
        reference_paiement: '',
    });
    const { data, setData, processing, clearErrors } = form;
    const errors = form.errors as Record<string, string | undefined>;

    // Dialogue monté en permanence : ré-hydratation à l'ouverture.
    React.useEffect(() => {
        if (!open) return;
        clearErrors();
        setData({
            est_paye: ligne?.est_paye ?? false,
            date_paiement: ligne?.date_paiement ?? '',
            mode_paiement: ligne?.mode_paiement ?? '',
            banque: ligne?.banque ?? '',
            reference_paiement: ligne?.reference_paiement ?? '',
        });
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [open, ligne?.id]);

    const apercu = libellePaiement({
        est_paye: data.est_paye,
        date_paiement: data.date_paiement || null,
        mode_paiement: data.mode_paiement || null,
        banque: data.banque || null,
    });

    const submit = (event: React.FormEvent) => {
        event.preventDefault();
        if (!ligne) return;

        form.transform((current) => ({
            est_paye: current.est_paye,
            date_paiement: current.date_paiement || null,
            mode_paiement: current.mode_paiement || null,
            banque: current.banque.trim() || null,
            reference_paiement: current.reference_paiement.trim() || null,
        }));
        form.post(route('retenue.lignes.paiement', { id: declarationId, ligne: ligne.id }), {
            preserveScroll: true,
            onSuccess: () => onOpenChange(false),
        });
    };

    return (
        <Dialog open={open} onOpenChange={onOpenChange}>
            <DialogContent
                className="max-h-[90vh] overflow-y-auto sm:max-w-md"
                /**
                 * Un formulaire de saisie ne se ferme jamais sur un clic à côté :
                 * le calendrier de FrDateInput s'ouvre dans un portail, donc Radix
                 * interprétait le choix d'une date comme un clic « à l'extérieur »
                 * et vidait tout le formulaire. Échap et les boutons Annuler / ×
                 * restent les seules sorties.
                 */
                onInteractOutside={(e) => e.preventDefault()}
            >
                <DialogHeader>
                    <DialogTitle>{t('retenue', 'mark_paid')}</DialogTitle>
                    <DialogDescription>{ligne ? `${ligne.beneficiaire_nom} — ${fmtMillimes(ligne.montant_net)} TND` : ''}</DialogDescription>
                </DialogHeader>

                <form onSubmit={submit} className="flex flex-col gap-4">
                    <div className="flex items-center gap-2">
                        <Checkbox
                            id="retenue-est-paye"
                            checked={data.est_paye}
                            onCheckedChange={(checked) => setData('est_paye', checked === true)}
                        />
                        <Label htmlFor="retenue-est-paye">{t('retenue', 'paid')}</Label>
                    </div>

                    <div className="flex flex-col gap-1.5">
                        <Label>{t('retenue', 'payment_date')}</Label>
                        <FrDateInput
                            value={data.date_paiement}
                            onChange={(iso) => setData('date_paiement', iso)}
                            disabled={!data.est_paye}
                            inputClassName="h-9"
                        />
                        <FieldError message={errors.date_paiement} />
                    </div>

                    <div className="flex flex-col gap-1.5">
                        <Label>{t('retenue', 'payment_mode')}</Label>
                        <Select
                            value={data.mode_paiement || undefined}
                            disabled={!data.est_paye}
                            onValueChange={(value) => setData('mode_paiement', value)}
                        >
                            <SelectTrigger>
                                <SelectValue placeholder={t('retenue', 'payment_mode')} />
                            </SelectTrigger>
                            <SelectContent>
                                {MODES_PAIEMENT.map((mode) => (
                                    <SelectItem key={mode} value={mode}>
                                        {mode}
                                    </SelectItem>
                                ))}
                            </SelectContent>
                        </Select>
                        <FieldError message={errors.mode_paiement} />
                    </div>

                    <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
                        <div className="flex flex-col gap-1.5">
                            <Label htmlFor="retenue-banque">{t('retenue', 'payment_bank')}</Label>
                            <Input
                                id="retenue-banque"
                                value={data.banque}
                                disabled={!data.est_paye}
                                onChange={(e) => setData('banque', e.target.value)}
                                maxLength={60}
                            />
                            <FieldError message={errors.banque} />
                        </div>
                        <div className="flex flex-col gap-1.5">
                            <Label htmlFor="retenue-reference">{t('retenue', 'payment_reference')}</Label>
                            <Input
                                id="retenue-reference"
                                value={data.reference_paiement}
                                disabled={!data.est_paye}
                                onChange={(e) => setData('reference_paiement', e.target.value)}
                                maxLength={100}
                            />
                            <FieldError message={errors.reference_paiement} />
                        </div>
                    </div>

                    {/* Aperçu du libellé tel qu'il sera stocké par le serveur. */}
                    <p className="bg-muted/40 rounded-md border px-3 py-2 text-xs">
                        {t('retenue', 'payment_preview')} : <strong className="tabular-nums">{apercu ?? t('retenue', 'unpaid')}</strong>
                    </p>

                    <DialogFooter>
                        <Button type="button" variant="outline" onClick={() => onOpenChange(false)}>
                            {t('retenue', 'cancel')}
                        </Button>
                        <Button type="submit" disabled={processing}>
                            {t('retenue', 'save')}
                        </Button>
                    </DialogFooter>
                </form>
            </DialogContent>
        </Dialog>
    );
}

function FieldError({ message }: { message?: string }) {
    if (!message) return null;
    return <p className="text-destructive text-xs">{message}</p>;
}
