import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Spinner } from '@/components/ui/spinner';
import { useTranslation } from '@/hooks/use-translation';
import { Link, router } from '@inertiajs/react';
import { AlertTriangle, CheckCircle2, CircleSlash, Plus, ScaleIcon, ShieldCheck } from 'lucide-react';
import * as React from 'react';
import { fmtMillimes } from './format';
import type { RetenueVerification } from './types';

interface Props {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    declarationId: number;
    verification: RetenueVerification | null;
    canUpdate: boolean;
}

/** En-tête de section : icône + titre + compteur, avec un emplacement à droite. */
function SectionHeader({ icon, title, aside, tone }: { icon: React.ReactNode; title: string; aside?: React.ReactNode; tone: string }) {
    return (
        <div className="flex flex-wrap items-baseline justify-between gap-x-3 gap-y-1">
            <h3 className={`flex items-center gap-2 text-sm font-semibold ${tone}`}>
                {icon}
                {title}
            </h3>
            {aside}
        </div>
    );
}

/**
 * Panneau « Vérifier » — contrôle en lecture seule de la déclaration.
 *
 * Il ne calcule rien : tout vient de la prop Inertia `verification`, produite à
 * la demande par le serveur. Le seul geste d'écriture est l'ajout d'une ligne
 * pour un logement oublié, et là encore le montant est recalculé côté serveur.
 *
 * Reste utile sur une déclaration clôturée : le contrôle sert alors à justifier
 * après coup (les boutons d'ajout, eux, disparaissent).
 */
