import React, { useEffect, useMemo, useState } from 'react';
import Layout from '../../components/Layout';
import { api } from '../../lib/api';
import { useNavigate, useParams } from 'react-router-dom';
import { toast } from 'sonner';
import { ArrowLeft, Save, Trash2, Truck, Plus, FileDown, Package, X, Calendar as CalendarIcon, Clock, BookUser } from 'lucide-react';
import { Popover, PopoverContent, PopoverTrigger } from '../../components/ui/popover';
import { Calendar } from '../../components/ui/calendar';
import ClientPickerModal, { formatClientForBordereau } from './ClientPickerModal';

const emptyItem = () => ({
    fournisseur: '', nbre_pal: 0, nbre_colis: 0, ref: '',
});

const todayISO = () => new Date().toISOString().slice(0, 10);

const pad2 = (n) => String(n).padStart(2, '0');

// Parse "JJ/MM/AAAA HH:MM" -> { date: Date|null, time: "HH:MM" }
// Tolère aussi "JJ/MM HH:MM" (sans année => année courante)
const parseLivraison = (s) => {
    if (!s) return { date: null, time: '' };
    const txt = String(s).trim();
    // Capture optional date (D/M or D/M/Y) and optional time HH:MM
    const m = txt.match(/^(\d{1,2})\/(\d{1,2})(?:\/(\d{2,4}))?(?:\s+(\d{1,2}):(\d{2}))?$/);
    if (!m) return { date: null, time: '' };
    const d = parseInt(m[1], 10);
    const mo = parseInt(m[2], 10);
    let y = m[3] ? parseInt(m[3], 10) : new Date().getFullYear();
    if (y < 100) y += 2000;
    const hh = m[4] ? parseInt(m[4], 10) : 0;
    const mm = m[5] ? parseInt(m[5], 10) : 0;
    const date = new Date(y, mo - 1, d, hh, mm, 0, 0);
    const time = m[4] ? `${pad2(hh)}:${pad2(mm)}` : '';
    return { date, time };
};

// Format Date+time -> "JJ/MM/AAAA HH:MM" (ou "JJ/MM/AAAA" si time vide)
const formatLivraison = (date, time) => {
    if (!date) return '';
    const s = `${pad2(date.getDate())}/${pad2(date.getMonth() + 1)}/${date.getFullYear()}`;
    return time ? `${s} ${time}` : s;
};

