import React, { useEffect, useMemo, useRef, useState } from 'react';
import Layout from '../components/Layout';
import { useNavigate, useParams } from 'react-router-dom';
import { api } from '../lib/api';
import { useAuth } from '../context/AuthContext';
import { toast } from 'sonner';
import StatusBadge from '../components/StatusBadge';
import { ArrowLeft, Truck, ImagePlus, X, CheckCircle2, PlayCircle, RotateCcw, History, Save, Edit3, Trash2, Download, ChevronLeft, ChevronRight, Plus, MessageSquarePlus, ExternalLink, FilePlus2, Mail } from 'lucide-react';
import { resizeImage } from '../lib/image';
import { markFolderSeen } from '../lib/seen';
import FolderEmailModal from '../components/FolderEmailModal';

function downloadDataUrl(dataUrl, filename) {
    const a = document.createElement('a');
    a.href = dataUrl;
    a.download = filename;
    document.body.appendChild(a);
    a.click();
    a.remove();
}

export default function FolderDetail() {
    const { id } = useParams();
    const { user } = useAuth();
    const navigate = useNavigate();
    const [folder, setFolder] = useState(null);
    const [loading, setLoading] = useState(true);

    // Bureau full edit
    const [editing, setEditing] = useState(false);
    const [editProblem, setEditProblem] = useState('');
    const [editPhotos, setEditPhotos] = useState([]);

    // Cariste/Bureau append (timeline new entry)
    const [appending, setAppending] = useState(false);
    const [appendText, setAppendText] = useState('');
    const [appendPhotos, setAppendPhotos] = useState([]);

    const [lightboxIndex, setLightboxIndex] = useState(null);
    const [confirmDelete, setConfirmDelete] = useState(false);
    const [emailOpen, setEmailOpen] = useState(false);
    const galleryRef = useRef(null);
    const appendGalleryRef = useRef(null);

    const load = async () => {
        try {
            const r = await api.get(`/folders/${id}`);
            setFolder(r.data);
            setEditProblem(r.data.problem);
            setEditPhotos(r.data.photos || []);
            markFolderSeen(r.data.id);
        } catch (e) {
            toast.error('Dossier introuvable');
            navigate('/');
        } finally {
            setLoading(false);
        }
    };
    useEffect(() => { load(); /* eslint-disable-next-line */ }, [id]);

    // Build flat list of photos in timeline order (for lightbox navigation)
    const contributions = useMemo(() => folder?.contributions || [], [folder]);
    const allPhotos = useMemo(() => contributions.flatMap((c) => c.photos || []), [contributions]);

    const photoGlobalIndex = (ci, li) => {
        let n = 0;
        for (let i = 0; i < ci; i++) n += (contributions[i].photos || []).length;
        return n + li;
    };

    useEffect(() => {
        const handler = (e) => {
            if (lightboxIndex === null) return;
            if (e.key === 'Escape') setLightboxIndex(null);
            if (e.key === 'ArrowLeft') setLightboxIndex((i) => (i > 0 ? i - 1 : i));
            if (e.key === 'ArrowRight') setLightboxIndex((i) => (allPhotos && i < allPhotos.length - 1 ? i + 1 : i));
        };
        window.addEventListener('keydown', handler);
        return () => window.removeEventListener('keydown', handler);
    }, [lightboxIndex, allPhotos]);

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

    const isBureau = user.role === 'bureau';
    const isOwner = folder.cariste_id === user.id;
    const canAppend = isOwner || isBureau; // bureau can also enrich the timeline
    const canFullEdit = isBureau;

    const handleAction = async (action) => {
        try {
            const r = await api.patch(`/folders/${folder.id}/status`, { action });
            setFolder(r.data);
            const labels = { take: 'Dossier pris en charge', close: 'Dossier clôturé', reopen: 'Dossier rouvert' };
            toast.success(labels[action]);
        } catch (err) {
            toast.error(err?.response?.data?.detail || 'Erreur');
        }
    };

    const handleDelete = async () => {
        try {
            await api.delete(`/folders/${folder.id}`);
            toast.success('Dossier supprimé');
            navigate('/');
        } catch (err) {
            toast.error(err?.response?.data?.detail || 'Erreur');
        }
    };

    const handleFiles = async (files, target) => {
        const current = target === 'append' ? appendPhotos : editPhotos;
        const totalExisting = target === 'append' ? allPhotos.length + appendPhotos.length : editPhotos.length;
        const remaining = 30 - totalExisting;
        if (remaining <= 0) { toast.error('Maximum 30 photos'); return; }
        const arr = Array.from(files).slice(0, remaining);
        const results = [];
        for (const f of arr) {
            try { results.push(await resizeImage(f)); } catch (_) { }
        }
        if (target === 'append') setAppendPhotos((p) => [...p, ...results]);
        else setEditPhotos(() => [...current, ...results]);
    };

    const saveEdit = async () => {
        try {
            const r = await api.patch(`/folders/${folder.id}`, { problem: editProblem, photos: editPhotos });
            setFolder(r.data);
            setEditing(false);
            toast.success('Dossier mis à jour');
        } catch (err) {
            toast.error(err?.response?.data?.detail || 'Erreur');
        }
    };

    const saveAppend = async () => {
        if (!appendText.trim() && appendPhotos.length === 0) {
            toast.error('Ajoute du texte ou des photos');
            return;
        }
        try {
            const r = await api.post(`/folders/${folder.id}/append`, {
                text: appendText.trim() || null,
                photos: appendPhotos.length ? appendPhotos : null,
            });
            setFolder(r.data);
            setAppending(false);
            setAppendText('');
            setAppendPhotos([]);
            toast.success('Mise à jour ajoutée');
        } catch (err) {
            toast.error(err?.response?.data?.detail || 'Erreur');
        }
    };

    return (
        <Layout>
            <button data-testid="back-btn" onClick={() => navigate(-1)} className="mb-5 inline-flex items-center gap-2 text-sm font-semibold text-slate-600 hover:text-stef transition">
                <ArrowLeft className="h-4 w-4" />
                Retour
            </button>

            <div className="flex items-start justify-between gap-3 mb-6 flex-wrap">
                <div className="min-w-0">
                    <div className="flex items-center gap-3">
                        <div className="flex h-11 w-11 sm:h-12 sm:w-12 items-center justify-center rounded-md bg-stef/10 text-stef shrink-0">
                            <Truck className="h-5 w-5 sm:h-6 sm:w-6" />
                        </div>
                        <div className="min-w-0">
                            <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-500">
                                {folder.immatriculation_remorque ? 'Remorque' : 'Camion'}
                            </p>
                            <h1 className="font-heading text-2xl sm:text-3xl font-black tracking-tight text-slate-900 truncate">
                                {folder.immatriculation_remorque || folder.plate}
                            </h1>
                            {folder.immatriculation_remorque && (
                                <p data-testid="folder-tracteur" className="mt-0.5 text-sm font-bold tracking-wider text-slate-600">
                                    Tracteur&nbsp;: <span className="text-slate-900">{folder.plate}</span>
                                </p>
                            )}
                            {isBureau && (folder.numero_em_sm || folder.type_em_sm) && (
                                <div data-testid="folder-em-sm" className="mt-1.5 flex items-center gap-2 flex-wrap">
                                    {(() => {
                                        const type = (folder.type_em_sm || '').toUpperCase();
                                        const num = (folder.numero_em_sm || '').trim();
                                        let href = null;
                                        if (num) {
                                            if (type === 'EM') {
                                                href = `https://tf-stb-kl.xdock.de/Wareneingang/Tour?sort=ReferenzASC&weTourId=${encodeURIComponent(num)}`;
                                            } else if (type === 'SM') {
                                                href = `https://tf-stb-kl.xdock.de/Warenausgang/Tour?sort=StatusASC&waTourId=${encodeURIComponent(num)}`;
                                            }
                                        }
                                        const content = (
                                            <>
                                                {type && (
                                                    <span className="inline-flex items-center rounded-full bg-stef/10 text-stef px-2 py-0.5 text-[11px] font-bold tracking-wider">
                                                        {type}
                                                    </span>
                                                )}
                                                {num && (
                                                    <span className="text-sm font-heading font-bold tracking-wider text-slate-900">{num}</span>
                                                )}
                                            </>
                                        );
                                        if (href) {
                                            return (
                                                <a
                                                    data-testid="folder-em-sm-link"
                                                    href={href}
                                                    target="_blank"
                                                    rel="noopener noreferrer"
                                                    className="inline-flex items-center gap-2 px-1.5 -mx-1.5 py-0.5 rounded-md hover:bg-stef/5 group cursor-pointer transition-colors"
                                                    title={`Ouvrir la tournée ${type} ${num} dans XDock`}
                                                >
                                                    {content}
                                                    <ExternalLink className="h-3 w-3 text-stef opacity-60 group-hover:opacity-100" />
                                                </a>
                                            );
                                        }
                                        return <span className="inline-flex items-center gap-2">{content}</span>;
                                    })()}
                                </div>
                            )}
                        </div>
                    </div>
                    <div className="mt-3 flex items-center gap-2 flex-wrap">
                        <StatusBadge status={folder.status} />
                        <span className="text-xs text-slate-500">créé par <strong className="text-slate-700">{folder.cariste_name}</strong></span>
                        <span className="text-xs text-slate-400">·</span>
                        <span className="text-xs text-slate-500">{new Date(folder.created_at).toLocaleString('fr-FR')}</span>
                    </div>
                </div>

                {isBureau && (
                    <div className="flex items-center gap-2 flex-wrap" data-testid="bureau-actions">
                        <button
                            data-testid="action-send-email"
                            onClick={() => setEmailOpen(true)}
                            className="inline-flex items-center gap-2 rounded-md border border-stef/40 bg-white text-stef px-3 sm:px-4 h-11 text-sm font-heading font-bold hover:bg-stef/5 transition-all"
                            title="Envoyer ce dossier par email"
                        >
                            <Mail className="h-4 w-4" /> <span className="hidden sm:inline">Envoyer par email</span>
                        </button>
                        {folder.status === 'en_attente' && (
                            <button data-testid="action-take" onClick={() => handleAction('take')} className="inline-flex items-center gap-2 rounded-md bg-stef px-3 sm:px-4 h-11 text-sm font-heading font-bold text-white hover:bg-stef-hover transition-all">
                                <PlayCircle className="h-4 w-4" /> Prendre
                            </button>
                        )}
                        {folder.status === 'en_cours' && (
                            <button data-testid="action-close" onClick={() => handleAction('close')} className="inline-flex items-center gap-2 rounded-md bg-emerald-600 px-3 sm:px-4 h-11 text-sm font-heading font-bold text-white hover:bg-emerald-700 transition-all">
                                <CheckCircle2 className="h-4 w-4" /> Clôturer
                            </button>
                        )}
                        {folder.status === 'cloture' && (
                            <button data-testid="action-reopen" onClick={() => handleAction('reopen')} className="inline-flex items-center gap-2 rounded-md border border-slate-300 bg-white px-3 sm:px-4 h-11 text-sm font-heading font-bold text-slate-700 hover:bg-slate-50 transition-all">
                                <RotateCcw className="h-4 w-4" /> Rouvrir
                            </button>
                        )}
                        <button data-testid="delete-folder-btn" onClick={() => setConfirmDelete(true)} className="inline-flex items-center gap-2 rounded-md border border-red-200 bg-white text-red-600 px-3 sm:px-4 h-11 text-sm font-heading font-bold hover:bg-red-50 transition-all">
                            <Trash2 className="h-4 w-4" /> <span className="hidden sm:inline">Supprimer</span>
                        </button>
                    </div>
                )}

                {!isBureau && user?.role === 'cariste' && folder.cariste_id === user?.id && folder.status === 'cloture' && (
                    <div className="flex items-center gap-2" data-testid="cariste-actions">
                        <button data-testid="cariste-action-reopen" onClick={() => handleAction('reopen')} className="inline-flex items-center gap-2 rounded-md bg-amber-500 px-3 sm:px-4 h-11 text-sm font-heading font-bold text-white hover:bg-amber-600 transition-all shadow-sm">
                            <RotateCcw className="h-4 w-4" /> Rouvrir
                        </button>
                    </div>
                )}
            </div>

            <div className="grid grid-cols-1 lg:grid-cols-3 gap-4 sm:gap-6">
                <div className="lg:col-span-2 space-y-4">
                    {/* Toolbar */}
                    <div className="flex items-center justify-between flex-wrap gap-2">
                        <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-500">
                            Contributions <span className="text-slate-400">({contributions.length})</span>
                        </p>
                        <div className="flex items-center gap-2">
                            {canFullEdit && !editing && !appending && (
                                <button data-testid="edit-btn" onClick={() => setEditing(true)} className="inline-flex items-center gap-1.5 rounded-md border border-slate-300 bg-white px-3 h-9 text-xs font-heading font-bold text-slate-700 hover:border-stef hover:text-stef transition">
                                    <Edit3 className="h-3.5 w-3.5" /> Modifier l'original
                                </button>
                            )}
                            {canAppend && !appending && !editing && (
                                <button data-testid="append-btn" onClick={() => setAppending(true)} className="inline-flex items-center gap-1.5 rounded-md bg-stef px-3 h-9 text-xs font-heading font-bold text-white hover:bg-stef-hover transition">
                                    <MessageSquarePlus className="h-3.5 w-3.5" /> Ajouter une mise à jour
                                </button>
                            )}
                        </div>
                    </div>

                    {/* Append form (top of timeline) */}
                    {appending && !editing && (
                        <div className="rounded-lg border-2 border-dashed border-stef/40 bg-stef/5 p-4" data-testid="append-form">
                            <div className="flex items-center gap-2 mb-3">
                                <FilePlus2 className="h-4 w-4 text-stef" />
                                <p className="text-xs font-bold uppercase tracking-wider text-stef">Nouvelle mise à jour</p>
                            </div>
                            <textarea
                                data-testid="append-text"
                                value={appendText}
                                onChange={(e) => setAppendText(e.target.value)}
                                rows={4}
                                placeholder="Ajoute une info, une précision, l'évolution du problème…"
                                className="w-full rounded-md border border-slate-300 bg-white px-3 py-2 text-sm text-slate-900 focus:border-stef focus:outline-none focus:ring-2 focus:ring-stef/20 transition"
                            />
                            <div className="mt-3 flex items-center justify-between gap-2 flex-wrap">
                                <button
                                    type="button"
                                    onClick={() => appendGalleryRef.current?.click()}
                                    data-testid="append-add-photo"
                                    className="inline-flex items-center gap-1.5 rounded-md bg-white border border-slate-300 px-3 h-9 text-xs font-bold text-slate-700 hover:border-stef hover:text-stef transition"
                                >
                                    <ImagePlus className="h-3.5 w-3.5" /> Ajouter des photos {appendPhotos.length > 0 && `(${appendPhotos.length})`}
                                </button>
                                <input ref={appendGalleryRef} type="file" accept="image/*" multiple className="hidden" onChange={(e) => handleFiles(e.target.files, 'append')} />
                                <div className="flex gap-2">
                                    <button data-testid="append-cancel" onClick={() => { setAppending(false); setAppendText(''); setAppendPhotos([]); }} className="h-9 rounded-md border border-slate-300 bg-white px-3 text-xs font-semibold text-slate-700 hover:bg-slate-50">Annuler</button>
                                    <button data-testid="append-save" onClick={saveAppend} className="h-9 rounded-md bg-stef px-3 text-xs font-heading font-bold text-white hover:bg-stef-hover inline-flex items-center gap-1.5">
                                        <Plus className="h-3.5 w-3.5" /> Enregistrer
                                    </button>
                                </div>
                            </div>
                            {appendPhotos.length > 0 && (
                                <div className="mt-3 grid grid-cols-4 sm:grid-cols-6 gap-2">
                                    {appendPhotos.map((src, i) => (
                                        <div key={i} className="relative aspect-square rounded-md overflow-hidden border border-slate-200">
                                            <img src={src} alt="" className="h-full w-full object-cover" />
                                            <button
                                                type="button"
                                                onClick={() => setAppendPhotos((p) => p.filter((_, idx) => idx !== i))}
                                                className="absolute top-1 right-1 h-5 w-5 rounded-full bg-black/70 text-white flex items-center justify-center"
                                            ><X className="h-3 w-3" /></button>
                                        </div>
                                    ))}
                                </div>
                            )}
                        </div>
                    )}

                    {/* Bureau full edit panel (replaces timeline) */}
                    {editing && (
                        <div className="rounded-lg border border-slate-200 bg-white p-4 sm:p-6" data-testid="edit-panel">
                            <div className="flex items-center justify-between mb-3">
                                <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-500">Édition du dossier (bureau)</p>
                            </div>
                            <label className="text-[11px] font-bold uppercase tracking-wider text-slate-500">Problème initial</label>
                            <textarea
                                data-testid="edit-problem"
                                value={editProblem}
                                onChange={(e) => setEditProblem(e.target.value)}
                                rows={5}
                                className="mt-1.5 w-full rounded-md border border-slate-300 bg-white px-4 py-3 text-base text-slate-900 focus:border-stef focus:outline-none focus:ring-2 focus:ring-stef/20 transition"
                            />
                            <div className="mt-4 flex items-center justify-between gap-2 flex-wrap">
                                <p className="text-[11px] font-bold uppercase tracking-wider text-slate-500">Photos ({editPhotos.length})</p>
                                <button
                                    type="button"
                                    onClick={() => galleryRef.current?.click()}
                                    data-testid="edit-add-photo"
                                    className="inline-flex items-center gap-1.5 rounded-md bg-stef px-3 h-9 text-xs font-bold text-white hover:bg-stef-hover transition"
                                >
                                    <ImagePlus className="h-3.5 w-3.5" /> Ajouter
                                </button>
                                <input ref={galleryRef} type="file" accept="image/*" multiple className="hidden" onChange={(e) => handleFiles(e.target.files, 'edit')} />
                            </div>
                            <div className="mt-2 grid grid-cols-3 sm:grid-cols-4 md:grid-cols-5 gap-2">
                                {editPhotos.map((src, i) => (
                                    <div key={i} className="relative aspect-square rounded-md overflow-hidden border border-slate-200">
                                        <img src={src} alt="" className="h-full w-full object-cover" />
                                        <button
                                            type="button"
                                            data-testid={`edit-remove-${i}`}
                                            onClick={() => setEditPhotos((p) => p.filter((_, idx) => idx !== i))}
                                            className="absolute top-1 right-1 h-6 w-6 rounded-full bg-black/70 text-white flex items-center justify-center"
                                        >
                                            <X className="h-3.5 w-3.5" />
                                        </button>
                                    </div>
                                ))}
                            </div>
                            <div className="mt-4 flex gap-2 justify-end flex-wrap">
                                <button data-testid="cancel-edit-btn" onClick={() => { setEditing(false); setEditProblem(folder.problem); setEditPhotos(folder.photos || []); }} className="h-10 rounded-md border border-slate-300 bg-white px-4 text-sm font-semibold text-slate-700 hover:bg-slate-50">
                                    Annuler
                                </button>
                                <button data-testid="save-edit-btn" onClick={saveEdit} className="h-10 rounded-md bg-stef px-4 text-sm font-heading font-bold text-white hover:bg-stef-hover inline-flex items-center gap-2">
                                    <Save className="h-4 w-4" /> Enregistrer
                                </button>
                            </div>
                        </div>
                    )}

                    {/* Timeline of contributions */}
                    {!editing && contributions.map((c, ci) => {
                        const isCreation = c.kind === 'created';
                        return (
                            <div
                                key={c.id}
                                data-testid={`contribution-${c.id}`}
                                className="rounded-lg border border-slate-200 bg-white overflow-hidden"
                            >
                                <div className={`flex items-center gap-3 px-4 py-2.5 border-b ${isCreation ? 'bg-stef/5 border-stef/15' : 'bg-slate-50 border-slate-200'}`}>
                                    <div className={`flex h-8 w-8 items-center justify-center rounded-md shrink-0 ${isCreation ? 'bg-stef text-white' : 'bg-slate-900 text-white'}`}>
                                        {isCreation ? <Truck className="h-4 w-4" /> : <MessageSquarePlus className="h-4 w-4" />}
                                    </div>
                                    <div className="min-w-0 flex-1">
                                        <p className="text-sm font-heading font-bold text-slate-900 truncate">
                                            {isCreation ? 'Création du dossier' : (c.summary || 'Mise à jour')}
                                        </p>
                                        <p className="text-xs text-slate-500 truncate">
                                            par <strong className="text-slate-700">{c.by_name || '—'}</strong>
                                            <span className="text-slate-400"> · </span>
                                            {new Date(c.at).toLocaleString('fr-FR')}
                                        </p>
                                    </div>
                                </div>
                                <div className="p-4 space-y-3">
                                    {c.text ? (
                                        <p className="text-sm sm:text-[15px] text-slate-800 whitespace-pre-wrap leading-relaxed" data-testid={`contribution-text-${c.id}`}>
                                            {c.text}
                                        </p>
                                    ) : null}
                                    {(c.photos || []).length > 0 && (
                                        <div className="grid grid-cols-3 sm:grid-cols-4 md:grid-cols-5 gap-2" data-testid={`contribution-photos-${c.id}`}>
                                            {c.photos.map((src, i) => (
                                                <div
                                                    key={i}
                                                    className="relative aspect-square rounded-md overflow-hidden border border-slate-200 cursor-pointer hover:opacity-90 transition"
                                                    onClick={() => setLightboxIndex(photoGlobalIndex(ci, i))}
                                                >
                                                    <img src={src} alt="" className="h-full w-full object-cover" />
                                                </div>
                                            ))}
                                        </div>
                                    )}
                                    {!c.text && (!c.photos || c.photos.length === 0) && (
                                        <p className="text-xs italic text-slate-400">Aucun contenu</p>
                                    )}
                                </div>
                            </div>
                        );
                    })}
                </div>

                <div>
                    <div className="rounded-lg border border-slate-200 bg-white p-4 sm:p-6">
                        <div className="flex items-center gap-2 mb-4">
                            <History className="h-4 w-4 text-stef" />
                            <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-700">Suivi</p>
                        </div>
                        <ol className="space-y-4 relative before:absolute before:left-[7px] before:top-2 before:bottom-2 before:w-px before:bg-slate-200" data-testid="history-list">
                            {(folder.history || []).map((h) => (
                                <li key={h.id} className="pl-6 relative">
                                    <span className="absolute left-0 top-1.5 h-3.5 w-3.5 rounded-full bg-white ring-2 ring-stef" />
                                    <p className="text-sm font-semibold text-slate-900">{h.label}</p>
                                    <p className="text-xs text-slate-500">{new Date(h.at).toLocaleString('fr-FR')}</p>
                                </li>
                            ))}
                        </ol>
                    </div>
                </div>
            </div>

            {/* Lightbox */}
            {lightboxIndex !== null && allPhotos[lightboxIndex] && (
                <div data-testid="lightbox" className="fixed inset-0 z-50 bg-black/90 flex flex-col" onClick={() => setLightboxIndex(null)}>
                    <div className="flex items-center justify-between gap-3 p-3 sm:p-4 text-white" onClick={(e) => e.stopPropagation()}>
                        <p className="text-sm font-bold">{folder.plate} · {lightboxIndex + 1}/{allPhotos.length}</p>
                        <div className="flex items-center gap-2">
                            <button
                                data-testid="lightbox-download"
                                onClick={() => downloadDataUrl(allPhotos[lightboxIndex], `${folder.plate}-photo-${lightboxIndex + 1}.jpg`)}
                                className="inline-flex items-center gap-2 h-10 px-3 sm:px-4 rounded-md bg-white text-slate-900 font-heading font-bold text-sm hover:bg-slate-100 transition"
                            >
                                <Download className="h-4 w-4" /> <span className="hidden sm:inline">Enregistrer</span>
                            </button>
                            <button
                                data-testid="lightbox-close"
                                onClick={() => setLightboxIndex(null)}
                                className="h-10 w-10 rounded-md bg-white/10 text-white hover:bg-white/20 flex items-center justify-center"
                            >
                                <X className="h-5 w-5" />
                            </button>
                        </div>
                    </div>
                    <div
                        className="flex-1 flex items-center justify-center overflow-auto p-2 sm:p-6"
                        onClick={(e) => e.stopPropagation()}
                        onTouchStart={(e) => { window.__lbTouchX = e.touches[0].clientX; }}
                        onTouchEnd={(e) => {
                            const start = window.__lbTouchX;
                            const end = e.changedTouches[0].clientX;
                            if (start == null) return;
                            const dx = end - start;
                            if (Math.abs(dx) > 50 && allPhotos.length > 1) {
                                if (dx < 0) setLightboxIndex((i) => Math.min(allPhotos.length - 1, i + 1));
                                else setLightboxIndex((i) => Math.max(0, i - 1));
                            }
                            window.__lbTouchX = null;
                        }}
                    >
                        <img
                            src={allPhotos[lightboxIndex]}
                            alt=""
                            className="max-h-full max-w-full select-none"
                            style={{ touchAction: 'pinch-zoom' }}
                            draggable={false}
                        />
                    </div>
                    {allPhotos.length > 1 && (
                        <>
                            <button
                                data-testid="lightbox-prev"
                                disabled={lightboxIndex === 0}
                                onClick={(e) => { e.stopPropagation(); setLightboxIndex((i) => Math.max(0, i - 1)); }}
                                className="absolute left-2 sm:left-4 top-1/2 -translate-y-1/2 h-11 w-11 sm:h-12 sm:w-12 rounded-full bg-white/10 text-white flex items-center justify-center hover:bg-white/20 disabled:opacity-30"
                            >
                                <ChevronLeft className="h-6 w-6" />
                            </button>
                            <button
                                data-testid="lightbox-next"
                                disabled={lightboxIndex === allPhotos.length - 1}
                                onClick={(e) => { e.stopPropagation(); setLightboxIndex((i) => Math.min(allPhotos.length - 1, i + 1)); }}
                                className="absolute right-2 sm:right-4 top-1/2 -translate-y-1/2 h-11 w-11 sm:h-12 sm:w-12 rounded-full bg-white/10 text-white flex items-center justify-center hover:bg-white/20 disabled:opacity-30"
                            >
                                <ChevronRight className="h-6 w-6" />
                            </button>
                        </>
                    )}
                </div>
            )}

            {/* Confirm delete */}
            {confirmDelete && (
                <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4" onClick={() => setConfirmDelete(false)}>
                    <div className="w-full max-w-sm rounded-lg bg-white p-6 shadow-xl" onClick={(e) => e.stopPropagation()} data-testid="confirm-delete-modal">
                        <div className="flex h-11 w-11 items-center justify-center rounded-md bg-red-50 text-red-600 mb-3">
                            <Trash2 className="h-5 w-5" />
                        </div>
                        <h3 className="font-heading text-lg font-black text-slate-900">Supprimer le dossier ?</h3>
                        <p className="mt-2 text-sm text-slate-600">Cette action est irréversible. Toutes les photos et l'historique seront définitivement supprimés.</p>
                        <div className="mt-5 flex justify-end gap-2">
                            <button onClick={() => setConfirmDelete(false)} className="h-10 rounded-md border border-slate-300 px-4 text-sm font-semibold text-slate-700 hover:bg-slate-50">Annuler</button>
                            <button data-testid="confirm-delete-btn" onClick={handleDelete} className="h-10 rounded-md bg-red-600 px-4 text-sm font-heading font-bold text-white hover:bg-red-700">Supprimer</button>
                        </div>
                    </div>
                </div>
            )}

            {emailOpen && (
                <FolderEmailModal
                    folder={folder}
                    currentUser={user}
                    onClose={() => setEmailOpen(false)}
                />
            )}
        </Layout>
    );
}
