import InputError from '@/components/input-error';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import { useTranslation } from '@/hooks/use-translation';
import { cn } from '@/lib/utils';
import axios from 'axios';
import { Info } from 'lucide-react';
import type { FormEvent } from 'react';
import { useState } from 'react';
import { toast } from 'sonner';
import {
    lirePourcentage,
    MONTANT_EXEMPLE,
    montantGarde,
    formatPourcent as pourcent,
    POURCENTAGE_DEFAUT,
    remplir,
    formatTnd as tnd,
    formatUsd as usd,
} from '../payment-rules-utils';
import type { PaymentRuleProps, RegleDePaiement } from '../types';

interface Props {
    logement: { id: number };
    paymentRule: PaymentRuleProps;
}

/**
 * Étape « Règles de paiement » du wizard d'édition (TL-301, siège seulement).
 *
 * Même contrat que EntryInstructionsSection : PATCH en axios et état local,
 * JAMAIS de rechargement Inertia de logements/edit (il rappellerait Rentals
 * United). Chaque carte chiffre sa règle avec les vrais chiffres du logement,
 * sur un versement de 1 000 $US — calcul dans `payment-rules-utils.ts`, miroir
 * de App\Services\Factures\RegleDePaiement::calculer(), ménage converti au taux
 * propriétaire et arrondi au centime comme l'exemple l'affiche.
 */