export default function SavForm() {
    const { id } = useParams();
    const isEdit = !!id;
    const navigate = useNavigate();

    const [date, setDate] = useState(todayISO());
    const [dateOpen, setDateOpen] = useState(false);
    const [livraisonDate, setLivraisonDate] = useState(null);
    const [livraisonTime, setLivraisonTime] = useState('');
    const [livraisonOpen, setLivraisonOpen] = useState(false);
    const [immatriculation, setImmatriculation] = useState('');
    const [temperature, setTemperature] = useState('+2 / +4°C');
    const [transporteur, setTransporteur] = useState('');
    const [destinataire, setDestinataire] = useState('');
    const [items, setItems] = useState([emptyItem()]);
    const [loading, setLoading] = useState(isEdit);
    const [saving, setSaving] = useState(false);
    const [pickerKind, setPickerKind] = useState(null); // 'transporteur' | 'destinataire' | null

    useEffect(() => {
        if (!isEdit) return;
        api.get(`/gp/sav/${id}`)
            .then((r) => {
                const b = r.data;
                setDate(b.date_bordereau || todayISO());
                const parsed = parseLivraison(b.livraison || '');
                setLivraisonDate(parsed.date);
                setLivraisonTime(parsed.time);
                setImmatriculation(b.immatriculation || '');
                setTemperature(b.temperature || '');
                setTransporteur(b.transporteur || '');
                setDestinataire(b.destinataire || '');
                setItems((b.items && b.items.length > 0) ? b.items.map((i) => ({
                    fournisseur: i.fournisseur || '', nbre_pal: i.nbre_pal || 0, nbre_colis: i.nbre_colis || 0,
                    ref: i.ref || '',
                })) : [emptyItem()]);
            })
            .catch((err) => { toast.error(err?.response?.data?.detail || 'Erreur'); navigate('/palettes/sav'); })
            .finally(() => setLoading(false));
    }, [id, isEdit, navigate]);

    const totals = useMemo(() => ({
        pal: items.reduce((s, it) => s + (parseInt(it.nbre_pal || 0) || 0), 0),
        colis: items.reduce((s, it) => s + (parseInt(it.nbre_colis || 0) || 0), 0),
        lines: items.filter((it) => (it.fournisseur || '').trim()).length,
    }), [items]);

    const livraisonText = formatLivraison(livraisonDate, livraisonTime);

    const updateItem = (idx, k, v) => setItems((arr) => arr.map((it, i) => (i === idx ? { ...it, [k]: v } : it)));
    const addItem = () => setItems((arr) => [...arr, emptyItem()]);
    const removeItem = (idx) => setItems((arr) => (arr.length === 1 ? [emptyItem()] : arr.filter((_, i) => i !== idx)));

    const save = async () => {
        if (!transporteur.trim() && !destinataire.trim() && totals.lines === 0) {
            toast.error('Renseigne au moins un transporteur/destinataire ou une ligne.');
            return;
        }
        setSaving(true);
        try {
            const payload = {
                date_bordereau: date,
                livraison: livraisonText,
                immatriculation: (immatriculation || '').trim(),
                temperature: (temperature || '').trim(),
                transporteur: transporteur.trim(),
                destinataire: destinataire.trim(),
                items: items.map((it) => ({
                    fournisseur: (it.fournisseur || '').trim(),
                    nbre_pal: Math.max(0, parseInt(it.nbre_pal || 0) || 0),
                    nbre_colis: Math.max(0, parseInt(it.nbre_colis || 0) || 0),
                    ref: (it.ref || '').trim(),
                })),
            };
            const r = isEdit ? await api.patch(`/gp/sav/${id}`, payload) : await api.post('/gp/sav', payload);
            toast.success(isEdit ? `Bordereau mis à jour` : `Bordereau créé`);
            navigate('/palettes/sav');
        } catch (err) { toast.error(err?.response?.data?.detail || 'Erreur'); }
        finally { setSaving(false); }
    };

    const del = async () => {
        if (!window.confirm('Supprimer ce bordereau et toutes ses lignes ?')) return;
        try { await api.delete(`/gp/sav/${id}`); toast.success('Supprimé'); navigate('/palettes/sav'); }
        catch (err) { toast.error(err?.response?.data?.detail || 'Erreur'); }
    };

    const exportPdf = async () => {
        try {
            const r = await api.get('/gp/export-sav-pdf', { params: { bid: id }, responseType: 'blob' });
            const url = window.URL.createObjectURL(new Blob([r.data], { type: 'application/pdf' }));
            const a = document.createElement('a');
            a.href = url; a.download = `bordereau_${id}.pdf`;
            document.body.appendChild(a); a.click(); a.remove();
            window.URL.revokeObjectURL(url);
        } catch { toast.error('Erreur génération PDF'); }
    };

    if (loading) return <Layout><div className="text-slate-500">Chargement…</div></Layout>;

    return (
        <Layout>
            <button onClick={() => navigate('/palettes/sav')} className="mb-4 inline-flex items-center gap-2 text-sm text-slate-600 hover:text-amber-600 transition" data-testid="sav-back">
                <ArrowLeft className="h-4 w-4" /> Retour à la liste
            </button>

            <div className="mb-6 flex items-start justify-between gap-4 flex-wrap">
                <div>
                    <p className="text-xs font-bold uppercase tracking-[0.2em] text-amber-600">Bordereau de Chargement</p>
                    <h1 className="mt-2 font-heading text-2xl sm:text-3xl font-black tracking-tight text-slate-900">
                        {isEdit ? 'Bordereau' : 'Nouveau bordereau'}
                    </h1>
                </div>
                {isEdit && (
                    <button data-testid="sav-export-pdf-detail" onClick={exportPdf} className="inline-flex items-center gap-2 rounded-md border border-amber-500 text-amber-700 bg-white px-4 h-10 text-sm font-bold hover:bg-amber-50">
                        <FileDown className="h-4 w-4" /> Exporter PDF
                    </button>
                )}
            </div>

            <div className="space-y-5">
                {/* Bordereau header */}
                <div className="rounded-lg border border-slate-200 bg-white p-5">
                    <h2 className="font-heading text-base font-bold text-slate-900 mb-4 flex items-center gap-2">
                        <Truck className="h-4 w-4 text-amber-500" /> En-tête du bordereau
                    </h2>
                    <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
                        <div>
                            <label className="text-xs font-bold uppercase tracking-wider text-slate-700">Date du bordereau</label>
                            <Popover open={dateOpen} onOpenChange={setDateOpen}>
                                <PopoverTrigger asChild>
                                    <button
                                        type="button"
                                        data-testid="b-date-trigger"
                                        className="mt-1.5 w-full h-11 rounded-md border border-slate-300 bg-white px-3 text-base text-left flex items-center gap-2 hover:border-amber-400 focus:border-amber-500 focus:outline-none focus:ring-2 focus:ring-amber-500/20"
                                    >
                                        <CalendarIcon className="h-4 w-4 text-amber-500 shrink-0" />
                                        <span className="text-slate-900">
                                            {date ? (() => {
                                                const [y, m, d] = date.split('-');
                                                return `${d}/${m}/${y}`;
                                            })() : 'Choisir une date'}
                                        </span>
                                    </button>
                                </PopoverTrigger>
                                <PopoverContent align="start" className="w-auto p-3">
                                    <Calendar
                                        mode="single"
                                        selected={date ? new Date(date + 'T00:00:00') : undefined}
                                        onSelect={(d) => {
                                            if (d) {
                                                const iso = `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())}`;
                                                setDate(iso);
                                                setDateOpen(false);
                                            }
                                        }}
                                        initialFocus
                                        data-testid="b-date-calendar"
                                    />
                                </PopoverContent>
                            </Popover>
                        </div>
                        <div>
                            <label className="text-xs font-bold uppercase tracking-wider text-slate-700">Date/Heure livraison</label>
                            <Popover open={livraisonOpen} onOpenChange={setLivraisonOpen}>
                                <PopoverTrigger asChild>
                                    <button
                                        type="button"
                                        data-testid="b-livraison-trigger"
                                        className="mt-1.5 w-full h-11 rounded-md border border-slate-300 bg-white px-3 text-base text-left flex items-center gap-2 hover:border-amber-400 focus:border-amber-500 focus:outline-none focus:ring-2 focus:ring-amber-500/20"
                                    >
                                        <CalendarIcon className="h-4 w-4 text-amber-500 shrink-0" />
                                        <span className={livraisonText ? 'text-slate-900' : 'text-slate-400'}>
                                            {livraisonText || 'Choisir date & heure'}
                                        </span>
                                    </button>
                                </PopoverTrigger>
                                <PopoverContent align="start" className="w-auto p-3">
                                    <Calendar
                                        mode="single"
                                        selected={livraisonDate || undefined}
                                        onSelect={(d) => setLivraisonDate(d || null)}
                                        initialFocus
                                        data-testid="b-livraison-calendar"
                                    />
                                    <div className="mt-3 pt-3 border-t border-slate-200 flex items-center gap-2">
                                        <Clock className="h-4 w-4 text-amber-500" />
                                        <label className="text-xs font-bold uppercase tracking-wider text-slate-700">Heure</label>
                                        <input
                                            data-testid="b-livraison-time"
                                            type="time"
                                            value={livraisonTime}
                                            onChange={(e) => setLivraisonTime(e.target.value)}
                                            className="ml-auto h-9 rounded-md border border-slate-300 bg-white px-2 text-sm focus:border-amber-500 focus:outline-none focus:ring-2 focus:ring-amber-500/20"
                                        />
                                    </div>
                                    <div className="mt-3 flex items-center justify-between gap-2">
                                        <button
                                            type="button"
                                            data-testid="b-livraison-clear"
                                            onClick={() => { setLivraisonDate(null); setLivraisonTime(''); }}
                                            className="text-xs text-slate-500 hover:text-red-600 underline"
                                        >
                                            Effacer
                                        </button>
                                        <button
                                            type="button"
                                            data-testid="b-livraison-ok"
                                            onClick={() => setLivraisonOpen(false)}
                                            className="rounded-md bg-amber-500 text-white px-3 h-8 text-xs font-bold hover:bg-amber-600"
                                        >
                                            OK
                                        </button>
                                    </div>
                                </PopoverContent>
                            </Popover>
                        </div>
                        <div className="rounded-md border border-amber-200 bg-amber-50/60 px-3 py-2 flex flex-col justify-end">
                            <p className="text-[10px] font-bold uppercase tracking-wider text-amber-700">Totaux</p>
                            <p className="mt-0.5 text-sm font-bold text-slate-900">
                                {totals.lines} ligne{totals.lines > 1 ? 's' : ''} · {totals.pal} pal · {totals.colis} colis
                            </p>
                        </div>
                        <div>
                            <label className="text-xs font-bold uppercase tracking-wider text-slate-700">Immatriculation</label>
                            <input data-testid="b-immatriculation" value={immatriculation} onChange={(e) => setImmatriculation(e.target.value.toUpperCase())} placeholder="ex. AB-123-CD"
                                   className="mt-1.5 w-full h-11 rounded-md border border-slate-300 bg-white px-3 text-base focus:border-amber-500 focus:outline-none focus:ring-2 focus:ring-amber-500/20" />
                        </div>
                        <div>
                            <label className="text-xs font-bold uppercase tracking-wider text-slate-700">Température</label>
                            <input data-testid="b-temperature" value={temperature} onChange={(e) => setTemperature(e.target.value)} placeholder="ex. +2 / +4 °C"
                                   className="mt-1.5 w-full h-11 rounded-md border border-slate-300 bg-white px-3 text-base focus:border-amber-500 focus:outline-none focus:ring-2 focus:ring-amber-500/20" />
                        </div>
                        <div className="hidden md:block" />
                        <div>
                            <div className="flex items-center justify-between">
                                <label className="text-xs font-bold uppercase tracking-wider text-slate-700">Transporteur</label>
                                <button
                                    type="button"
                                    data-testid="b-pick-transporteur"
                                    onClick={() => setPickerKind('transporteur')}
                                    className="inline-flex items-center gap-1 text-[11px] font-bold text-amber-700 hover:text-amber-800 hover:underline"
                                >
                                    <BookUser className="h-3 w-3" /> Choisir un client
                                </button>
                            </div>
                            <textarea data-testid="b-transporteur" value={transporteur} onChange={(e) => setTransporteur(e.target.value)} rows={4} placeholder="Nom, adresse, pays"
                                      className="mt-1.5 w-full rounded-md border border-slate-300 bg-white px-3 py-2 text-sm focus:border-amber-500 focus:outline-none focus:ring-2 focus:ring-amber-500/20" />
                        </div>
                        <div>
                            <div className="flex items-center justify-between">
                                <label className="text-xs font-bold uppercase tracking-wider text-slate-700">Destinataire</label>
                                <button
                                    type="button"
                                    data-testid="b-pick-destinataire"
                                    onClick={() => setPickerKind('destinataire')}
                                    className="inline-flex items-center gap-1 text-[11px] font-bold text-amber-700 hover:text-amber-800 hover:underline"
                                >
                                    <BookUser className="h-3 w-3" /> Choisir un client
                                </button>
                            </div>
                            <textarea data-testid="b-destinataire" value={destinataire} onChange={(e) => setDestinataire(e.target.value)} rows={4} placeholder="Nom, adresse, pays"
                                      className="mt-1.5 w-full rounded-md border border-slate-300 bg-white px-3 py-2 text-sm focus:border-amber-500 focus:outline-none focus:ring-2 focus:ring-amber-500/20" />
                        </div>
                    </div>
                </div>

                {/* Items */}
                <div className="rounded-lg border border-slate-200 bg-white">
                    <div className="flex items-center justify-between px-5 py-3 border-b border-slate-200">
                        <h2 className="font-heading text-base font-bold text-slate-900 flex items-center gap-2">
                            <Package className="h-4 w-4 text-amber-500" /> Fournisseurs / Lignes
                        </h2>
                        <button data-testid="b-add-line" onClick={addItem} className="inline-flex items-center gap-1.5 rounded-md bg-amber-500 text-white px-3 h-9 text-xs font-bold hover:bg-amber-600">
                            <Plus className="h-3.5 w-3.5" /> Ajouter une ligne
                        </button>
                    </div>

                    <div className="divide-y divide-slate-100">
                        {items.map((it, idx) => (
                            <div key={idx} data-testid={`b-line-${idx}`} className="px-5 py-4 grid grid-cols-1 md:grid-cols-12 gap-3 items-start">
                                <div className="md:col-span-5">
                                    <label className="text-[10px] font-bold uppercase tracking-wider text-slate-600">Fournisseur / Expéditeur</label>
                                    <input data-testid={`b-fournisseur-${idx}`} value={it.fournisseur} onChange={(e) => updateItem(idx, 'fournisseur', e.target.value)} placeholder="Fournisseur"
                                           className="mt-1 w-full h-10 rounded-md border border-slate-300 bg-white px-3 text-sm focus:border-amber-500 focus:outline-none focus:ring-2 focus:ring-amber-500/20" />
                                </div>
                                <div className="md:col-span-1">
                                    <label className="text-[10px] font-bold uppercase tracking-wider text-slate-600">Pal</label>
                                    <input data-testid={`b-pal-${idx}`} type="number" min={0} value={it.nbre_pal} onChange={(e) => updateItem(idx, 'nbre_pal', Math.max(0, parseInt(e.target.value || 0)))}
                                           className="mt-1 w-full h-10 rounded-md border border-slate-300 bg-white px-2 text-sm text-center focus:border-amber-500 focus:outline-none focus:ring-2 focus:ring-amber-500/20" />
                                </div>
                                <div className="md:col-span-1">
                                    <label className="text-[10px] font-bold uppercase tracking-wider text-slate-600">Colis</label>
                                    <input data-testid={`b-colis-${idx}`} type="number" min={0} value={it.nbre_colis} onChange={(e) => updateItem(idx, 'nbre_colis', Math.max(0, parseInt(e.target.value || 0)))}
                                           className="mt-1 w-full h-10 rounded-md border border-slate-300 bg-white px-2 text-sm text-center focus:border-amber-500 focus:outline-none focus:ring-2 focus:ring-amber-500/20" />
                                </div>
                                <div className="md:col-span-4">
                                    <label className="text-[10px] font-bold uppercase tracking-wider text-slate-600">Commentaire</label>
                                    <textarea data-testid={`b-ref-${idx}`} value={it.ref} onChange={(e) => updateItem(idx, 'ref', e.target.value)} rows={2} placeholder="1 commentaire par ligne"
                                              className="mt-1 w-full rounded-md border border-slate-300 bg-white px-3 py-2 text-sm focus:border-amber-500 focus:outline-none focus:ring-2 focus:ring-amber-500/20" />
                                </div>
                                <div className="md:col-span-1 flex md:justify-end md:pt-6">
                                    <button onClick={() => removeItem(idx)} className="inline-flex h-9 w-9 items-center justify-center rounded-md text-slate-400 hover:text-red-600 hover:bg-red-50" title="Supprimer la ligne" data-testid={`b-rm-line-${idx}`}>
                                        <X className="h-4 w-4" />
                                    </button>
                                </div>
                            </div>
                        ))}
                    </div>
                </div>

                <div className="flex flex-wrap items-center justify-between gap-3">
                    <div>
                        {isEdit && (
                            <button data-testid="b-delete-btn" onClick={del} className="inline-flex items-center gap-2 rounded-md border border-red-300 bg-white px-4 h-11 text-sm font-bold text-red-700 hover:bg-red-50">
                                <Trash2 className="h-4 w-4" /> Supprimer le bordereau
                            </button>
                        )}
                    </div>
                    <button data-testid="b-save-btn" onClick={save} disabled={saving} className="inline-flex items-center gap-2 rounded-md bg-amber-500 text-white px-6 h-11 text-sm font-heading font-bold hover:bg-amber-600 active:scale-[0.99] transition-all disabled:opacity-60">
                        <Save className="h-4 w-4" /> {saving ? 'Enregistrement…' : (isEdit ? 'Enregistrer' : 'Créer le bordereau')}
                    </button>
                </div>
            </div>

            {pickerKind && (
                <ClientPickerModal
                    kind={pickerKind}
                    onClose={() => setPickerKind(null)}
                    onManage={() => { setPickerKind(null); navigate('/palettes/sav/clients'); }}
                    onPick={(c) => {
                        const text = formatClientForBordereau(c);
                        if (pickerKind === 'transporteur') setTransporteur(text);
                        else setDestinataire(text);
                        setPickerKind(null);
                    }}
                />
            )}
        </Layout>
    );
}