export function VerificationPanel({ open, onOpenChange, declarationId, verification, canUpdate }: Props) {
    const { t } = useTranslation();

    // Le POST d'ajout ne recalcule pas `verification` (prop optionnelle, absente
    // du rendu normal) : on garde en mémoire les logements déjà ajoutés pour que
    // la liste reste lisible jusqu'au prochain « Vérifier ».
    const [ajoutes, setAjoutes] = React.useState<number[]>([]);
    const [ajoutEnCours, setAjoutEnCours] = React.useState<number | null>(null);

    // Nouveau rapport ⇒ la mémoire locale des ajouts n'a plus lieu d'être.
    React.useEffect(() => {
        setAjoutes([]);
        setAjoutEnCours(null);
    }, [verification]);

    const ajouter = (propertyId: number) => {
        router.post(
            route('retenue.lignes.logement', { id: declarationId, property: propertyId }),
            {},
            {
                preserveScroll: true,
                // Sans ça Inertia remonte la page : le panneau se fermerait et
                // l'état « Ajouté » serait perdu à chaque clic.
                preserveState: true,
                onStart: () => setAjoutEnCours(propertyId),
                onSuccess: () => setAjoutes((prev) => (prev.includes(propertyId) ? prev : [...prev, propertyId])),
                onFinish: () => setAjoutEnCours(null),
            },
        );
    };

    // ⚠️ PLUS DE `!isLocked` : le serveur accepte désormais une ligne sur une
    // période clôturée ou déposée. Le garder ici ferait mentir l'écran.
    const peutAjouter = canUpdate;

    const oublies = verification?.logements_oublies ?? [];
    const ecarts = verification?.ecarts ?? [];
    const nonDeposables = verification?.lignes_non_deposables ?? [];
    const montantsNuls = verification?.montants_nuls ?? [];

    return (
        <Dialog open={open} onOpenChange={onOpenChange}>
            <DialogContent className="sm:max-w-3xl">
                <DialogHeader>
                    <DialogTitle className="flex items-center gap-2">
                        <ShieldCheck className="h-5 w-5" />
                        {t('retenue', 'verify')}
                    </DialogTitle>
                    <DialogDescription>{t('retenue', 'verify_hint')}</DialogDescription>
                </DialogHeader>

                {verification && (
                    <div className="flex max-h-[70vh] flex-col gap-5 overflow-y-auto pr-1">
                        {verification.rien_a_signaler ? (
                            <div className="flex items-center gap-2 rounded-md border border-emerald-300 bg-emerald-50 px-4 py-3 text-sm text-emerald-900">
                                <CheckCircle2 className="h-5 w-5 shrink-0 text-emerald-600" />
                                {t('retenue', 'verify_nothing')}
                            </div>
                        ) : (
                            <>
                                {/* 1 — Logements oubliés : la seule section actionnable. */}
                                {oublies.length > 0 && (
                                    <section className="flex flex-col gap-2">
                                        <SectionHeader
                                            tone="text-amber-900"
                                            icon={<AlertTriangle className="h-4 w-4 shrink-0" />}
                                            title={t('retenue', 'verify_forgotten').replace(':count', String(oublies.length))}
                                            aside={
                                                <span className="text-sm font-semibold text-amber-900 tabular-nums">
                                                    {t('retenue', 'verify_forgotten_total').replace(
                                                        ':montant',
                                                        fmtMillimes(verification.total_oublie),
                                                    )}
                                                </span>
                                            }
                                        />
                                        <p className="text-muted-foreground text-xs">{t('retenue', 'verify_forgotten_hint')}</p>
                                        <ul className="divide-y divide-amber-200 rounded-md border border-amber-300 bg-amber-50">
                                            {oublies.map((oubli) => {
                                                const ajoute = ajoutes.includes(oubli.property_id);
                                                return (
                                                    <li
                                                        key={oubli.property_id}
                                                        className={`flex flex-wrap items-center gap-x-3 gap-y-1 px-3 py-2 text-sm ${
                                                            ajoute ? 'opacity-50' : ''
                                                        }`}
                                                    >
                                                        <span className="font-medium text-amber-950">
                                                            {oubli.property_nom ?? oubli.property_uid ?? `#${oubli.property_id}`}
                                                        </span>
                                                        <span className="text-amber-800">{oubli.beneficiaire_nom}</span>
                                                        {!oubli.identite_complete && (
                                                            <Badge variant="outline" className="border-red-300 text-red-700">
                                                                <AlertTriangle className="h-3 w-3" />
                                                                {t('retenue', 'identity_incomplete')}
                                                            </Badge>
                                                        )}
                                                        <span className="ml-auto font-semibold text-amber-950 tabular-nums">
                                                            {fmtMillimes(oubli.montant_calcule)}
                                                        </span>
                                                        {peutAjouter &&
                                                            (ajoute ? (
                                                                <Badge variant="secondary">
                                                                    <CheckCircle2 className="h-3 w-3" />
                                                                    {t('retenue', 'verify_added')}
                                                                </Badge>
                                                            ) : (
                                                                <Button
                                                                    size="sm"
                                                                    variant="outline"
                                                                    disabled={ajoutEnCours !== null}
                                                                    onClick={() => ajouter(oubli.property_id)}
                                                                >
                                                                    {ajoutEnCours === oubli.property_id ? (
                                                                        <Spinner size="sm" className="text-current" />
                                                                    ) : (
                                                                        <Plus className="h-4 w-4" />
                                                                    )}
                                                                    {t('retenue', 'verify_add')}
                                                                </Button>
                                                            ))}
                                                    </li>
                                                );
                                            })}
                                        </ul>
                                    </section>
                                )}

                                {/* 2 — Écarts : information seule, l'utilisateur arbitre. */}
                                {ecarts.length > 0 && (
                                    <section className="flex flex-col gap-2">
                                        <SectionHeader
                                            tone="text-foreground"
                                            icon={<ScaleIcon className="h-4 w-4 shrink-0" />}
                                            title={t('retenue', 'verify_gaps').replace(':count', String(ecarts.length))}
                                        />
                                        <p className="text-muted-foreground text-xs">{t('retenue', 'verify_gaps_hint')}</p>
                                        <ul className="divide-border divide-y rounded-md border">
                                            {ecarts.map((ecart) => (
                                                <li key={ecart.ligne_id} className="flex flex-col gap-1 px-3 py-2 text-sm">
                                                    {/* Pas de pastille « Manuel » ici : toute ligne listée
                                                        dans cette section a, par définition, un montant
                                                        déclaré différent du montant calculé. */}
                                                    <div className="flex flex-wrap items-center gap-x-2 gap-y-1">
                                                        <span className="font-medium">{ecart.beneficiaire_nom}</span>
                                                        {ecart.property_nom && (
                                                            <span className="text-muted-foreground text-xs">{ecart.property_nom}</span>
                                                        )}
                                                    </div>
                                                    <div className="flex flex-wrap gap-x-4 gap-y-1 text-xs tabular-nums">
                                                        <span className="text-muted-foreground">
                                                            {t('retenue', 'verify_entered')} : {fmtMillimes(ecart.montant_saisi)}
                                                        </span>
                                                        <span className="text-muted-foreground">
                                                            {t('retenue', 'verify_computed')} : {fmtMillimes(ecart.montant_calcule)}
                                                        </span>
                                                        <span className={`font-semibold ${ecart.ecart < 0 ? 'text-red-700' : 'text-amber-700'}`}>
                                                            {t('retenue', 'verify_gap')} : {ecart.ecart > 0 ? '+' : ''}
                                                            {fmtMillimes(ecart.ecart)}
                                                        </span>
                                                    </div>
                                                </li>
                                            ))}
                                        </ul>
                                    </section>
                                )}

                                {/* 3 — Lignes que le DÉPÔT refuserait, avec sa
                                    propre phrase. Ce bloc listait des NOMS sur un
                                    contrôle qui ne regardait que le CIN : il
                                    restait muet sur cinq autres champs exigés, et
                                    l'utilisateur découvrait chaque manque un refus
                                    à la fois. La raison vient désormais du
                                    constructeur du fichier lui-même. */}
                                {nonDeposables.length > 0 && (
                                    <section className="flex flex-col gap-2">
                                        <SectionHeader
                                            tone="text-amber-900"
                                            icon={<AlertTriangle className="h-4 w-4 shrink-0" />}
                                            title={
                                                nonDeposables.length === 1
                                                    ? '1 ligne ne peut pas être déposée'
                                                    : `${nonDeposables.length} lignes ne peuvent pas être déposées`
                                            }
                                        />
                                        <p className="text-muted-foreground text-xs">
                                            Ce que la plateforme refuserait, mot pour mot, et où le corriger.
                                        </p>
                                        <ul className="divide-y divide-amber-200 rounded-md border border-amber-300 bg-amber-50">
                                            {nonDeposables.map((anomalie) => (
                                                <li key={anomalie.ligne_id} className="flex flex-col gap-0.5 px-3 py-2 text-sm text-amber-900">
                                                    <span className="flex flex-wrap items-center gap-x-3">
                                                        {/* `ou` décide de la destination : la fiche du
                                                            bénéficiaire pour une adresse ou un e-mail,
                                                            la ligne elle-même pour une opération TEJ. */}
                                                        {anomalie.ou === 'fiche' ? (
                                                            <Link
                                                                href={`/fournisseurs?search=${encodeURIComponent(anomalie.beneficiaire_nom ?? '')}`}
                                                                className="font-medium underline underline-offset-2 hover:text-amber-950"
                                                            >
                                                                {anomalie.beneficiaire_nom}
                                                            </Link>
                                                        ) : (
                                                            <span className="font-medium">{anomalie.beneficiaire_nom}</span>
                                                        )}
                                                        {anomalie.property_nom && (
                                                            <span className="text-xs text-amber-800">{anomalie.property_nom}</span>
                                                        )}
                                                    </span>
                                                    <ul className="flex flex-col gap-0.5">
                                                        {anomalie.raisons.map((raison, i) => (
                                                            <li key={i} className="text-xs text-amber-800">
                                                                {raison}
                                                            </li>
                                                        ))}
                                                    </ul>
                                                </li>
                                            ))}
                                        </ul>
                                    </section>
                                )}

                                {/* 4 — Montants nuls. */}
                                {montantsNuls.length > 0 && (
                                    <section className="flex flex-col gap-2">
                                        <SectionHeader
                                            tone="text-foreground"
                                            icon={<CircleSlash className="h-4 w-4 shrink-0" />}
                                            title={t('retenue', 'verify_zero_amounts').replace(':count', String(montantsNuls.length))}
                                        />
                                        <ul className="divide-border divide-y rounded-md border">
                                            {montantsNuls.map((anomalie) => (
                                                <li key={anomalie.ligne_id} className="flex flex-wrap items-center gap-x-3 gap-y-1 px-3 py-2 text-sm">
                                                    <span className="font-medium">{anomalie.beneficiaire_nom}</span>
                                                    {anomalie.property_nom && (
                                                        <span className="text-muted-foreground text-xs">{anomalie.property_nom}</span>
                                                    )}
                                                </li>
                                            ))}
                                        </ul>
                                    </section>
                                )}
                            </>
                        )}

                        {verification.logements_sans_proprietaire > 0 && (
                            <p className="text-muted-foreground text-xs">
                                {t('retenue', 'verify_properties_without_owner').replace(':count', String(verification.logements_sans_proprietaire))}
                            </p>
                        )}
                    </div>
                )}

                <DialogFooter>
                    <Button variant="outline" onClick={() => onOpenChange(false)}>
                        {t('retenue', 'dismiss')}
                    </Button>
                </DialogFooter>
            </DialogContent>
        </Dialog>
    );
}
