import { FrDateInput } from '@/components/fr-date-input';
import { todayIso } from '@/components/fr-date';
import InputError from '@/components/input-error';
import {
    AlertDialog,
    AlertDialogAction,
    AlertDialogCancel,
    AlertDialogContent,
    AlertDialogDescription,
    AlertDialogFooter,
    AlertDialogHeader,
    AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { Button } from '@/components/ui/button';
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Spinner } from '@/components/ui/spinner';
import { Textarea } from '@/components/ui/textarea';
import { useTranslation } from '@/hooks/use-translation';
import { router } from '@inertiajs/react';
import { CheckCircle2, CircleAlert } from 'lucide-react';
import { useEffect, useState } from 'react';
import { fmtDate, fmtMontant, TYPE_LIBELLE } from '../format';
import type { Devise, FactureType } from '../types';

export interface Verification {
    ok: boolean;
    texte: string;
    /** Id du champ à corriger : un point rouge cliquable y amène directement. */
    cible?: string;
}

/**
 * Confirmation d'émission. Dit ce qui va se passer — le numéro, le gel du
 * contenu — et liste ce que le serveur vérifiera, pour que l'erreur éventuelle
 * se voie AVANT le clic.
 */
export function EmitDialog({
    open,
    onOpenChange,
    type,
    numero,
    verifications,
    enCours,
    onConfirmer,
    onAller,
}: {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    type: FactureType;
    numero: string;
    verifications: Verification[];
    enCours: boolean;
    onConfirmer: () => void;
    /** Ferme la fenêtre et place le curseur dans le champ à corriger. */
    onAller: (cible: string) => void;
}) {
    const { t } = useTranslation();
    const bloque = verifications.some((v) => !v.ok);
    const libelle = TYPE_LIBELLE[type].toLowerCase();

    return (
        <Dialog open={open} onOpenChange={(o) => !enCours && onOpenChange(o)}>
            <DialogContent className="sm:max-w-md">
                <DialogHeader>
                    <DialogTitle>{t('factures', 'editeur.emettre_titre', 'Émettre la {type} ?').replace('{type}', libelle)}</DialogTitle>
                    <DialogDescription>
                        {bloque
                            ? t('factures', 'editeur.emettre_bloque', 'Complétez les points en rouge avant d\'émettre.')
                            : t(
                                  'factures',
                                  'editeur.emettre_texte',
                                  'Elle recevra le numéro {numero} et son contenu sera figé. Une erreur se corrigera ensuite par un avoir, jamais en la modifiant.',
                              ).replace('{numero}', numero)}
                    </DialogDescription>
                </DialogHeader>
                <ul className="grid gap-2 text-sm">
                    {verifications.map((v) => (
                        <li key={v.texte}>
                            {!v.ok && v.cible ? (
                                <button
                                    type="button"
                                    onClick={() => v.cible && onAller(v.cible)}
                                    className="group flex w-full items-center gap-2 rounded-md px-1 py-0.5 text-left text-rose-700 hover:bg-rose-50"
                                >
                                    <CircleAlert className="h-4 w-4 shrink-0 text-rose-600" />
                                    <span className="underline decoration-rose-300 underline-offset-2 group-hover:decoration-rose-600">{v.texte}</span>
                                    <span className="ml-auto text-xs text-rose-500">{t('factures', 'editeur.corriger', 'Corriger →')}</span>
                                </button>
                            ) : (
                                <span className="flex items-center gap-2 px-1 py-0.5">
                                    {v.ok ? <CheckCircle2 className="h-4 w-4 shrink-0 text-emerald-600" /> : <CircleAlert className="h-4 w-4 shrink-0 text-rose-600" />}
                                    <span className={v.ok ? '' : 'text-rose-700'}>{v.texte}</span>
                                </span>
                            )}
                        </li>
                    ))}
                </ul>
                <DialogFooter>
                    <Button variant="outline" onClick={() => onOpenChange(false)} disabled={enCours}>
                        {t('factures', 'editeur.annuler', 'Annuler')}
                    </Button>
                    {!bloque && (
                        <Button className="bg-secondary hover:bg-secondary/90" onClick={onConfirmer} disabled={enCours}>
                            {enCours && <Spinner size="sm" className="mr-2 text-white" />}
                            {t('factures', 'editeur.emettre_numero', 'Émettre {numero}').replace('{numero}', numero)}
                        </Button>
                    )}
                </DialogFooter>
            </DialogContent>
        </Dialog>
    );
}