export default function PaymentRulesSection({ logement, paymentRule }: Props) {
    const { t } = useTranslation();
    const tr = (key: string, fallback: string) => t('properties.payment-rules', key, fallback);

    const [enregistre, setEnregistre] = useState<{ regle: RegleDePaiement; pourcentage: number | null }>({
        regle: paymentRule.regle,
        pourcentage: paymentRule.pourcentage,
    });
    const [regle, setRegle] = useState<RegleDePaiement>(paymentRule.regle);
    const [saisiePct, setSaisiePct] = useState<string>(String(paymentRule.pourcentage ?? POURCENTAGE_DEFAUT));
    const [erreurs, setErreurs] = useState<Record<string, string>>({});
    const [saving, setSaving] = useState(false);

    const pct = lirePourcentage(saisiePct);
    const modifie = regle !== enregistre.regle || (regle === 'pourcentage' && pct !== (enregistre.pourcentage ?? POURCENTAGE_DEFAUT));
    const invalide = regle === 'pourcentage' && pct === null;

    // ---- Exemples chiffrés ----
    // Le ménage en $US vient du serveur (RegleDePaiement::menage) : le même que la facture.
    const { commission, menage_tnd: menageTnd, menage_usd: menageUsd, menage_source: menageSource, menage_taux: menageTaux } = paymentRule;
    const tauxManquant = remplir(tr('example_rate_missing', ''), { menage: tnd(menageTnd) });

    const exemples: Record<RegleDePaiement, string> = {
        menage_commission:
            menageUsd === null
                ? tauxManquant
                : remplir(tr('example_menage_commission', ''), {
                      montant: usd(MONTANT_EXEMPLE),
                      menage: usd(menageUsd),
                      commission: pourcent(commission),
                      reste: usd(MONTANT_EXEMPLE - menageUsd),
                      garde: usd(montantGarde('menage_commission', MONTANT_EXEMPLE, menageUsd, commission, POURCENTAGE_DEFAUT)),
                  }),
        menage:
            menageUsd === null
                ? tauxManquant
                : remplir(tr('example_menage', ''), {
                      montant: usd(MONTANT_EXEMPLE),
                      garde: usd(montantGarde('menage', MONTANT_EXEMPLE, menageUsd, commission, POURCENTAGE_DEFAUT)),
                  }),
        // Le pourcentage ne dépend pas du ménage : cet exemple existe même sans taux.
        pourcentage:
            pct === null
                ? tr('example_pct_invalid', '')
                : remplir(tr('example_pourcentage', ''), {
                      montant: usd(MONTANT_EXEMPLE),
                      pct: pourcent(pct),
                      garde: usd(montantGarde('pourcentage', MONTANT_EXEMPLE, menageUsd ?? 0, commission, pct)),
                  }),
    };

    const options: { valeur: RegleDePaiement; titre: string; aide: string }[] = [
        {
            valeur: 'menage_commission',
            titre: tr('regle_menage_commission', 'Ménage + commission'),
            aide: tr('regle_menage_commission_desc', ''),
        },
        { valeur: 'menage', titre: tr('regle_menage', 'Ménage'), aide: tr('regle_menage_desc', '') },
        { valeur: 'pourcentage', titre: tr('regle_pourcentage', 'Tout le montant (100 %)'), aide: tr('regle_pourcentage_desc', '') },
    ];

    async function enregistrer(event: FormEvent) {
        event.preventDefault();
        if (invalide) {
            setErreurs({ regle_paiement_pct: tr('example_pct_invalid', '') });
            return;
        }

        setSaving(true);
        setErreurs({});
        try {
            const res = await axios.patch<{ ok: boolean; regle_paiement: RegleDePaiement; regle_paiement_pct: number | null }>(
                route('logements.payment-rule.update', logement.id),
                { regle_paiement: regle, regle_paiement_pct: regle === 'pourcentage' ? pct : null },
            );
            setEnregistre({ regle: res.data.regle_paiement, pourcentage: res.data.regle_paiement_pct });
            toast.success(tr('saved', 'Règle de paiement enregistrée.'));
        } catch (e) {
            const resp = (e as { response?: { status?: number; data?: { errors?: Record<string, string[]> } } }).response;
            if (resp?.status === 422 && resp.data?.errors) {
                setErreurs(Object.fromEntries(Object.entries(resp.data.errors).map(([k, v]) => [k, v[0]])));
            } else {
                toast.error(tr('save_error', 'Erreur lors de l’enregistrement.'));
            }
        } finally {
            setSaving(false);
        }
    }

    return (
        <div className="flex flex-col gap-6">
            <div>
                <h2 className="text-primary text-xl font-semibold">{tr('page_title', 'Règles de paiement')}</h2>
                <p className="text-muted-foreground mt-1 text-sm">{tr('page_subtitle', '')}</p>
            </div>

            <form onSubmit={enregistrer}>
                <Card>
                    <CardContent className="space-y-6 pt-6">
                        <RadioGroup
                            value={regle}
                            onValueChange={(valeur) => setRegle(valeur as RegleDePaiement)}
                            className="grid-cols-1"
                            aria-label={tr('page_title', 'Règles de paiement')}
                        >
                            {options.map((option) => {
                                const choisie = regle === option.valeur;
                                const id = `payment-rule-${option.valeur}`;

                                return (
                                    <div
                                        key={option.valeur}
                                        className={cn(
                                            'rounded-lg border transition-colors',
                                            choisie ? 'border-secondary bg-secondary/5' : 'hover:bg-muted/40',
                                        )}
                                    >
                                        <Label htmlFor={id} className="flex cursor-pointer items-start gap-3 p-4 font-normal">
                                            <RadioGroupItem value={option.valeur} id={id} className="mt-0.5" />
                                            <span className="grid min-w-0 flex-1 gap-1">
                                                <span className="flex flex-wrap items-center gap-2 text-sm font-medium">
                                                    {option.titre}
                                                    {option.valeur === 'menage_commission' && (
                                                        <Badge variant="outline" className="font-normal">
                                                            {tr('default_badge', 'Par défaut')}
                                                        </Badge>
                                                    )}
                                                </span>
                                                <span className="text-muted-foreground text-xs">{option.aide}</span>
                                                <span className="text-sm tabular-nums">{exemples[option.valeur]}</span>
                                            </span>
                                        </Label>

                                        {/* Le pourcentage n'appartient qu'à cette règle : le champ
                                            vit HORS du <label> du bouton radio (un <label> ne
                                            contient qu'un seul contrôle). */}
                                        {option.valeur === 'pourcentage' && choisie && (
                                            <div className="flex flex-col gap-1 border-t px-4 py-3 sm:pl-11">
                                                <Label htmlFor="payment-rule-pct">{tr('pourcentage_label', 'Pourcentage gardé')}</Label>
                                                <div className="flex items-center gap-2">
                                                    <Input
                                                        id="payment-rule-pct"
                                                        type="number"
                                                        inputMode="decimal"
                                                        min={0}
                                                        max={100}
                                                        step={0.01}
                                                        value={saisiePct}
                                                        onChange={(e) => setSaisiePct(e.target.value)}
                                                        aria-invalid={invalide || Boolean(erreurs.regle_paiement_pct)}
                                                        className="w-32"
                                                    />
                                                    <span className="text-muted-foreground text-sm">%</span>
                                                </div>
                                                <InputError message={erreurs.regle_paiement_pct} />
                                            </div>
                                        )}
                                    </div>
                                );
                            })}
                        </RadioGroup>
                        <InputError message={erreurs.regle_paiement} />

                        <div className="flex justify-end">
                            <Button type="submit" disabled={saving || !modifie || invalide}>
                                {saving ? tr('saving', 'Enregistrement…') : tr('save', 'Enregistrer')}
                            </Button>
                        </div>
                    </CardContent>
                </Card>
            </form>

            {/* D'où viennent les chiffres des exemples — ils se modifient ailleurs. */}
            <Card>
                <CardHeader>
                    <CardTitle className="text-base">{tr('data_title', 'Chiffres utilisés')}</CardTitle>
                </CardHeader>
                <CardContent>
                    <ul className="text-muted-foreground list-disc space-y-1 pl-5 text-sm">
                        <li>
                            {paymentRule.commission_saisie
                                ? remplir(tr('data_commission', ''), { commission: pourcent(commission) })
                                : remplir(tr('data_commission_default', ''), { commission: pourcent(commission) })}
                        </li>
                        <li>
                            {menageUsd === null || menageSource === null
                                ? remplir(tr('data_menage_sans_taux', ''), { tnd: tnd(menageTnd) })
                                : menageUsd === 0
                                  ? tr('data_menage_zero', '')
                                  : remplir(tr(`data_menage_${menageSource}`, ''), {
                                        menage: usd(menageUsd),
                                        tnd: tnd(menageTnd),
                                        taux: menageTaux ? menageTaux.toLocaleString('fr-FR', { maximumFractionDigits: 3 }) : '',
                                    })}
                        </li>
                    </ul>
                </CardContent>
            </Card>

            <div className="bg-muted/30 text-muted-foreground flex items-start gap-2 rounded-lg border p-3 text-sm">
                <Info className="mt-0.5 h-4 w-4 shrink-0" aria-hidden="true" />
                <p>{tr('cohost_note', '')}</p>
            </div>
        </div>
    );
}