/** Envoi par e-mail, PDF joint. L'adresse est montrée et modifiable avant l'envoi. */
export function SendDialog({
    open,
    onOpenChange,
    factureId,
    numero,
    emailParDefaut,
}: {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    factureId: number;
    numero: string;
    emailParDefaut: string | null;
}) {
    const { t } = useTranslation();
    const [email, setEmail] = useState(emailParDefaut ?? '');
    const [message, setMessage] = useState('');
    const [enCours, setEnCours] = useState(false);
    const [erreur, setErreur] = useState<string | undefined>();

    useEffect(() => {
        if (open) {
            setEmail(emailParDefaut ?? '');
            setErreur(undefined);
        }
    }, [open, emailParDefaut]);

    const envoyer = () => {
        router.post(
            route('factures.envoyer', factureId),
            { email, message: message || null },
            {
                preserveScroll: true,
                onStart: () => setEnCours(true),
                onFinish: () => setEnCours(false),
                onError: (e) => setErreur(e.email),
                onSuccess: (page) => {
                    const flash = (page.props as { flash?: { type?: string } }).flash;
                    if (flash?.type !== 'error') onOpenChange(false);
                },
            },
        );
    };

    return (
        <Dialog open={open} onOpenChange={(o) => !enCours && onOpenChange(o)}>
            <DialogContent className="sm:max-w-lg">
                <DialogHeader>
                    <DialogTitle>{t('factures', 'editeur.envoyer_titre', 'Envoyer {numero}').replace('{numero}', numero)}</DialogTitle>
                    <DialogDescription>
                        {t('factures', 'editeur.envoyer_texte', 'Le PDF part en pièce jointe, depuis contact@thelandlord.tn. L\'envoi est immédiat.')}
                    </DialogDescription>
                </DialogHeader>
                <div className="grid gap-3">
                    <div className="grid gap-1.5">
                        <Label htmlFor="envoi_email">{t('factures', 'editeur.envoyer_a', 'Destinataire')}</Label>
                        <Input id="envoi_email" type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="client@exemple.tn" />
                        <InputError message={erreur} />
                    </div>
                    <div className="grid gap-1.5">
                        <Label htmlFor="envoi_message">{t('factures', 'editeur.envoyer_message', 'Message (facultatif)')}</Label>
                        <Textarea
                            id="envoi_message"
                            rows={4}
                            value={message}
                            onChange={(e) => setMessage(e.target.value)}
                            placeholder={t('factures', 'editeur.envoyer_message_defaut', 'Sans message, le courriel dit : « Veuillez trouver ci-joint la facture… »')}
                        />
                    </div>
                </div>
                <DialogFooter>
                    <Button variant="outline" onClick={() => onOpenChange(false)} disabled={enCours}>
                        {t('factures', 'editeur.annuler', 'Annuler')}
                    </Button>
                    <Button className="bg-secondary hover:bg-secondary/90" onClick={envoyer} disabled={enCours || email.trim() === ''}>
                        {enCours && <Spinner size="sm" className="mr-2 text-white" />}
                        {t('factures', 'editeur.envoyer', 'Envoyer')}
                    </Button>
                </DialogFooter>
            </DialogContent>
        </Dialog>
    );
}

/** Date d'encaissement d'une facture. */
export function PaymentDialog({
    open,
    onOpenChange,
    factureId,
    numero,
    montant,
    devise,
}: {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    factureId: number;
    numero: string;
    montant: number;
    devise: Devise;
}) {
    const { t } = useTranslation();
    const [date, setDate] = useState(todayIso());
    const [enCours, setEnCours] = useState(false);
    const [erreur, setErreur] = useState<string | undefined>();

    const valider = () => {
        router.post(
            route('factures.paiement', factureId),
            { payee_le: date },
            {
                preserveScroll: true,
                onStart: () => setEnCours(true),
                onFinish: () => setEnCours(false),
                onError: (e) => setErreur(e.payee_le ?? e.facture),
                onSuccess: () => onOpenChange(false),
            },
        );
    };

    return (
        <Dialog open={open} onOpenChange={(o) => !enCours && onOpenChange(o)}>
            <DialogContent className="sm:max-w-sm">
                <DialogHeader>
                    <DialogTitle>{t('factures', 'editeur.payer_titre', 'Marquer {numero} payée').replace('{numero}', numero)}</DialogTitle>
                    <DialogDescription>
                        {t('factures', 'editeur.payer_texte', 'Montant encaissé : {montant}.').replace('{montant}', fmtMontant(montant, devise))}
                    </DialogDescription>
                </DialogHeader>
                <div className="grid gap-1.5">
                    <Label>{t('factures', 'editeur.payer_date', 'Date du paiement')}</Label>
                    <FrDateInput value={date} onChange={setDate} max={todayIso()} />
                    <InputError message={erreur} />
                </div>
                <DialogFooter>
                    <Button variant="outline" onClick={() => onOpenChange(false)} disabled={enCours}>
                        {t('factures', 'editeur.annuler', 'Annuler')}
                    </Button>
                    <Button className="bg-secondary hover:bg-secondary/90" onClick={valider} disabled={enCours || !date}>
                        {t('factures', 'editeur.payer_valider', 'Marquer payée le {date}').replace('{date}', fmtDate(date))}
                    </Button>
                </DialogFooter>
            </DialogContent>
        </Dialog>
    );
}

/** Confirmation d'une action qui crée ou supprime un document. */
export function ConfirmDialog({
    open,
    onOpenChange,
    titre,
    texte,
    action,
    danger,
    onConfirmer,
}: {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    titre: string;
    texte: string;
    action: string;
    danger?: boolean;
    onConfirmer: () => void;
}) {
    const { t } = useTranslation();

    return (
        <AlertDialog open={open} onOpenChange={onOpenChange}>
            <AlertDialogContent>
                <AlertDialogHeader>
                    <AlertDialogTitle>{titre}</AlertDialogTitle>
                    <AlertDialogDescription>{texte}</AlertDialogDescription>
                </AlertDialogHeader>
                <AlertDialogFooter>
                    <AlertDialogCancel>{t('factures', 'editeur.annuler', 'Annuler')}</AlertDialogCancel>
                    <AlertDialogAction className={danger ? 'bg-rose-600 hover:bg-rose-700' : 'bg-secondary hover:bg-secondary/90'} onClick={onConfirmer}>
                        {action}
                    </AlertDialogAction>
                </AlertDialogFooter>
            </AlertDialogContent>
        </AlertDialog>
    );
}
