/**
 * =========================================================================
 * PLATEFORME ECO-PANNEAU.FR - VERSION 1.0.0
 * Interface Client B2B (Tableau de bord, Facturation, Gestion des panneaux)
 * =========================================================================
 */

const { useState, useEffect, useMemo, useRef } = React;
const { 
    Home, Building, MessageSquare, FileText, UserCircle, Plus, Search, 
    CheckCircle, AlertTriangle, Shield, Copy, Archive, Trash2, Edit, Eye,
    CreditCard, Download, Loader, LogOut, ArrowLeft, KeyRound, ShieldAlert,
    Lock, ShieldCheck, Mail, Users, Bell, Power, Settings, FileCheck, Image, X, Zap, Package, Share2, RefreshCw, MapPin, ExternalLink, ArrowUp
} = window;

// =========================================================================
// 1. COMPOSANT STRIPE : FORMULAIRE DE PAIEMENT
// =========================================================================

const StripePaymentForm = ({ clientSecret, onSuccess, onCancel, amountCents }) => {
    const stripePromise = useMemo(() => window.Stripe(window.ECO_CONFIG.stripePubKey), []);
    const options = useMemo(() => ({ clientSecret, appearance: { theme: 'stripe', variables: { colorPrimary: '#10b981', borderRadius: '12px' } } }), [clientSecret]);

    const CheckoutForm = () => {
        const stripeInstance = window.ReactStripe.useStripe();
        const elements = window.ReactStripe.useElements();
        const [isProcessing, setIsProcessing] = useState(false);
        const [error, setError] = useState(null);

        const handleSubmit = async (e) => {
            e.preventDefault();
            if (!stripeInstance || !elements) return;
            setIsProcessing(true); setError(null);
            
            const { error: submitError } = await elements.submit();
            if (submitError) { setError(submitError.message); setIsProcessing(false); return; }

            const { error: confirmError, paymentIntent } = await stripeInstance.confirmPayment({
                elements, confirmParams: { return_url: window.location.href }, redirect: "if_required"
            });

            if (confirmError) { setError(confirmError.message); setIsProcessing(false); } 
            else if (paymentIntent && paymentIntent.status === "succeeded") { onSuccess(paymentIntent.id); }
            else { setError("Statut de paiement inattendu."); setIsProcessing(false); }
        };

        return (
            <form onSubmit={handleSubmit} className="space-y-6">
                <div className="bg-slate-50 p-4 rounded-xl mb-4 border border-slate-200 relative overflow-hidden">
                    <p className="text-sm font-bold text-slate-700 text-center mt-2">
                        Montant à régler : <span className="text-lg text-emerald-600 font-black">{amountCents ? (amountCents / 100).toFixed(2) : "0.00"} € TTC</span>
                    </p>
                </div>
                <window.ReactStripe.PaymentElement />
                {error && <div className="p-3 bg-red-50 text-red-600 text-sm font-bold rounded-xl border border-red-200 flex items-center gap-2"><AlertTriangle size={16}/> {error}</div>}
                <div className="flex gap-3 pt-4">
                    <button type="button" onClick={onCancel} disabled={isProcessing} title="Annuler le paiement" className="px-6 py-3 rounded-xl font-bold text-slate-500 hover:bg-slate-100 transition disabled:opacity-50">Annuler</button>
                    <button type="submit" disabled={isProcessing || !stripeInstance || !elements} title="Confirmer le paiement" className="flex-1 bg-emerald-600 text-white py-3 rounded-xl font-black uppercase tracking-widest hover:bg-emerald-700 transition shadow-lg flex items-center justify-center gap-2 disabled:opacity-50">
                        {isProcessing ? <Loader className="animate-spin w-5 h-5"/> : <CreditCard size={18}/>} Payer et activer
                    </button>
                </div>
            </form>
        );
    };

    return (
        <window.ReactStripe.Elements stripe={stripePromise} options={options}>
            <CheckoutForm />
        </window.ReactStripe.Elements>
    );
};

// =========================================================================
// 2. VUE PRINCIPALE DU CLIENT B2B
// =========================================================================

window.ClientView = ({ data, refreshData, showToast }) => {
    const [activeTab, setActiveTab] = useState('dashboard');
    const [uiMode, setUiMode] = useState('simplifie');
    const [pushEnabled, setPushEnabled] = useState(localStorage.getItem('eco_push_enabled') === 'true' && window.Notification?.permission === 'granted');
    const [mobileChatView, setMobileChatView] = useState(false);
    
    // Modales partagées natives-like
    const [confirmDialog, setConfirmDialog] = useState(null);
    const [promptDialog, setPromptDialog] = useState(null);
    const [legalModal, setLegalModal] = useState(null); // 'cgv' | 'rgpd'
    
    const [archiveConfig, setArchiveConfig] = useState(null);

    const [managingPanneau, setManagingPanneau] = useState(null);
    const [editingEntity, setEditingEntity] = useState(null);
    const [draggedItem, setDraggedItem] = useState(null);
    const [isSaving, setIsSaving] = useState(false);
    
    // Renonciation légale au droit de rétractation
    const [waiverAccepted, setWaiverAccepted] = useState(false);
    
    const [isModalOpen, setIsModalOpen] = useState(false);
    const [modalStep, setModalStep] = useState('config_full');
    const [validationErrors, setValidationErrors] = useState([]);
    const [paymentData, setPaymentData] = useState(null);
    const [previewPanneau, setPreviewPanneau] = useState(null);
    
    // Coffre-fort légal
    const [vaultDragging, setVaultDragging] = useState(false);
    const [viewingDoc, setViewingDoc] = useState(null);

    // Gestionnaire de liens délégués
    const [newLink, setNewLink] = useState({ name: '', expDays: 7, lockedFields: [] });

    // Modale de confirmation de livraison
    const [deliveryConfirmModal, setDeliveryConfirmModal] = useState(null);

    const [profileData, setProfileData] = useState({ type_client: 'entreprise', employees_gt_5: false, name: '', address: '', siret: '', tva: '', monthlyReport: 0, two_factor_method: 'none' });
    const [hasTva, setHasTva] = useState(true);
    const [showTvaWarning, setShowTvaWarning] = useState(false);
    
    const [passwordData, setPasswordData] = useState({ oldPassword: '', newPassword: '' });
    const [teamEmail, setTeamEmail] = useState('');
    const [totpSetupData, setTotpSetupData] = useState(null);

    const [meRes, setMeRes] = useState(null);
    useEffect(() => { 
        fetch(window.ECO_CONFIG.apiBaseUrl + 'auth/me').then(r=>r.json()).then(d=>setMeRes(d.data)); 
    }, []);

    const myClientData = data.clients?.find(c => c.id === meRes?.user_id) || data.clients?.[0] || {};
    const isSuspended = myClientData.paymentStatus === 'suspended';
    const isCollaborator = !data.team; 
    
    const isImpersonating = meRes?.is_impersonating;
    // CORRECTION : Protection de la date avec String()
    const isSupportLocked = myClientData.admin_access_until && new Date(String(myClientData.admin_access_until || '').replace(' ', 'T')) > new Date();
    const isLockedForClient = isSupportLocked && !isImpersonating;

    const purchasesAllowed = data.settings?.allow_new_purchases !== '0';

    const profileLoadedRef = useRef(false);

    useEffect(() => {
        if (myClientData.id && !profileLoadedRef.current) {
            if (myClientData.uiMode) setUiMode(myClientData.uiMode);
            
            const isTvaExempt = myClientData.tva === 'NON_ASSUJETTI';
            setHasTva(!isTvaExempt);
            
            setProfileData({
                type_client: myClientData.type_client || 'entreprise',
                employees_gt_5: myClientData.employees_gt_5 == 1 || myClientData.employees_gt_5 === true,
                name: myClientData.name || '', address: myClientData.address || '',
                siret: myClientData.siret || '', tva: isTvaExempt ? '' : (myClientData.tva || ''),
                monthlyReport: myClientData.monthlyReport || 0,
                two_factor_method: myClientData.two_factor_method || 'none'
            });
            profileLoadedRef.current = true;
        }
    }, [myClientData]);

    // Écouteur de copier/coller pour le coffre-fort
    useEffect(() => {
        if (modalStep !== 'legal_vault' || !isModalOpen) return;
        const handlePaste = (e) => {
            if (e.clipboardData && e.clipboardData.files && e.clipboardData.files.length > 0) {
                handleVaultUpload(e.clipboardData.files);
            }
        };
        window.addEventListener('paste', handlePaste);
        return () => window.removeEventListener('paste', handlePaste);
    }, [modalStep, isModalOpen, managingPanneau]);

    useEffect(() => {
        const url = new URL(window.location);
        const confirmDelivery = url.searchParams.get('confirm_delivery');
        if (confirmDelivery) {
            setActiveTab('livraisons');
            setDeliveryConfirmModal(confirmDelivery);
            url.searchParams.delete('confirm_delivery');
            window.history.replaceState({}, '', url);
        }
    }, []);

    const handleConfirmDelivery = () => {
        if (!deliveryConfirmModal) return;
        setIsSaving(true);
        fetch(window.ECO_CONFIG.apiBaseUrl + 'panneaux/shipping', {
            method: 'POST',
            body: JSON.stringify({ id: deliveryConfirmModal, shipping_status: 'Livré' })
        }).then(res => res.json()).then(d => {
            if (d.status === 'success') {
                showToast("Réception confirmée, merci !");
                refreshData();
                setDeliveryConfirmModal(null);
            } else {
                showToast(d.message || "Une erreur est survenue", "error");
            }
        }).finally(() => setIsSaving(false));
    };

    const activePanneaux = data.panneaux?.filter(c => c.status === 'Actif') || [];
    const draftPanneaux = data.panneaux?.filter(c => c.status === 'Brouillon') || [];
    const interactions = data.interactions || [];
    const totalUnread = interactions.filter(m => !m.resolved && m.author !== 'Client').length;
    const activeDeliveries = data.panneaux?.filter(c => c.physicalPanels > 0 && c.shipping_status !== 'Livré') || [];

    // --- CALCUL DES TARIFS GLOBAUX UTILES A LA PAGE ---
    const pRental = data.prices?.rentalMo ?? 180;
    const pPurchase = data.prices?.purchase ?? 850;
    const pHosting = data.prices?.hostingYr ?? 1;
    const pBoardFirst = data.prices?.boardFirst ?? 250;
    const pBoardAdd = data.prices?.boardAdd ?? 150;
    const pNoAds = data.prices?.noAds ?? 150;

    const originalPanneau = data.panneaux?.find(p => p.id === managingPanneau?.id);
    const isActif = originalPanneau?.status === 'Actif';
    const originalOfferType = originalPanneau?.offerType || 'rental';
    const originalPanels = originalPanneau?.physicalPanels || 0;
    const originalHasNoAds = originalPanneau?.hasNoAds || false;

    const currentOfferType = managingPanneau?.offerType || 'rental';
    const currentPanels = managingPanneau?.physicalPanels || 0;
    const currentHasNoAds = managingPanneau?.hasNoAds || false;

    let addedPanelsCost = 0;
    if (currentPanels > originalPanels) {
        const costNew = currentPanels > 0 ? pBoardFirst + (currentPanels - 1) * pBoardAdd : 0;
        const costOld = originalPanels > 0 ? pBoardFirst + (originalPanels - 1) * pBoardAdd : 0;
        addedPanelsCost = Math.max(0, costNew - costOld);
    }

    let upfrontHT = 0;
    if (!isActif) {
        upfrontHT = (currentPanels > 0 ? pBoardFirst + (currentPanels - 1) * pBoardAdd : 0) + (currentHasNoAds ? pNoAds : 0) + (currentOfferType === 'rental' ? pRental : pPurchase + pHosting);
    } else {
        if (originalOfferType === 'rental' && currentOfferType === 'purchase') upfrontHT += pPurchase + pHosting;
        if (currentHasNoAds && !originalHasNoAds) upfrontHT += pNoAds;
        upfrontHT += addedPanelsCost;
    }

    const discountPct = myClientData.discount || 0;
    const priceMultiplier = Math.max(0, (100 - discountPct) / 100);
    const platformHasTva = data.settings?.billing_has_tva !== '0';
    const tvaMult = platformHasTva ? 1.20 : 1.00;
    const finalUpfrontTTC = upfrontHT * priceMultiplier * tvaMult;
    const finalMonthlyTTC = pRental * priceMultiplier * tvaMult;

    const handleLogout = async () => {
        await fetch(window.ECO_CONFIG.apiBaseUrl + 'auth/logout');
        window.location.href = '?';
    };

    const handleUnimpersonate = async () => {
        const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'auth/unimpersonate', { method: 'POST' });
        const d = await res.json();
        if (d.status === 'success') { window.location.href = '?'; } else { showToast(d.message, 'error'); }
    };

    const handleRevokeAccess = async () => {
        setIsSaving(true);
        try {
            const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'clients/revoke_access', { method: 'POST' });
            if ((await res.json()).status === 'success') {
                showToast("Accès révoqué avec succès !", "success");
                if (isImpersonating) window.location.href = '?'; 
                else {
                    refreshData();
                    setActiveTab('dashboard'); 
                }
            }
        } finally { setIsSaving(false); }
    };

    let finalCustomLogout = null;
    if (isLockedForClient) {
        finalCustomLogout = { label: "Stopper l'assistance", icon: <ShieldAlert size={18}/>, action: handleRevokeAccess, className: "bg-red-600 hover:bg-red-700 text-white" };
    } else if (isImpersonating) {
        finalCustomLogout = { label: "Clôturer l'intervention", icon: <CheckCircle size={18}/>, action: handleRevokeAccess, className: "bg-emerald-600 hover:bg-emerald-700 text-white" };
    }

    let finalNavItems = [
        { id: 'dashboard', icon: <Home size={18}/>, label: 'Tableau de bord', badge: 0 },
        { id: 'panels', icon: <Building size={18}/>, label: 'Mes panneaux', badge: 0 },
        { id: 'livraisons', icon: <Package size={18}/>, label: 'Livraisons', badge: activeDeliveries.length },
        { id: 'messages', icon: <MessageSquare size={18}/>, label: 'Messagerie', badge: totalUnread },
        ...(isCollaborator ? [] : [{ id: 'billing', icon: <FileText size={18}/>, label: 'Factures', badge: 0 }]),
        { id: 'account', icon: <UserCircle size={18}/>, label: 'Mon compte', badge: 0 },
    ];

    if (isLockedForClient) {
        finalNavItems = [ { id: 'messages', icon: <MessageSquare size={18}/>, label: 'Messagerie', badge: totalUnread } ];
        if (activeTab !== 'messages') setActiveTab('messages');
    }

    const saveEditedEntity = () => {
        let newInter = [...(managingPanneau.intervenants || [])];
        let newLots = JSON.parse(JSON.stringify(managingPanneau.lots || []));
        const loc = editingEntity.location;

        if (loc.type === 'intervenant') {
            if (loc.index !== undefined) newInter[loc.index] = editingEntity.data;
            else newInter.push({...editingEntity.data, id: crypto.randomUUID()});
        } else if (loc.type === 'lot') {
            if (loc.index !== undefined) newLots[loc.index] = {...newLots[loc.index], ...editingEntity.data};
            else newLots.push({...editingEntity.data, id: crypto.randomUUID(), entreprises: []});
        } else if (loc.type === 'entreprise') {
            if (loc.index !== undefined) newLots[loc.lotIndex].entreprises[loc.index] = editingEntity.data;
            else newLots[loc.lotIndex].entreprises.push({...editingEntity.data, id: crypto.randomUUID()});
        }
        setManagingPanneau({ ...managingPanneau, intervenants: newInter, lots: newLots });
        setEditingEntity(null);
    };

    const deleteEntity = (loc) => {
        setConfirmDialog({
            title: "Supprimer l'élément", message: "Êtes-vous sûr de vouloir supprimer cet élément ?", confirmText: "Supprimer", isDestructive: true,
            onConfirm: () => {
                let newInter = [...(managingPanneau.intervenants || [])];
                let newLots = JSON.parse(JSON.stringify(managingPanneau.lots || []));
                if (loc.type === 'intervenant') newInter.splice(loc.index, 1);
                else if (loc.type === 'lot') newLots.splice(loc.index, 1);
                else newLots[loc.lotIndex].entreprises.splice(loc.index, 1);
                setManagingPanneau({ ...managingPanneau, intervenants: newInter, lots: newLots });
            }
        });
    };

    const handleDragStart = (e, location) => { setDraggedItem(location); e.dataTransfer.effectAllowed = 'move'; };
    const handleDragOver = (e) => { e.preventDefault(); e.dataTransfer.dropEffect = 'move'; };
    const handleDrop = (e, dropLocation) => {
        e.preventDefault();
        if (!draggedItem || draggedItem.type !== dropLocation.type) return;
        if (draggedItem.type === 'entreprise' && draggedItem.lotIndex !== dropLocation.lotIndex) return;
        
        let newInter = [...(managingPanneau.intervenants || [])];
        let newLots = JSON.parse(JSON.stringify(managingPanneau.lots || []));
        
        if (draggedItem.type === 'intervenant') { const item = newInter.splice(draggedItem.index, 1)[0]; newInter.splice(dropLocation.index, 0, item); } 
        else if (draggedItem.type === 'lot') { const item = newLots.splice(draggedItem.index, 1)[0]; newLots.splice(dropLocation.index, 0, item); } 
        else if (draggedItem.type === 'entreprise') { const arr = newLots[dropLocation.lotIndex].entreprises; const item = arr.splice(draggedItem.index, 1)[0]; arr.splice(dropLocation.index, 0, item); }
        setManagingPanneau({ ...managingPanneau, intervenants: newInter, lots: newLots });
        setDraggedItem(null);
    };

    const validatePanel = () => {
        const errors = [];
        if (!managingPanneau.name?.trim()) errors.push("Le nom du chantier est manquant.");
        if (!managingPanneau.location?.trim()) errors.push("L'adresse du panneau est manquante.");
        if (!managingPanneau.pdfId) errors.push("L'arrêté légal (PDF) n'a pas été uploadé.");
        
        if (!isCollaborator) {
            if (!profileData.name?.trim()) errors.push("Facturation : raison sociale ou nom manquant (onglet Mon compte).");
            if (!profileData.address?.trim()) errors.push("Facturation : adresse postale manquante (onglet Mon compte).");
            if (profileData.type_client === 'entreprise' && !profileData.siret?.trim()) errors.push("Facturation : SIRET de l'entreprise manquant (onglet Mon compte).");
        }
        return errors;
    };

    const handleSavePanneau = async (forceDraft = false) => {
        if (!forceDraft && managingPanneau.status === 'Actif') {
            const errs = validatePanel();
            if (errs.length > 0) { setValidationErrors(errs); return; }
        }

        setIsSaving(true);
        try {
            const payload = { 
                id: managingPanneau.id, status: managingPanneau.status, offerType: managingPanneau.offerType, currentRate: managingPanneau.currentRate, physicalPanels: managingPanneau.physicalPanels, 
                details: { ...managingPanneau, name: managingPanneau.name?.trim() || 'Brouillon sans nom', location: managingPanneau.location?.trim() || '' } 
            };
            const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'panneaux', { method: 'POST', body: JSON.stringify(payload) });
            const d = await res.json();
            if(d.status === 'success') { showToast(forceDraft ? "Brouillon sauvegardé !" : "Panneau mis à jour !"); setIsModalOpen(false); refreshData(); }
            else showToast(d.message, 'error');
        } catch(e) { showToast("Erreur de sauvegarde", "error"); }
        setIsSaving(false);
    };

    const handleActivationRequest = async () => {
        if(isSuspended) return showToast("Votre compte est suspendu. Veuillez régulariser vos factures.", "error");
        
        // Si le client n'a pas assez de solde pour payer, la CB est requise
        const remainingToPay = Math.max(0, finalUpfrontTTC - (myClientData.wallet_balance || 0));
        
        if(remainingToPay > 0 && (!waiverAccepted || !purchasesAllowed)) {
            if (!purchasesAllowed) return showToast("Les nouvelles commandes sont suspendues.", "error");
            return showToast("Veuillez accepter les conditions de rétractation.", "error");
        }
        
        setIsSaving(true);
        try {
            const payload = { panneau_id: managingPanneau.id, offer_type: managingPanneau.offerType, physical_panels: managingPanneau.physicalPanels, hasNoAds: managingPanneau.hasNoAds };
            const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'stripe/intent', { method: 'POST', body: JSON.stringify(payload) });
            const d = await res.json();
            
            if(d.status === 'success') {
                if(d.data.free_activation_required) {
                    const freeRes = await fetch(window.ECO_CONFIG.apiBaseUrl + 'panneaux/activate_free', { method: 'POST', body: JSON.stringify({ ...payload, id: managingPanneau.id, offerType: managingPanneau.offerType, physicalPanels: managingPanneau.physicalPanels, details: managingPanneau, name: managingPanneau.name }) });
                    if((await freeRes.json()).status === 'success') { showToast("Mise à jour et activation réussie !"); setIsModalOpen(false); refreshData(); }
                    else showToast("Erreur d'activation", "error");
                } else {
                    setPaymentData({ secret: d.data.clientSecret, subId: d.data.subscription_id, amountCents: d.data.amountCents });
                    setModalStep('payment');
                }
            } else showToast(d.message, 'error');
        } catch(e) { showToast("Erreur de communication", "error"); }
        setIsSaving(false);
    };

    const handlePaymentSuccess = async (pi_id) => {
        setIsSaving(true);
        try {
            const payload = { payment_intent_id: pi_id, subscription_id: paymentData?.subId, id: managingPanneau.id, offerType: managingPanneau.offerType, currentRate: managingPanneau.currentRate, physicalPanels: managingPanneau.physicalPanels, details: managingPanneau, name: managingPanneau.name };
            const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'panneaux/activate_paid', { method: 'POST', body: JSON.stringify(payload) });
            const d = await res.json();
            if(d.status === 'success') { showToast("Paiement validé !"); setIsModalOpen(false); refreshData(); }
            else showToast(d.message, 'error');
        } catch(e) { showToast("Erreur", "error"); }
        setIsSaving(false);
    };

    const handleCreateDelegateLink = async () => {
        if (!newLink.name.trim()) return showToast("Veuillez donner un nom au lien.", "error");
        setIsSaving(true);
        try {
            const linkId = crypto.randomUUID();
            const expTime = Math.floor(Date.now() / 1000) + (newLink.expDays * 86400);
            const linkObj = { id: linkId, name: newLink.name.trim(), exp: expTime, active: true, lockedFields: newLink.lockedFields };
            
            const updatedPanneau = { ...managingPanneau, delegate_links: [...(managingPanneau.delegate_links || []), linkObj] };
            await fetch(window.ECO_CONFIG.apiBaseUrl + 'panneaux', { method: 'POST', body: JSON.stringify({ id: updatedPanneau.id, status: updatedPanneau.status, offerType: updatedPanneau.offerType, physicalPanels: updatedPanneau.physicalPanels, details: updatedPanneau }) });
            
            setManagingPanneau(updatedPanneau);
            setNewLink({ name: '', expDays: 7, lockedFields: [] });
            refreshData();
            showToast("Nouveau lien de saisie créé.", "success");
        } catch(e) { showToast("Erreur lors de la création", "error"); }
        setIsSaving(false);
    };

    const handleDeleteTeamMember = (uid) => {
        setConfirmDialog({
            title: "Supprimer le collaborateur", message: "Voulez-vous vraiment supprimer ce collaborateur ?", isDestructive: true, confirmText: "Supprimer",
            onConfirm: async () => {
                setIsSaving(true);
                try {
                    const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'clients/team/delete', { method: 'POST', body: JSON.stringify({ uid }) });
                    if ((await res.json()).status === 'success') { showToast("Collaborateur supprimé."); refreshData(); }
                } finally { setIsSaving(false); }
            }
        });
    };

    const handleAssignPanel = async (panneauId, assignedUid) => {
        setIsSaving(true);
        try {
            const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'panneaux/assign', { method: 'POST', body: JSON.stringify({ panneau_id: panneauId, assigned_uid: assignedUid }) });
            if ((await res.json()).status === 'success') { showToast("Assignation mise à jour."); refreshData(); }
        } finally { setIsSaving(false); }
    };

    const handleAutoFill = () => {
        setPromptDialog({
            title: "Saisie automatique", message: "Saisissez votre numéro SIRET (14 chiffres) ou SIREN (9 chiffres) :", placeholder: "N° SIREN ou SIRET", confirmText: "Rechercher",
            onConfirm: async (num) => {
                const cleanNum = num.replace(/\D/g, '');
                if (cleanNum.length !== 9 && cleanNum.length !== 14) return showToast("Le numéro doit contenir exactement 9 ou 14 chiffres.", "error");
                setIsSaving(true);
                try {
                    const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'system/sirene', { method: 'POST', body: JSON.stringify({ q: cleanNum }) });
                    const responseData = await res.json();
                    if (responseData.status !== 'success') throw new Error(responseData.message);

                    const apiData = responseData.data;
                    if (apiData.results && apiData.results.length > 0) {
                        const company = apiData.results[0];
                        const expectedSiren = cleanNum.substring(0, 9);
                        if (company.siren !== expectedSiren) { setIsSaving(false); return showToast("Numéro invalide.", "error"); }
                        const siege = company.siege || {};
                        let foundSiret = siege.siret || company.siren + "00010";
                        if (cleanNum.length === 14) { if (siege.siret === cleanNum) foundSiret = cleanNum; else if (company.matching_etablissements) { const exactEtab = company.matching_etablissements.find(e => e.siret === cleanNum); if (exactEtab) foundSiret = cleanNum; } }
                        const addressParts = [siege.numero_voie, siege.indice_repetition, siege.type_voie, siege.libelle_voie, siege.code_postal, siege.libelle_commune];
                        const address = addressParts.filter(Boolean).join(' ').replace(/\s+/g, ' ').trim() || "Adresse non renseignée";
                        const tvaKey = (12 + 3 * (parseInt(company.siren, 10) % 97)) % 97;
                        const calculatedTva = `FR${tvaKey.toString().padStart(2, '0')}${company.siren}`;

                        setProfileData({ ...profileData, type_client: 'entreprise', name: company.nom_complet, address: address, siret: foundSiret, tva: calculatedTva });
                        setHasTva(true); showToast("Informations récupérées !", "success");
                    } else showToast("Aucune entreprise trouvée.", "error");
                } catch (err) { showToast("Le service est indisponible.", "error"); }
                setIsSaving(false);
            }
        });
    };

    const handleToggleTva = () => {
        if (isCollaborator) return;
        if (hasTva) setShowTvaWarning(true); 
        else setHasTva(true); 
    };

    const confirmTvaExemption = () => {
        setHasTva(false); setProfileData({ ...profileData, tva: '' }); setShowTvaWarning(false);
    };

    const handleSaveProfile = async () => {
        if(!profileData.name.trim() || !profileData.address.trim()) {
            return showToast("Veuillez remplir le nom et l'adresse.", "error");
        }
        if (profileData.type_client === 'entreprise' && !profileData.siret.trim()) {
            return showToast("Veuillez remplir le SIRET.", "error");
        }

        let cleanTva = 'NON_ASSUJETTI';
        if (profileData.type_client === 'entreprise' && hasTva) {
            if (!profileData.tva || profileData.tva.trim() === '') return showToast("Veuillez renseigner votre numéro de TVA.", "error");
            cleanTva = profileData.tva.replace(/\s+/g, '').toUpperCase();
            if (!/^[A-Z]{2}[A-Z0-9]{2,12}$/.test(cleanTva)) return showToast("Format de TVA invalide.", "error");
        }

        setIsSaving(true);
        try {
            const payload = { ...profileData, tva: cleanTva, uiMode: uiMode };
            const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'clients/profile/update', { method: 'POST', body: JSON.stringify(payload) });
            if((await res.json()).status === 'success') { 
                setProfileData({ ...profileData, tva: profileData.type_client === 'entreprise' && hasTva ? cleanTva : '' });
                showToast("Profil mis à jour !"); 
                refreshData(); 
            }
        } finally { setIsSaving(false); }
    };

    const handleUiModeChange = async (isAdvanced) => {
        const newMode = isAdvanced ? 'professionnel' : 'simplifie';
        setUiMode(newMode); setIsSaving(true);
        try {
            let cleanTva = 'NON_ASSUJETTI';
            if (profileData.type_client === 'entreprise' && hasTva && profileData.tva) cleanTva = profileData.tva.replace(/\s+/g, '').toUpperCase();
            const payload = { ...profileData, tva: cleanTva, uiMode: newMode };
            const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'clients/profile/update', { method: 'POST', body: JSON.stringify(payload) });
            if((await res.json()).status === 'success') { showToast(isAdvanced ? "Interface avancée activée." : "Interface simplifiée activée."); refreshData(); }
        } catch(e) { showToast("Erreur", "error"); } finally { setIsSaving(false); }
    };

    const handleSavePassword = async () => {
        if(!passwordData.oldPassword || !passwordData.newPassword) return showToast("Champs manquants", "error");
        setIsSaving(true);
        try {
            const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'clients/password/update', { method: 'POST', body: JSON.stringify({ oldPassword: passwordData.oldPassword, password: passwordData.newPassword }) });
            const d = await res.json();
            if(d.status === 'success') { showToast("Mot de passe mis à jour"); setPasswordData({oldPassword:'', newPassword:''}); }
            else showToast(d.message, 'error');
        } finally { setIsSaving(false); }
    };

    const handleInviteTeam = async () => {
        if(!teamEmail) return;
        setIsSaving(true);
        try {
            const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'clients/invite_team', { method: 'POST', body: JSON.stringify({ email: teamEmail }) });
            const d = await res.json();
            if(d.status === 'success') { showToast("Invitation envoyée !"); setTeamEmail(''); refreshData(); }
            else showToast(d.message, 'error');
        } finally { setIsSaving(false); }
    };

    const requestAccountDeletion = () => {
        setPromptDialog({
            title: "Suppression du compte", message: "Pour confirmer la suppression de votre compte, veuillez saisir votre mot de passe :", inputType: "password", placeholder: "Mot de passe", confirmText: "Confirmer la suppression",
            onConfirm: async (pwd) => {
                try {
                    const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'clients/request_delete', { method: 'POST', body: JSON.stringify({ password: pwd }) });
                    const d = await res.json();
                    if (d.status === 'success') showToast("E-mail de confirmation envoyé.", "info");
                    else showToast(d.message, 'error');
                } catch(e) { showToast("Erreur", "error"); }
            }
        });
    };

    const togglePush = () => {
        if (pushEnabled) { localStorage.setItem('eco_push_enabled', 'false'); setPushEnabled(false); showToast("Notifications web désactivées.", "info"); } 
        else {
            if (!window.Notification) return showToast("Votre navigateur ne supporte pas les notifications.", "error");
            Notification.requestPermission().then(perm => {
                if (perm === 'granted') { localStorage.setItem('eco_push_enabled', 'true'); setPushEnabled(true); showToast("Notifications activées !", "success"); } 
                else { showToast("Vous avez bloqué les notifications dans votre navigateur.", "error"); }
            });
        }
    };

    const enableTotp = async () => {
        setIsSaving(true);
        try {
            const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'clients/profile/setup_totp', { method: 'POST' });
            const d = await res.json();
            if (d.status === 'success') {
                setTotpSetupData(d.data);
            } else {
                showToast(d.message, 'error');
            }
        } catch(e) { showToast("Erreur réseau", "error"); }
        setIsSaving(false);
    };

    const confirmTotp = async () => {
        setIsSaving(true);
        try {
            const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'clients/profile/update_2fa', { method: 'POST', body: JSON.stringify({ method: 'totp' }) });
            if ((await res.json()).status === 'success') {
                setProfileData({...profileData, two_factor_method: 'totp'});
                setTotpSetupData(null);
                showToast("2FA par application activée avec succès !", "success");
            }
        } catch(e) {}
        setIsSaving(false);
    };

    const handleVaultUpload = async (files) => {
        if (!files || files.length === 0) return;
        let currentTotalSize = managingPanneau.privateDocs?.reduce((acc, doc) => acc + (doc.size || 0), 0) || 0;
        
        setIsSaving(true);
        let newDocs = [...(managingPanneau.privateDocs || [])];
        
        for (let i = 0; i < files.length; i++) {
            const file = files[i];
            if (file.size > 100 * 1024 * 1024) { showToast(`Le fichier ${file.name} dépasse 100 Mo.`, "error"); continue; }
            if (currentTotalSize + file.size > 500 * 1024 * 1024) { showToast("La limite totale de 500 Mo du coffre-fort serait dépassée.", "error"); break; }
            try {
                const type = file.type.includes('pdf') ? 'pdf' : 'image';
                const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'upload/file', { method: 'POST', body: (() => { const fd = new FormData(); fd.append('file', file); fd.append('type', type); fd.append('is_private', 'true'); return fd; })() });
                const d = await res.json();
                if (d.status === 'success') {
                    newDocs.push({ id: d.data.fileId, type, name: file.name, date: new Date().toLocaleDateString('fr-FR'), size: d.data.size || file.size });
                    currentTotalSize += (d.data.size || file.size);
                } else showToast(d.message, "error");
            } catch(err) { showToast("Erreur upload", "error"); }
        }
        
        const updatedPanneau = {...managingPanneau, privateDocs: newDocs};
        setManagingPanneau(updatedPanneau);
        await fetch(window.ECO_CONFIG.apiBaseUrl + 'panneaux', { method: 'POST', body: JSON.stringify({ id: updatedPanneau.id, status: updatedPanneau.status, offerType: updatedPanneau.offerType, physicalPanels: updatedPanneau.physicalPanels, details: updatedPanneau }) });
        refreshData(); setIsSaving(false);
    };

    const deleteVaultDoc = (idx) => {
        setConfirmDialog({
            title: "Supprimer la preuve", message: "Voulez-vous vraiment supprimer ce document privé ?", isDestructive: true, confirmText: "Supprimer",
            onConfirm: async () => {
                const newDocs = [...managingPanneau.privateDocs]; 
                newDocs.splice(idx, 1);
                const updatedPanneau = {...managingPanneau, privateDocs: newDocs};
                setManagingPanneau(updatedPanneau); setIsSaving(true);
                await fetch(window.ECO_CONFIG.apiBaseUrl + 'panneaux', { method: 'POST', body: JSON.stringify({ id: updatedPanneau.id, status: updatedPanneau.status, offerType: updatedPanneau.offerType, physicalPanels: updatedPanneau.physicalPanels, details: updatedPanneau }) });
                refreshData(); setIsSaving(false);
            }
        });
    };

    const allSimpOptionsActive = data.settings?.simp_opt_description === '1' && data.settings?.simp_opt_image === '1' && data.settings?.simp_opt_theme === '1' && data.settings?.simp_opt_link === '1' && data.settings?.simp_opt_emergency === '1' && data.settings?.simp_opt_schedule === '1';
    const isAdvancedMode = uiMode === 'professionnel' || allSimpOptionsActive;

    const renderDashboard = () => (
        <div className="space-y-8 animate-in fade-in slide-in-from-bottom-4">
            <div className="flex flex-col md:flex-row justify-between gap-4 items-start md:items-center">
                <div><h1 className="text-3xl font-black text-slate-800">Bienvenue, {myClientData.name || 'Client'}</h1><p className="text-slate-500 font-medium">Gérez vos obligations légales BTP en toute simplicité.</p></div>
                {!isSuspended && !isCollaborator && purchasesAllowed && (
                    <button onClick={() => { setManagingPanneau({ name: '', location: '', permitNumber: '', status: 'Brouillon', offerType: 'rental', currentRate: data.prices?.rentalMo ?? 180, physicalPanels: 0, hasNoAds: false, privateDocs: [], shippingAddress: '' }); setValidationErrors([]); setWaiverAccepted(false); setModalStep('config_full'); setIsModalOpen(true); }} className="bg-emerald-600 text-white px-6 py-3 rounded-xl font-black uppercase tracking-widest text-sm hover:bg-emerald-700 transition shadow-lg flex items-center gap-2">
                        <Plus size={18}/> Nouveau panneau
                    </button>
                )}
            </div>

            {(!purchasesAllowed) && (
                <div className="bg-orange-50 text-orange-800 p-4 rounded-2xl border border-orange-200 shadow-sm flex items-center gap-3">
                    <AlertTriangle size={24} className="shrink-0" />
                    <p className="text-sm font-bold">La création de nouvelles commandes est temporairement suspendue.</p>
                </div>
            )}

            {isSuspended && (
                <div className="bg-red-50 border-2 border-red-200 p-6 rounded-2xl flex items-start gap-4">
                    <AlertTriangle size={32} className="text-red-600 shrink-0"/>
                    <div>
                        <h3 className="font-black text-red-800 text-lg">Facture impayée - compte suspendu</h3>
                        <p className="text-red-700 text-sm mt-1">L'accès à l'édition de vos panneaux est temporairement bloqué. Veuillez régulariser votre situation dans l'onglet Factures.</p>
                        {!isCollaborator && <button onClick={() => setActiveTab('billing')} className="mt-3 bg-red-600 text-white px-4 py-2 rounded-xl text-xs font-bold hover:bg-red-700 transition">Régulariser maintenant</button>}
                    </div>
                </div>
            )}

            <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
                <window.StatCard title="Panneaux actifs" value={activePanneaux.length} icon={<ShieldCheck size={24}/>} color="text-emerald-600" bg="bg-emerald-100" onClick={() => setActiveTab('panels')} />
                <window.StatCard title="Brouillons" value={draftPanneaux.length} icon={<Edit size={24}/>} color="text-slate-600" bg="bg-slate-200" onClick={() => setActiveTab('panels')} />
                <window.StatCard title="Scans riverains" value={data.stats?.totalViews || 0} icon={<UserCircle size={24}/>} color="text-blue-600" bg="bg-blue-100" />
                <window.StatCard title="Messages" value={totalUnread} icon={<MessageSquare size={24}/>} color="text-amber-600" bg="bg-amber-100" onClick={() => setActiveTab('messages')} />
            </div>

            {data.stats?.history && data.stats.history.length > 0 && (
                <div className="bg-white p-6 rounded-3xl border border-slate-200 shadow-sm mt-6">
                    <h3 className="font-black text-slate-800 mb-6 flex items-center gap-2">
                        <window.Activity size={18} className="text-emerald-600"/> 
                        Activité des riverains (30 derniers jours)
                    </h3>
                    <window.SimpleBarChart data={data.stats.history} />
                </div>
            )}
        </div>
    );

    const renderPanels = () => (
        <div className="space-y-6 animate-in fade-in slide-in-from-bottom-4">
            <div className="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4">
                <div><h1 className="text-3xl font-black text-slate-800">Mes panneaux</h1><p className="text-slate-500 font-medium">Gestion de vos affichages légaux.</p></div>
                <div className="flex gap-2">
                    {!isSuspended && !isCollaborator && purchasesAllowed && (
                        <button onClick={() => { setManagingPanneau({ name: '', location: '', permitNumber: '', status: 'Brouillon', offerType: 'rental', currentRate: data.prices?.rentalMo ?? 180, physicalPanels: 0, hasNoAds: false, privateDocs: [], shippingAddress: '' }); setValidationErrors([]); setWaiverAccepted(false); setModalStep('config_full'); setIsModalOpen(true); }} className="bg-emerald-600 text-white px-5 py-2.5 rounded-xl font-bold text-sm hover:bg-emerald-700 transition shadow-lg flex items-center gap-2">
                            <Plus size={16}/> Nouveau panneau
                        </button>
                    )}
                </div>
            </div>

            {(!purchasesAllowed) && (
                <div className="bg-orange-50 text-orange-800 p-4 rounded-2xl border border-orange-200 shadow-sm flex items-center gap-3">
                    <AlertTriangle size={24} className="shrink-0" />
                    <p className="text-sm font-bold">La création de nouvelles commandes est temporairement suspendue.</p>
                </div>
            )}

            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                {data.panneaux?.map((c, i) => (
                    <div key={i} className={`bg-white rounded-3xl p-6 shadow-sm border ${c.status === 'Actif' ? 'border-emerald-200' : 'border-slate-200'} flex flex-col`}>
                        <div className="flex justify-between items-start mb-4">
                            <div className="flex items-center gap-3">
                                <div className={`w-12 h-12 rounded-2xl flex items-center justify-center shrink-0 ${c.status === 'Actif' ? 'bg-emerald-100 text-emerald-600' : 'bg-slate-100 text-slate-400'}`}><Building size={24}/></div>
                                <div>
                                    <h3 className="font-black text-lg text-slate-800 leading-tight truncate max-w-[200px] sm:max-w-[250px]" title={c.name}>{c.name || 'Brouillon sans nom'}</h3>
                                    <p className="text-xs text-slate-500 font-medium mt-0.5 truncate max-w-[200px]" title={c.location}>{c.location || 'Localisation non définie'}</p>
                                </div>
                            </div>
                            <span className={`px-3 py-1 rounded-lg text-[10px] font-black uppercase tracking-widest shrink-0 ${c.status === 'Actif' ? 'bg-emerald-50 text-emerald-700 border border-emerald-200' : 'bg-slate-100 text-slate-600 border border-slate-200'}`}>{c.status}</span>
                        </div>
                        
                        <div className="flex-1"></div>

                        {c.status === 'Actif' && (
                            <div className="grid grid-cols-2 gap-2 mb-4 bg-slate-50 p-3 rounded-xl border border-slate-100">
                                <div className="text-center"><p className="text-[10px] font-bold text-slate-400 uppercase">Scans QR</p><p className="font-black text-slate-800">{c.views}</p></div>
                                <div className="text-center border-l border-slate-200"><p className="text-[10px] font-bold text-slate-400 uppercase">Abonnement</p><p className="font-black text-slate-800">{c.offerType === 'rental' ? 'Location' : 'Achat'}</p></div>
                            </div>
                        )}

                        <div className="flex flex-wrap gap-2 pt-4 border-t border-slate-100">
                            {c.status === 'Actif' && (
                                <>
                                    <button onClick={() => setPreviewPanneau(c)} title="Aperçu du panneau" className="flex-1 sm:flex-none justify-center bg-emerald-50 text-emerald-700 px-4 py-2 rounded-xl text-xs font-bold hover:bg-emerald-100 flex items-center gap-2 transition"><window.QrCode size={16}/> Voir le panneau</button>
                                    <button onClick={() => { setManagingPanneau(c); setModalStep('share'); setIsModalOpen(true); }} title="Lien de saisie déléguée" className="flex-1 sm:flex-none justify-center bg-blue-50 text-blue-700 px-4 py-2 rounded-xl text-xs font-bold hover:bg-blue-100 flex items-center gap-2 transition"><Share2 size={16}/> Saisie déléguée</button>
                                    <button onClick={() => { setManagingPanneau(c); setModalStep('legal_vault'); setIsModalOpen(true); }} title="Documents d'huissier" className="flex-1 sm:flex-none justify-center bg-slate-900 text-white px-4 py-2 rounded-xl text-xs font-bold hover:bg-slate-800 flex items-center gap-2 transition"><Lock size={16}/> Coffre-fort</button>
                                    {!isSuspended && (
                                        <button onClick={() => { setManagingPanneau({...c}); setValidationErrors([]); setModalStep('config_full'); setIsModalOpen(true); }} title="Éditer le panneau" className="flex-1 sm:flex-none justify-center bg-white border border-slate-200 text-slate-600 px-4 py-2 rounded-xl text-xs font-bold hover:bg-slate-50 flex items-center gap-2 transition"><Edit size={16}/> Modifier</button>
                                    )}
                                    {!isCollaborator && (
                                        <button onClick={() => {
                                            setConfirmDialog({
                                                title: "Clôturer le panneau",
                                                message: "Clôturer ce panneau ? Cette action va archiver toutes les données et arrêter la facturation.",
                                                confirmText: "Clôturer et archiver",
                                                isDestructive: true,
                                                onConfirm: () => setArchiveConfig({ type: 'doe', panelId: c.id })
                                            });
                                        }} disabled={archiveConfig !== null} title="Clôturer et archiver le panneau" className="w-full justify-center bg-red-50 text-red-600 px-4 py-2 rounded-xl text-xs font-bold hover:bg-red-100 flex items-center gap-2 transition"><Archive size={16}/> Clôturer et archiver (D.O.E)</button>
                                    )}
                                </>
                            )}
                            {c.status === 'Brouillon' && !isSuspended && (
                                <>
                                    <button onClick={() => setPreviewPanneau(c)} title="Aperçu du panneau" className="flex-1 sm:flex-none justify-center bg-blue-50 text-blue-700 px-4 py-2 rounded-xl text-xs font-bold hover:bg-blue-100 flex items-center gap-2 transition"><Eye size={16}/> Aperçu</button>
                                    <button onClick={() => { setManagingPanneau({...c}); setValidationErrors([]); setModalStep('config_full'); setIsModalOpen(true); }} title="Éditer ce brouillon" className="flex-1 bg-emerald-600 text-white px-4 py-2 rounded-xl text-xs font-bold hover:bg-emerald-700 flex items-center justify-center gap-2 transition"><Edit size={16}/> Reprendre l'édition</button>
                                    {!isCollaborator && <button onClick={() => {
                                        setConfirmDialog({
                                            title: "Supprimer le brouillon",
                                            message: "Voulez-vous vraiment supprimer ce brouillon ?",
                                            confirmText: "Supprimer",
                                            isDestructive: true,
                                            onConfirm: () => {
                                                fetch(window.ECO_CONFIG.apiBaseUrl + 'panneaux/delete', { method: 'POST', body: JSON.stringify({id: c.id}) }).then(() => refreshData());
                                            }
                                        });
                                    }} title="Supprimer ce brouillon" className="px-4 py-2 rounded-xl text-xs font-bold text-red-600 bg-red-50 hover:bg-red-100 transition"><Trash2 size={16}/></button>}
                                </>
                            )}
                            {!isCollaborator && purchasesAllowed && (
                                <button onClick={() => { 
                                    const deepClone = JSON.parse(JSON.stringify(c));
                                    const cleanIntervenants = (deepClone.intervenants || []).map(i => ({...i, id: crypto.randomUUID(), logoId: '', logoUrl: ''}));
                                    const cleanLots = (deepClone.lots || []).map(l => ({...l, id: crypto.randomUUID(), entreprises: (l.entreprises || []).map(e => ({...e, id: crypto.randomUUID(), logoId: '', logoUrl: ''}))}));

                                    setManagingPanneau(null); 
                                    setManagingPanneau({ 
                                        ...c, 
                                        id: undefined, 
                                        delegate_links: [],
                                        name: c.name + ' (Copie)', 
                                        location: '', 
                                        permitNumber: '', 
                                        status: 'Brouillon', 
                                        offerType: 'rental', 
                                        physicalPanels: 0, 
                                        hasNoAds: false, 
                                        privateDocs: [], 
                                        shippingAddress: c.shippingAddress || '',
                                        imageId: '', 
                                        imageUrl: '', 
                                        pdfId: '',
                                        maitreOuvrageLogoId: '', 
                                        maitreOuvrageLogoUrl: '',
                                        intervenants: cleanIntervenants,
                                        lots: cleanLots
                                    }); 
                                    setValidationErrors([]);
                                    setWaiverAccepted(false);
                                    setModalStep('config_full'); 
                                    setIsModalOpen(true); 
                                }} title="Dupliquer le panneau" className="flex-1 sm:flex-none justify-center bg-white border border-slate-200 text-slate-600 px-4 py-2 rounded-xl text-xs font-bold hover:bg-slate-50 flex items-center gap-2 transition"><Copy size={16}/> Dupliquer</button>
                            )}
                        </div>

                        {(!isCollaborator && data.team?.length > 0 && isAdvancedMode) && (
                            <div className="mt-4 pt-4 border-t border-slate-100 flex items-center justify-between gap-2">
                                <span className="text-[10px] font-bold text-slate-400 uppercase">Géré par :</span>
                                <select
                                    value={c.assigned_uid || ''}
                                    onChange={(e) => handleAssignPanel(c.id, e.target.value)}
                                    disabled={isSaving}
                                    className="text-xs font-bold text-slate-700 border border-slate-200 rounded-lg px-2 py-1 outline-none bg-slate-50 focus:border-emerald-500 transition"
                                >
                                    <option value="">Moi-même (principal)</option>
                                    {data.team.map(m => (
                                        <option key={m.id} value={m.id}>{m.email}</option>
                                    ))}
                                </select>
                            </div>
                        )}
                        {isCollaborator && (
                            <div className="mt-4 pt-4 border-t border-slate-100 text-right">
                                <span className="text-[10px] font-bold text-blue-700 bg-blue-50 px-3 py-1 rounded-md uppercase tracking-wider">Assigné à vous</span>
                            </div>
                        )}
                    </div>
                ))}
                {data.panneaux?.length === 0 && (
                    <div className="col-span-full text-center p-12 bg-white rounded-3xl border border-slate-200 border-dashed">
                        <Building size={48} className="mx-auto text-slate-300 mb-4" />
                        <h3 className="text-lg font-black text-slate-700">Aucun panneau</h3>
                        <p className="text-slate-500 text-sm mt-1">{isCollaborator ? "Aucun panneau ne vous est assigné." : "Créez votre premier panneau pour démarrer."}</p>
                    </div>
                )}
            </div>
        </div>
    );

    const renderLivraisons = () => {
        const deliveries = data.panneaux?.filter(c => c.physicalPanels > 0) || [];
        const activeDeliveries = deliveries.filter(c => c.shipping_status !== 'Livré');
        const historyDeliveries = deliveries.filter(c => c.shipping_status === 'Livré');

        const DeliveryCard = ({ c, isHistory }) => {
            const isShipped = c.shipping_status === 'Expédié';
            const isWaiting = c.shipping_status === 'Validation en cours' || c.shipping_status === "Attente d'impression";
            const displayStatus = c.shipping_status === "Attente d'impression" ? "Validée (en attente d'impression)" : c.shipping_status;
            
            return (
                <div className={`bg-white rounded-3xl p-5 shadow-sm border ${isShipped ? 'border-blue-200' : 'border-slate-200'} flex flex-col gap-4 transition hover:shadow-md`}>
                    <div className="flex gap-4 items-start">
                        <div className={`w-12 h-12 rounded-2xl flex items-center justify-center shrink-0 ${isShipped ? 'bg-blue-50 text-blue-600' : (isHistory ? 'bg-emerald-50 text-emerald-600' : 'bg-slate-100 text-slate-500')}`}>
                            {isHistory ? <CheckCircle size={24} /> : <Package size={24} />}
                        </div>
                        <div className="min-w-0 flex-1">
                            <p className="font-black text-base text-slate-800 truncate" title={c.name}>{c.name}</p>
                            <p className="text-xs text-slate-500 flex items-center gap-1 mt-0.5"><MapPin size={12}/> {c.shippingAddress || c.location}</p>
                        </div>
                        <div className="text-right shrink-0">
                            <p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest mb-1">Quantité</p>
                            <p className="text-lg font-black text-slate-800 leading-none">{c.physicalPanels}</p>
                        </div>
                    </div>

                    <div className={`p-3 rounded-xl border ${isShipped ? 'bg-blue-50/50 border-blue-100' : 'bg-slate-50 border-slate-100'}`}>
                        <div className="flex justify-between items-center mb-1">
                            <p className="text-[10px] font-bold uppercase tracking-widest text-slate-500">Statut de la commande</p>
                            <span className={`px-2 py-0.5 rounded-md text-[10px] font-black uppercase text-center ${isShipped ? 'bg-blue-100 text-blue-700' : (isHistory ? 'bg-emerald-100 text-emerald-700' : 'bg-amber-100 text-amber-700')}`}>
                                {displayStatus}
                            </span>
                        </div>
                        {c.tracking_number && (
                            <div className="mt-3 pt-3 border-t border-slate-200/60">
                                <p className="text-xs font-bold text-slate-700">N° de suivi : <span className="font-mono text-blue-600 ml-1 select-all">{c.tracking_number}</span></p>
                                {c.tracking_link && (
                                    <a href={c.tracking_link} target="_blank" rel="noopener noreferrer" className="text-[11px] font-bold text-blue-600 hover:text-blue-800 flex items-center gap-1 mt-1.5 transition">
                                        <ExternalLink size={12}/> Suivre mon colis sur le site du transporteur
                                    </a>
                                )}
                            </div>
                        )}
                        {isWaiting && (
                            <p className="text-[11px] text-slate-500 mt-2 font-medium">Votre commande est en cours de traitement par nos équipes. Vous recevrez un lien de suivi dès l'expédition.</p>
                        )}
                    </div>

                    {isShipped && !isHistory && (
                        <button onClick={() => setDeliveryConfirmModal(c.id)} disabled={isSaving} className="w-full bg-emerald-600 text-white py-3 rounded-xl font-bold text-sm hover:bg-emerald-700 transition shadow-md flex justify-center items-center gap-2">
                            <CheckCircle size={16}/> Confirmer la réception
                        </button>
                    )}
                </div>
            );
        };

        return (
            <div className="space-y-8 animate-in fade-in slide-in-from-bottom-4">
                <div className="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4">
                    <div><h1 className="text-3xl font-black text-slate-800">Livraisons</h1><p className="text-slate-500 font-medium">Suivi de vos commandes de panneaux physiques.</p></div>
                </div>
                
                {deliveries.length === 0 ? (
                    <div className="text-center p-12 bg-white rounded-3xl border border-slate-200 border-dashed">
                        <Package size={48} className="mx-auto text-slate-300 mb-4" />
                        <h3 className="text-lg font-black text-slate-700">Aucune livraison</h3>
                        <p className="text-slate-500 text-sm mt-1">Vous n'avez pas encore commandé de panneaux physiques.</p>
                    </div>
                ) : (
                    <>
                        {activeDeliveries.length > 0 && (
                            <div className="space-y-4">
                                <h3 className="font-black text-slate-800 text-lg flex items-center gap-2"><Package size={20} className="text-blue-600"/> En cours ({activeDeliveries.length})</h3>
                                <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                                    {activeDeliveries.map(c => <DeliveryCard key={c.id} c={c} isHistory={false} />)}
                                </div>
                            </div>
                        )}
                        
                        {historyDeliveries.length > 0 && (
                            <div className="space-y-4">
                                <h3 className="font-black text-slate-800 text-lg flex items-center gap-2 pt-4 border-t border-slate-200"><CheckCircle size={20} className="text-emerald-600"/> Historique ({historyDeliveries.length})</h3>
                                <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 opacity-80 hover:opacity-100 transition-opacity">
                                    {historyDeliveries.map(c => <DeliveryCard key={c.id} c={c} isHistory={true} />)}
                                </div>
                            </div>
                        )}
                    </>
                )}
            </div>
        );
    };

    const renderMessages = () => {
        const supportThreadId = `SUPPORT_${myClientData.id}`;
        const threadsMap = {
            [supportThreadId]: { id: supportThreadId, title: "Support technique eco-panneau", targetEmail: 'Admin', messages: [], unread: 0, isSupport: true }
        };

        if (isCollaborator) delete threadsMap[supportThreadId];

        interactions.forEach(m => {
            if (m.panneauId === supportThreadId && !isCollaborator) {
                threadsMap[supportThreadId].messages.push(m);
                if (m.author === 'Admin' && !m.resolved) threadsMap[supportThreadId].unread++;
            } else if (m.panneauId !== supportThreadId) {
                const riverainEmail = (m.author !== 'Client' && m.author !== 'Admin') ? m.author : m.target;
                if (!riverainEmail) return;
                
                const threadId = `${m.panneauId}_${riverainEmail}`;
                const panneauName = activePanneaux.find(c => c.id === m.panneauId)?.name || draftPanneaux.find(c => c.id === m.panneauId)?.name || 'Panneau inconnu';
                
                if (!threadsMap[threadId]) {
                    threadsMap[threadId] = { id: threadId, panneauId: m.panneauId, title: `${panneauName} - ${riverainEmail}`, targetEmail: riverainEmail, messages: [], unread: 0, isSupport: false };
                }
                threadsMap[threadId].messages.push(m);
                if (m.author !== 'Client' && !m.resolved) threadsMap[threadId].unread++;
            }
        });

        const threads = Object.values(threadsMap)
            .filter(t => t.isSupport || t.messages.length > 0)
            .sort((a,b) => {
                // CORRECTION : Contournement du bug Date Safari avec le wrapper String
                const dateA = a.messages.length > 0 ? new Date(String(a.messages[0].created_at || '').replace(' ', 'T')).getTime() : 0;
                const dateB = b.messages.length > 0 ? new Date(String(b.messages[0].created_at || '').replace(' ', 'T')).getTime() : 0;
                return dateB - dateA;
            });

        const requestedChatId = new URLSearchParams(window.location.search).get('chat_id');
        const selectedThreadId = requestedChatId || (threads[0]?.id);
        
        const setChatId = (id) => { 
            const u = new URL(window.location); 
            u.searchParams.set('chat_id', id); 
            window.history.replaceState({}, '', u); 
            setMobileChatView(true);
            refreshData(); 
        };
        const selectedThread = threads.find(t => t.id === selectedThreadId);

        const handleSendClient = async (text) => {
            if (!selectedThread) return;
            
            const optimisticMsg = {
                id: 'temp_' + Date.now(),
                panneauId: selectedThread.isSupport ? selectedThread.id : selectedThread.panneauId,
                author: 'Client',
                target: selectedThread.targetEmail,
                detail: text,
                isAlert: 0,
                resolved: 0,
                created_at: new Date().toISOString()
            };
            window.dispatchEvent(new CustomEvent('optimistic_message', { detail: optimisticMsg }));

            const payload = {
                panneauId: selectedThread.isSupport ? selectedThread.id : selectedThread.panneauId,
                detail: text,
                author: 'Client',
                targetEmail: selectedThread.targetEmail
            };
            fetch(window.ECO_CONFIG.apiBaseUrl + 'interactions', { method: 'POST', body: JSON.stringify(payload) });
        };

        const forceChatMobile = mobileChatView || !!requestedChatId || threads.length === 1;

        return (
            <div className="flex flex-col md:flex-row h-[calc(100vh-10rem)] min-h-[600px] bg-white rounded-3xl shadow-sm border border-slate-200 overflow-hidden animate-in fade-in slide-in-from-bottom-4">
                <div className={`w-full h-full md:w-1/3 border-r border-slate-200 flex-col bg-slate-50/50 ${forceChatMobile ? 'hidden md:flex' : 'flex'}`}>
                    <div className="p-4 border-b border-slate-200 bg-white flex justify-between items-center">
                        <h2 className="font-black text-slate-800 text-lg">Conversations</h2>
                    </div>
                    <div className="flex-1 overflow-y-auto p-2 space-y-1 custom-scrollbar">
                        {threads.map(t => (
                            <button key={t.id} onClick={() => setChatId(t.id)} className={`w-full text-left p-3 rounded-xl flex items-center justify-between transition ${selectedThreadId === t.id ? 'bg-emerald-50 border border-emerald-200' : 'hover:bg-white border border-transparent'}`}>
                                <div className="min-w-0 pr-2">
                                    <p className={`text-sm truncate ${t.isSupport ? 'font-black text-emerald-700' : 'font-bold text-slate-800'}`}>{t.title}</p>
                                    <p className="text-xs text-slate-500 truncate">{t.messages.length} messages</p>
                                </div>
                                {t.unread > 0 && <span className="bg-red-500 text-white text-[10px] px-2 py-0.5 rounded-full shrink-0">{t.unread}</span>}
                            </button>
                        ))}
                        {threads.length === 0 && <p className="text-center text-slate-400 text-sm mt-10 italic">Aucune conversation.</p>}
                    </div>
                </div>
                <div className={`w-full h-full md:w-2/3 flex-col relative bg-slate-50 ${forceChatMobile ? 'flex' : 'hidden md:flex'}`}>
                    {selectedThread ? (
                        <>
                            <div className="p-4 border-b border-slate-200 bg-white shrink-0 flex items-center gap-3">
                                {threads.length > 1 && (
                                    <button onClick={() => {
                                        setMobileChatView(false);
                                        const u = new URL(window.location);
                                        u.searchParams.delete('chat_id');
                                        window.history.replaceState({}, '', u);
                                    }} className="md:hidden p-2 -ml-2 text-slate-500 hover:bg-slate-100 rounded-lg transition shrink-0">
                                        <ArrowLeft size={18}/>
                                    </button>
                                )}
                                <h3 className="font-black text-slate-800 truncate">{selectedThread.title}</h3>
                            </div>
                            <div className="flex-1 min-h-0 relative">
                                <div className="absolute inset-0">
                                    <window.ChatBox 
                                        messages={selectedThread.messages} 
                                        currentUserRole="client" 
                                        panneauId={selectedThread.isSupport ? selectedThread.id : selectedThread.panneauId} 
                                        refreshData={refreshData} 
                                        onSend={handleSendClient}
                                        clientName={myClientData.name || 'Client'}
                                    />
                                </div>
                            </div>
                        </>
                    ) : (<div className="flex-1 flex flex-col items-center justify-center text-slate-400"><MessageSquare size={48} className="mb-4 opacity-50"/><p className="font-medium">Sélectionnez une conversation</p></div>)}
                </div>
            </div>
        );
    };

    const renderBilling = () => (
        <div className="space-y-6 animate-in fade-in slide-in-from-bottom-4">
            <div className="flex justify-between items-center">
                <div><h1 className="text-3xl font-black text-slate-800">Factures</h1><p className="text-slate-500 font-medium">Historique comptable et paiements.</p></div>
                <a href="?api=invoices/export_csv" className="bg-white border border-slate-200 text-slate-700 px-4 py-2.5 rounded-xl font-bold text-sm hover:bg-slate-50 transition shadow-sm flex items-center gap-2"><Download size={16}/> Export CSV</a>
            </div>

            {myClientData.wallet_balance > 0 && (
                <div className="bg-emerald-50 border border-emerald-200 p-5 rounded-3xl mb-6 flex flex-col sm:flex-row items-start sm:items-center justify-between shadow-sm gap-4">
                    <div className="flex items-center gap-4">
                        <div className="w-12 h-12 bg-emerald-100 text-emerald-600 rounded-2xl flex items-center justify-center shrink-0"><Zap size={24}/></div>
                        <div>
                            <p className="text-sm font-bold text-emerald-900">Solde disponible (Avoir / Crédit)</p>
                            <p className="text-xs text-emerald-700 mt-1 font-medium">Ce montant sera automatiquement déduit de vos prochains achats ou abonnements.</p>
                        </div>
                    </div>
                    <div className="text-3xl font-black text-emerald-600 shrink-0">
                        {myClientData.wallet_balance.toFixed(2)} €
                    </div>
                </div>
            )}
            
            <div className="bg-white rounded-3xl shadow-sm border border-slate-200 overflow-x-auto">
                <table className="w-full text-left border-collapse whitespace-nowrap">
                    <thead>
                        <tr className="bg-slate-50 text-[10px] uppercase tracking-widest text-slate-500 border-b border-slate-200">
                            <th className="p-4 font-bold">Date</th><th className="p-4 font-bold">Panneau</th><th className="p-4 font-bold">Détail</th><th className="p-4 font-bold">Montant</th><th className="p-4 font-bold text-right">PDF</th>
                        </tr>
                    </thead>
                    <tbody className="divide-y divide-slate-100">
                        {data.invoices?.map((inv, i) => (
                            <tr key={i} className="hover:bg-slate-50 transition">
                                {/* CORRECTION : Contournement du bug Date Safari avec le wrapper String */}
                                <td className="p-4 text-sm font-bold text-slate-700">{new Date(String(inv.created_at || '').replace(' ', 'T')).toLocaleDateString('fr-FR')}</td>
                                <td className="p-4 text-sm text-slate-600 truncate max-w-[200px]">{inv.panneauName}</td>
                                <td className="p-4 text-sm text-slate-600">{inv.type}</td>
                                <td className="p-4 text-sm font-black text-slate-800">{inv.amount} €</td>
                                <td className="p-4 text-right"><a href={`?api=invoices/download&ref=${inv.invoiceNumber}`} title="Télécharger la facture" className="inline-flex p-2 bg-slate-100 text-slate-600 rounded-lg hover:bg-slate-200 transition"><Download size={16}/></a></td>
                            </tr>
                        ))}
                    </tbody>
                </table>
                {data.invoices?.length === 0 && <div className="p-12 text-center text-slate-500"><FileText size={48} className="mx-auto mb-4 opacity-50"/>Aucune facture pour le moment.</div>}
            </div>
        </div>
    );

    const renderAccount = () => (
        <div className="space-y-6 animate-in fade-in slide-in-from-bottom-4">
            <div><h1 className="text-3xl font-black text-slate-800">Mon compte</h1><p className="text-slate-500 font-medium">Paramètres de profil et sécurité.</p></div>

            <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
                <div className="bg-white rounded-3xl p-6 sm:p-8 shadow-sm border border-slate-200">
                    <div className="flex justify-between items-center mb-6">
                        <h3 className="font-black text-slate-800 flex items-center gap-2"><Building size={18} className="text-emerald-600"/> Profil de la société</h3>
                        {!isCollaborator && (
                            <button onClick={handleAutoFill} className="text-xs font-bold text-blue-700 bg-blue-50 hover:bg-blue-100 px-3 py-1.5 rounded-lg flex items-center gap-1 transition border border-blue-200 shadow-sm">
                                <Zap size={14}/> Saisie automatique
                            </button>
                        )}
                    </div>
                    <div className="space-y-4">
                        
                        {!isCollaborator && (
                            <div className="flex items-center gap-4 mb-4 pb-4 border-b border-slate-100">
                                <label className="flex items-center gap-2 cursor-pointer">
                                    <input type="radio" name="type_client" value="particulier" checked={profileData.type_client === 'particulier'} onChange={(e) => setProfileData({...profileData, type_client: e.target.value})} className="w-4 h-4 accent-emerald-600" />
                                    <span className="text-sm font-bold text-slate-700">Particulier</span>
                                </label>
                                <label className="flex items-center gap-2 cursor-pointer">
                                    <input type="radio" name="type_client" value="entreprise" checked={profileData.type_client === 'entreprise'} onChange={(e) => setProfileData({...profileData, type_client: e.target.value})} className="w-4 h-4 accent-emerald-600" />
                                    <span className="text-sm font-bold text-slate-700">Entreprise</span>
                                </label>
                            </div>
                        )}

                        <div className="space-y-1"><label className="text-xs font-bold text-slate-500 uppercase block">{profileData.type_client === 'entreprise' ? 'Nom / raison sociale *' : 'Nom complet *'}</label><input value={profileData.name} onChange={e=>setProfileData({...profileData, name: e.target.value})} disabled={isCollaborator} className="w-full border-2 border-slate-200 rounded-xl p-3 text-sm focus:border-emerald-500 outline-none transition disabled:bg-slate-50" /></div>
                        <div className="space-y-1"><label className="text-xs font-bold text-slate-500 uppercase block">Adresse complète *</label><textarea value={profileData.address} onChange={e=>setProfileData({...profileData, address: e.target.value})} disabled={isCollaborator} rows="2" className="w-full border-2 border-slate-200 rounded-xl p-3 text-sm focus:border-emerald-500 outline-none transition resize-none disabled:bg-slate-50"></textarea></div>
                        
                        {profileData.type_client === 'entreprise' && (
                            <>
                                <div className="space-y-1"><label className="text-xs font-bold text-slate-500 uppercase block">SIRET *</label><input value={profileData.siret} onChange={e=>setProfileData({...profileData, siret: e.target.value})} disabled={isCollaborator} className="w-full border-2 border-slate-200 rounded-xl p-3 text-sm focus:border-emerald-500 outline-none transition disabled:bg-slate-50" /></div>
                                
                                {!isCollaborator && (
                                    <label className="flex items-center gap-3 p-3 bg-slate-50 border border-slate-200 rounded-xl cursor-pointer hover:bg-slate-100 transition mt-2">
                                        <input type="checkbox" checked={profileData.employees_gt_5} onChange={(e) => setProfileData({...profileData, employees_gt_5: e.target.checked})} className="w-5 h-5 accent-emerald-600" />
                                        <div><p className="text-sm font-bold text-slate-800">L'entreprise compte plus de 5 employés</p></div>
                                    </label>
                                )}

                                {!isCollaborator && (
                                    <div className="pt-2 border-t border-slate-100 mt-4">
                                        <label className="flex items-center justify-between cursor-pointer group py-2">
                                            <div>
                                                <p className="text-sm font-bold text-slate-800">Assujetti à la TVA</p>
                                                <p className="text-[10px] font-medium text-slate-500">Mon entreprise facture la TVA.</p>
                                            </div>
                                            <div className={`w-12 h-6 rounded-full transition-colors relative shrink-0 ${hasTva ? 'bg-emerald-500' : 'bg-slate-300'}`}>
                                                <div className={`absolute top-1 bg-white w-4 h-4 rounded-full transition-transform ${hasTva ? 'left-7' : 'left-1'}`}></div>
                                            </div>
                                            <input type="checkbox" className="hidden" checked={hasTva} onChange={handleToggleTva} />
                                        </label>

                                        {hasTva && (
                                            <div className="space-y-1 mt-2 animate-in fade-in slide-in-from-top-2">
                                                <label className="text-xs font-bold text-slate-500 uppercase block">TVA intracommunautaire *</label>
                                                <input value={profileData.tva} onChange={e=>setProfileData({...profileData, tva: e.target.value})} placeholder="FR..." className="w-full border-2 border-slate-200 rounded-xl p-3 text-sm focus:border-emerald-500 outline-none transition uppercase" />
                                            </div>
                                        )}
                                    </div>
                                )}
                            </>
                        )}

                        {!isCollaborator && (
                            <label className="flex items-center gap-3 p-4 border border-slate-200 rounded-xl cursor-pointer hover:bg-slate-50 transition mt-4">
                                <input type="checkbox" checked={profileData.monthlyReport === 1} onChange={(e) => setProfileData({...profileData, monthlyReport: e.target.checked ? 1 : 0})} className="w-5 h-5 accent-emerald-600" />
                                <div><p className="text-sm font-bold text-slate-800">Rapports d'activité</p><p className="text-xs text-slate-500">Recevoir un e-mail mensuel sur l'usage des panneaux.</p></div>
                            </label>
                        )}
                        {!isCollaborator && <button onClick={handleSaveProfile} disabled={isSaving} className="w-full bg-slate-900 text-white py-3 rounded-xl font-bold shadow-md hover:bg-slate-800 transition disabled:opacity-50">Enregistrer les modifications</button>}
                    </div>
                </div>

                <div className="space-y-6">

                    <div className="bg-white rounded-3xl p-6 sm:p-8 shadow-sm border border-slate-200">
                        <h3 className="font-black text-slate-800 mb-6 flex items-center gap-2"><Lock size={18} className="text-emerald-600"/> Sécurité</h3>
                        <div className="space-y-4">
                            <div className="space-y-1"><label className="text-xs font-bold text-slate-500 uppercase block">Ancien mot de passe</label><input type="password" value={passwordData.oldPassword} onChange={e=>setPasswordData({...passwordData, oldPassword: e.target.value})} className="w-full border-2 border-slate-200 rounded-xl p-3 text-sm focus:border-emerald-500 outline-none transition" /></div>
                            <div className="space-y-1"><label className="text-xs font-bold text-slate-500 uppercase block">Nouveau mot de passe</label><input type="password" value={passwordData.newPassword} onChange={e=>setPasswordData({...passwordData, newPassword: e.target.value})} className="w-full border-2 border-slate-200 rounded-xl p-3 text-sm focus:border-emerald-500 outline-none transition" placeholder="Min 8 car., Maj, Min, Chiffre" /></div>
                            <button onClick={handleSavePassword} disabled={isSaving} className="w-full bg-slate-100 text-slate-700 py-3 rounded-xl font-bold hover:bg-slate-200 transition disabled:opacity-50">Modifier le mot de passe</button>
                        </div>
                    </div>

                    <div className="bg-white rounded-3xl p-6 sm:p-8 shadow-sm border border-slate-200 mt-6">
                        <h3 className="font-black text-slate-800 mb-6 flex items-center gap-2"><ShieldCheck size={18} className="text-emerald-600"/> Authentification à double facteur (2FA)</h3>
                        <p className="text-xs text-slate-500 mb-4">Protégez votre compte avec une étape de sécurité supplémentaire lors de la connexion.</p>
                        
                        <div className="space-y-3">
                            <label className={`flex items-center gap-3 p-4 border rounded-xl cursor-pointer transition shadow-sm ${profileData.two_factor_method === 'none' ? 'border-emerald-500 bg-emerald-50' : 'border-slate-200 hover:bg-slate-50'}`}>
                                <input type="radio" name="2fa_method" checked={profileData.two_factor_method === 'none'} onChange={async () => {
                                    setIsSaving(true);
                                    await fetch(window.ECO_CONFIG.apiBaseUrl + 'clients/profile/update_2fa', { method: 'POST', body: JSON.stringify({ method: 'none' }) });
                                    setProfileData({...profileData, two_factor_method: 'none'});
                                    setTotpSetupData(null);
                                    showToast("2FA désactivée.");
                                    setIsSaving(false);
                                }} className="w-5 h-5 accent-emerald-600 shrink-0" />
                                <div className="flex-1"><span className="text-sm font-bold text-slate-800">Désactivée</span></div>
                            </label>

                            <label className={`flex items-center gap-3 p-4 border rounded-xl cursor-pointer transition shadow-sm ${profileData.two_factor_method === 'email' ? 'border-emerald-500 bg-emerald-50' : 'border-slate-200 hover:bg-slate-50'}`}>
                                <input type="radio" name="2fa_method" checked={profileData.two_factor_method === 'email'} onChange={async () => {
                                    setIsSaving(true);
                                    await fetch(window.ECO_CONFIG.apiBaseUrl + 'clients/profile/update_2fa', { method: 'POST', body: JSON.stringify({ method: 'email' }) });
                                    setProfileData({...profileData, two_factor_method: 'email'});
                                    setTotpSetupData(null);
                                    showToast("2FA par e-mail activée.");
                                    setIsSaving(false);
                                }} className="w-5 h-5 accent-emerald-600 shrink-0" />
                                <div className="flex-1">
                                    <span className="text-sm font-bold text-slate-800 block">Par e-mail</span>
                                    <span className="text-[10px] text-slate-500 leading-tight">Un code à 6 chiffres vous sera envoyé à chaque connexion.</span>
                                </div>
                            </label>

                            <label className={`flex items-center gap-3 p-4 border rounded-xl cursor-pointer transition shadow-sm ${profileData.two_factor_method === 'totp' ? 'border-emerald-500 bg-emerald-50' : 'border-slate-200 hover:bg-slate-50'}`}>
                                <input type="radio" name="2fa_method" checked={profileData.two_factor_method === 'totp'} onChange={() => {
                                    if (profileData.two_factor_method !== 'totp') enableTotp();
                                }} className="w-5 h-5 accent-emerald-600 shrink-0" />
                                <div className="flex-1">
                                    <span className="text-sm font-bold text-slate-800 block">Application (Google Auth, Authy...)</span>
                                    <span className="text-[10px] text-slate-500 leading-tight">Générez des codes hors-ligne directement sur votre smartphone.</span>
                                </div>
                            </label>
                        </div>
                    </div>

                    {!isCollaborator && isAdvancedMode && (
                        <div className="bg-white rounded-3xl p-6 sm:p-8 shadow-sm border border-slate-200">
                            <h3 className="font-black text-slate-800 mb-2 flex items-center gap-2"><Users size={18} className="text-emerald-600"/> Équipe de collaborateurs</h3>
                            <p className="text-xs text-slate-500 mb-4">Gérez les accès de votre équipe à vos panneaux.</p>
                            <button onClick={() => setModalStep('team_manage')} className="w-full bg-slate-100 text-slate-700 py-3 rounded-xl font-bold hover:bg-slate-200 transition flex justify-center items-center gap-2 shadow-sm"><Users size={16}/> Gérer l'équipe ({data.team?.length || 0})</button>
                        </div>
                    )}

                    {/* Bloc Documents Légaux */}
                    <div className="bg-white p-6 rounded-3xl border border-slate-200 shadow-sm mt-6">
                        <h3 className="font-black text-slate-800 mb-2 flex items-center gap-2"><FileText size={18} className="text-slate-600"/> Documents légaux</h3>
                        <p className="text-xs text-slate-500 mb-4 leading-relaxed font-medium">Consultez nos conditions d'utilisation et notre politique de confidentialité.</p>
                        <div className="flex flex-col sm:flex-row gap-3">
                            <button onClick={() => setLegalModal('cgv')} className="flex-1 bg-slate-50 border border-slate-200 text-slate-700 px-4 py-3 rounded-xl font-bold text-sm shadow-sm hover:bg-slate-100 transition flex items-center justify-center gap-2">
                                Conditions générales de vente
                            </button>
                            <button onClick={() => setLegalModal('rgpd')} className="flex-1 bg-slate-50 border border-slate-200 text-slate-700 px-4 py-3 rounded-xl font-bold text-sm shadow-sm hover:bg-slate-100 transition flex items-center justify-center gap-2">
                                Politique de confidentialité
                            </button>
                        </div>
                    </div>

                    <div className="bg-indigo-50 p-6 rounded-2xl border border-indigo-100 shadow-sm mt-6">
                        <h3 className="font-black text-indigo-900 mb-2 flex items-center gap-2"><Bell size={18}/> Alertes navigateur</h3>
                        <p className="text-xs text-indigo-700/80 mb-4 leading-relaxed font-medium">Recevez une alerte visuelle et sonore sur votre PC/Mobile dès qu'un riverain poste un message.</p>
                        <button onClick={togglePush} className={`w-full px-4 py-3 rounded-xl font-bold text-sm transition shadow-sm ${pushEnabled ? 'bg-indigo-200 text-indigo-800 hover:bg-indigo-300' : 'bg-indigo-600 text-white hover:bg-indigo-700'}`}>
                            {pushEnabled ? 'Désactiver les alertes' : 'Activer les alertes (Opt-in)'}
                        </button>
                    </div>

                    {!isCollaborator && (
                        <div className="bg-slate-50 p-6 rounded-2xl border border-slate-200 shadow-sm mt-6">
                            <h3 className="font-black text-slate-800 mb-2 flex items-center gap-2"><Download size={18} className="text-blue-600"/> Données personnelles (RGPD)</h3>
                            <p className="text-xs text-slate-500 mb-4 leading-relaxed font-medium">Téléchargez une archive complète de vos données personnelles (profil, factures, panneaux, D.O.E, pièces jointes) au format ZIP sécurisé.</p>
                            <button onClick={() => setArchiveConfig({ type: 'rgpd' })} disabled={archiveConfig !== null} className="w-full bg-white border border-slate-200 text-slate-700 px-4 py-3 rounded-xl font-bold text-sm shadow-sm hover:bg-slate-50 transition flex items-center justify-center gap-2 disabled:opacity-50">
                                <Download size={16}/> Exporter mes données
                            </button>
                        </div>
                    )}

                    {!isCollaborator && (
                        <div className="bg-red-50 p-6 rounded-2xl border border-red-100 shadow-sm">
                            <h3 className="font-black text-red-900 mb-2 flex items-center gap-2"><Power size={18}/> Zone de danger</h3>
                            <p className="text-xs text-red-700/80 mb-4 leading-relaxed font-medium">La suppression de votre compte effacera définitivement tous vos panneaux, factures et fichiers (D.O.E inclus).</p>
                            <button onClick={requestAccountDeletion} className="w-full bg-red-600 text-white px-4 py-3 rounded-xl font-bold text-sm shadow-md hover:bg-red-700 transition">Supprimer mon compte définitivement</button>
                        </div>
                    )}
                </div>
            </div>
        </div>
    );

    return (
        <window.DashboardLayout 
            role={isCollaborator ? "Collaborateur" : "Client titulaire"} 
            user={myClientData.name || 'Connecté'} 
            theme="emerald" 
            navItems={finalNavItems} 
            activeTab={activeTab} 
            setActiveTab={setActiveTab} 
            onLogout={handleLogout} 
            customLogout={finalCustomLogout}
            sidebarFooter={(!isCollaborator && !allSimpOptionsActive) ? (
                <label className="flex items-center justify-between p-3 rounded-xl border border-slate-200 bg-white hover:bg-slate-50 transition cursor-pointer mb-2" title="Activer les fonctionnalités avancées (équipes, personnalisation)">
                    <span className="text-xs font-bold text-slate-700">Mode avancé</span>
                    <div className={`w-8 h-4 rounded-full transition-colors relative shrink-0 ${uiMode === 'professionnel' ? 'bg-emerald-500' : 'bg-slate-300'}`}>
                        <div className={`absolute top-[2px] bg-white w-3 h-3 rounded-full transition-transform ${uiMode === 'professionnel' ? 'translate-x-4' : 'translate-x-1'}`}></div>
                    </div>
                    <input type="checkbox" className="hidden" checked={uiMode === 'professionnel'} onChange={(e) => handleUiModeChange(e.target.checked)} disabled={isSaving} />
                </label>
            ) : null}
        >
            {window.ECO_CONFIG.stripePubKey?.startsWith('pk_test_') && (
                <div className="bg-yellow-100 text-yellow-800 p-3 text-center font-bold text-sm shadow-sm mb-6 rounded-2xl border border-yellow-200">
                    Mode Test Stripe Actif - Aucun débit réel ne sera effectué lors de vos transactions.
                </div>
            )}

            {isLockedForClient && (
                <div className="bg-orange-50 border border-orange-200 p-4 sm:p-6 rounded-2xl flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4 mb-8 shadow-sm animate-in fade-in slide-in-from-top-4">
                    <div className="flex items-center gap-4">
                        <div className="w-12 h-12 bg-orange-100 text-orange-600 rounded-full flex items-center justify-center shrink-0">
                            <Lock size={24}/>
                        </div>
                        <div>
                            <h3 className="font-black text-orange-900 text-lg">Télémaintenance en cours</h3>
                            <p className="text-orange-800 text-sm font-medium mt-1">L'équipe technique intervient sur votre compte. Vos actions sont temporairement restreintes à la messagerie.</p>
                        </div>
                    </div>
                    <button onClick={handleRevokeAccess} disabled={isSaving} className="w-full sm:w-auto shrink-0 bg-orange-600 text-white px-5 py-3 rounded-xl font-bold text-sm hover:bg-orange-700 transition shadow-md flex justify-center items-center gap-2 disabled:opacity-50">
                        {isSaving ? <Loader size={18} className="animate-spin"/> : <ShieldAlert size={18}/>} Reprendre le contrôle
                    </button>
                </div>
            )}

            {isImpersonating && (
                <div className="bg-emerald-50 border border-emerald-200 p-4 sm:p-6 rounded-2xl flex flex-col lg:flex-row items-start lg:items-center justify-between gap-4 mb-8 shadow-sm animate-in fade-in slide-in-from-top-4">
                    <div className="flex items-center gap-4">
                        <div className="w-12 h-12 bg-emerald-100 text-emerald-600 rounded-full flex items-center justify-center shrink-0">
                            <Eye size={24}/>
                        </div>
                        <div>
                            <h3 className="font-black text-emerald-900 text-lg">Mode administrateur actif</h3>
                            <p className="text-emerald-800 text-sm font-medium mt-1">Vous contrôlez actuellement le compte de <strong>{myClientData.name}</strong>. N'oubliez pas de clôturer l'intervention une fois terminé.</p>
                        </div>
                    </div>
                    <div className="flex flex-col sm:flex-row gap-3 shrink-0 w-full lg:w-auto">
                        <button onClick={handleUnimpersonate} className="flex-1 sm:flex-none justify-center bg-white border border-emerald-200 text-emerald-700 px-5 py-3 rounded-xl font-bold text-sm hover:bg-emerald-50 transition shadow-sm flex items-center gap-2"><ArrowLeft size={16}/> Pause</button>
                        <button onClick={handleRevokeAccess} disabled={isSaving} className="flex-1 sm:flex-none justify-center bg-emerald-600 text-white px-5 py-3 rounded-xl font-bold text-sm hover:bg-emerald-700 transition shadow-md flex items-center gap-2 disabled:opacity-50">
                            {isSaving ? <Loader size={18} className="animate-spin"/> : <CheckCircle size={18}/>} Clôturer (Fin)
                        </button>
                    </div>
                </div>
            )}

            {(!isLockedForClient && activeTab === 'dashboard') && renderDashboard()}
            {(!isLockedForClient && activeTab === 'panels') && renderPanels()}
            {(!isLockedForClient && activeTab === 'livraisons') && renderLivraisons()}
            {activeTab === 'messages' && renderMessages()}
            {(!isLockedForClient && activeTab === 'billing') && renderBilling()}
            {(!isLockedForClient && activeTab === 'account') && renderAccount()}

            {isModalOpen && modalStep.startsWith('config') && (
                <div className="fixed inset-0 bg-slate-900/80 backdrop-blur-md z-[200] animate-in fade-in duration-300 flex items-center justify-center p-0 sm:p-4" onMouseDown={(e) => { if(e.target === e.currentTarget) document.getElementById('editor-cancel-btn')?.click(); }}>
                    <div className="h-full sm:h-[95vh] w-full max-w-5xl mx-auto bg-white sm:rounded-3xl shadow-2xl flex flex-col relative overflow-hidden" onMouseDown={e => e.stopPropagation()}>
                        <div className="p-4 sm:p-6 border-b border-slate-100 flex justify-between items-center bg-slate-50 shrink-0">
                            <div><h2 className="text-xl font-black text-slate-800">{managingPanneau.id ? 'Édition du panneau' : 'Nouveau panneau'}</h2><p className="text-xs text-slate-500 font-medium">Assurez-vous de l'exactitude des informations légales.</p></div>
                            <button onClick={() => document.getElementById('editor-cancel-btn')?.click()} className="text-slate-400 hover:bg-white hover:text-slate-700 p-2 rounded-xl border border-transparent hover:border-slate-200 transition" title="Fermer"><X size={24}/></button>
                        </div>
                        
                        {validationErrors.length > 0 && (
                            <div className="mx-4 sm:mx-6 mt-4 bg-red-50 border-2 border-red-200 p-4 rounded-xl">
                                <h4 className="font-black text-red-800 flex items-center gap-2 mb-2"><AlertTriangle size={18}/> Impossible de publier. Éléments bloquants :</h4>
                                <ul className="list-disc pl-5 text-sm text-red-700 space-y-1 font-medium">
                                    {validationErrors.map((err, idx) => <li key={idx}>{err}</li>)}
                                </ul>
                            </div>
                        )}

                        <div className="flex-1 relative overflow-hidden">
                            <window.PanneauEditorForm 
                                panneau={managingPanneau} 
                                setPanneau={setManagingPanneau} 
                                managingPanneau={managingPanneau} 
                                onCancel={() => setIsModalOpen(false)} 
                                onSaveDraft={() => handleSavePanneau(true)} 
                                onPublish={
                                    isCollaborator 
                                    ? (managingPanneau.status === 'Actif' ? () => {
                                        const errs = validatePanel();
                                        if (errs.length > 0) setValidationErrors(errs);
                                        else handleSavePanneau(false);
                                      } : undefined) 
                                    : () => {
                                        const errs = validatePanel();
                                        if (errs.length > 0) {
                                            setValidationErrors(errs);
                                        } else {
                                            setValidationErrors([]);
                                            
                                            // CALCULER S'IL S'AGIT D'UN NOUVEL ACHAT/UPGRADE SUR UN PANNEAU DEJA ACTIF
                                            const original = data.panneaux.find(p => p.id === managingPanneau.id);
                                            const upgrading = original && original.status === 'Actif' && (
                                                (original.offerType === 'rental' && managingPanneau.offerType === 'purchase') ||
                                                (!original.hasNoAds && managingPanneau.hasNoAds) ||
                                                (managingPanneau.physicalPanels > original.physicalPanels)
                                            );

                                            if (managingPanneau.status === 'Brouillon' || upgrading) {
                                                setWaiverAccepted(false);
                                                setModalStep('select_offer');
                                            } else {
                                                handleSavePanneau(false);
                                            }
                                        }
                                    }
                                }
                                onPreview={() => setPreviewPanneau(managingPanneau)}
                                onEditEntity={(loc, data) => setEditingEntity({location: loc, data})} 
                                draggedItem={draggedItem} 
                                handleDragStart={handleDragStart} 
                                handleDragOver={handleDragOver} 
                                handleDrop={handleDrop} 
                                deleteEntity={deleteEntity} 
                                isSaving={isSaving} 
                                uiMode={uiMode} 
                                settings={data.settings}
                                validationErrors={validationErrors}
                            />
                        </div>
                        {editingEntity && <window.EntityEditorModal editingEntity={editingEntity} setEditingEntity={setEditingEntity} saveEditedEntity={saveEditedEntity} />}
                    </div>
                </div>
            )}

            {isModalOpen && modalStep === 'select_offer' && (
                <div className="fixed inset-0 bg-slate-900/80 backdrop-blur-md z-[200] animate-in fade-in duration-300 flex items-center justify-center p-4">
                    <div className="w-full max-w-2xl bg-white rounded-3xl shadow-2xl flex flex-col relative overflow-hidden">
                        <div className="p-6 border-b border-slate-100 bg-slate-50 flex justify-between items-center">
                            <div><h2 className="text-xl font-black text-slate-800">Choix de l'offre</h2><p className="text-xs text-slate-500 font-medium">Sélectionnez le type d'abonnement et les options matérielles.</p></div>
                            <button onClick={() => setModalStep('config_full')} className="text-slate-400 hover:bg-white hover:text-slate-700 p-2 rounded-xl border border-transparent hover:border-slate-200 transition" title="Retour à l'édition"><X size={24}/></button>
                        </div>
                        <div className="p-6 space-y-8 overflow-y-auto custom-scrollbar max-h-[80vh]">
                            
                            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                                <div 
                                    onClick={() => setManagingPanneau({...managingPanneau, offerType: 'rental'})}
                                    className={`p-6 rounded-2xl border-2 cursor-pointer transition flex flex-col justify-between ${currentOfferType === 'rental' ? 'border-emerald-500 bg-emerald-50 shadow-md' : 'border-slate-200 hover:border-emerald-200'} ${(isActif && originalOfferType === 'purchase') ? 'opacity-50 pointer-events-none' : ''}`}
                                >
                                    <div>
                                        <div className="flex items-center gap-2 mb-2"><div className={`w-4 h-4 rounded-full border-2 flex items-center justify-center ${currentOfferType === 'rental' ? 'border-emerald-600' : 'border-slate-300'}`}><div className={`w-2 h-2 rounded-full bg-emerald-600 transition-opacity ${currentOfferType === 'rental' ? 'opacity-100' : 'opacity-0'}`}></div></div><h4 className="font-black text-slate-800">Abonnement mensuel</h4></div>
                                        <p className="text-3xl font-black text-emerald-600 my-4">{pRental} € <span className="text-sm font-bold text-slate-500">HT / mois</span></p>
                                        <p className="text-sm text-slate-600 leading-relaxed font-medium">Paiement mensuel automatisé. Résiliable à tout moment, en un clic, à la fin de vos travaux. Engagement mensuel, tout mois entamé est dû.</p>
                                    </div>
                                </div>
                                <div 
                                    onClick={() => setManagingPanneau({...managingPanneau, offerType: 'purchase'})}
                                    className={`p-6 rounded-2xl border-2 cursor-pointer transition flex flex-col justify-between ${currentOfferType === 'purchase' ? 'border-emerald-500 bg-emerald-50 shadow-md' : 'border-slate-200 hover:border-emerald-200'}`}
                                >
                                    <div>
                                        <div className="flex items-center gap-2 mb-2"><div className={`w-4 h-4 rounded-full border-2 flex items-center justify-center ${currentOfferType === 'purchase' ? 'border-emerald-600' : 'border-slate-300'}`}><div className={`w-2 h-2 rounded-full bg-emerald-600 transition-opacity ${currentOfferType === 'purchase' ? 'opacity-100' : 'opacity-0'}`}></div></div><h4 className="font-black text-slate-800">Achat définitif</h4></div>
                                        <p className="text-3xl font-black text-emerald-600 my-4">{pPurchase} € <span className="text-sm font-bold text-slate-500">HT</span></p>
                                        <p className="text-sm text-slate-600 leading-relaxed font-medium">Paiement unique sans abonnement. Le panneau numérique reste actif indéfiniment.</p>
                                    </div>
                                </div>
                            </div>

                            <div className="bg-slate-50 p-6 rounded-2xl border border-slate-200 shadow-sm">
                                <h4 className="font-black text-slate-800 mb-2 flex items-center gap-2"><Package size={18} className="text-blue-600"/> Commander des panneaux physiques</h4>
                                <p className="text-sm text-slate-600 mb-6">Recevez votre panneau pré-imprimé (Format A1) sur un support rigide Akilux résistant aux intempéries, livré directement au cabinet.</p>
                                
                                <div className="flex items-center justify-between bg-white p-4 rounded-xl border border-slate-200 mb-4">
                                    <div>
                                        <p className="text-sm font-bold text-slate-800">Quantité souhaitée</p>
                                        <p className="text-xs text-slate-500 mt-1 font-medium">{pBoardFirst}€ HT le premier, {pBoardAdd}€ HT l'unité supplémentaire.</p>
                                    </div>
                                    <div className="flex items-center gap-4 bg-slate-50 border border-slate-200 rounded-xl p-1 shadow-inner">
                                        <button onClick={() => setManagingPanneau({...managingPanneau, physicalPanels: Math.max(originalPanels, currentPanels - 1)})} className="w-10 h-10 flex items-center justify-center rounded-lg bg-white text-slate-600 hover:text-emerald-600 shadow-sm transition font-black text-xl">-</button>
                                        <span className="font-black text-xl w-6 text-center text-slate-800">{currentPanels}</span>
                                        <button onClick={() => setManagingPanneau({...managingPanneau, physicalPanels: currentPanels + 1})} className="w-10 h-10 flex items-center justify-center rounded-lg bg-white text-slate-600 hover:text-emerald-600 shadow-sm transition font-black text-xl">+</button>
                                    </div>
                                </div>
                                
                                {currentPanels > 0 && (
                                    <div className="bg-white p-4 rounded-xl border border-slate-200 animate-in fade-in slide-in-from-top-2">
                                        <label className="text-sm font-bold text-slate-800 block mb-1">Adresse de livraison</label>
                                        <p className="text-[10px] text-slate-500 mb-3">Laissez vide pour utiliser l'adresse de votre société.</p>
                                        <textarea 
                                            value={managingPanneau.shippingAddress || ''} 
                                            onChange={e => setManagingPanneau({...managingPanneau, shippingAddress: e.target.value})} 
                                            className="w-full border border-slate-200 rounded-lg p-3 text-sm focus:border-blue-500 outline-none transition resize-none bg-slate-50 focus:bg-white" 
                                            rows="2" 
                                            placeholder={profileData.address || "Bâtiment, rue, code postal, ville..."}
                                        ></textarea>
                                    </div>
                                )}
                            </div>

                            {/* Résumé en temps réel */}
                            <div className="bg-slate-900 rounded-2xl p-5 text-white shadow-xl">
                                <h4 className="text-sm font-bold text-slate-300 uppercase tracking-widest mb-3 border-b border-slate-700 pb-2">Résumé de votre commande</h4>
                                <div className="space-y-2 text-sm font-medium">
                                    {!isActif && (
                                        <>
                                            <div className="flex justify-between"><span className="text-slate-300">{currentOfferType === 'rental' ? 'Abonnement mensuel (1er mois inclus)' : 'Achat définitif'}</span><span>{(currentOfferType === 'rental' ? pRental : pPurchase).toFixed(2)} € HT</span></div>
                                            {currentOfferType === 'purchase' && <div className="flex justify-between items-center"><span className="text-slate-300">Hébergement annuel (1ère année offerte)</span><span>0.00 € HT <span className="line-through text-slate-500 text-xs ml-1">{pHosting.toFixed(2)} €</span></span></div>}
                                            {currentPanels > 0 && <div className="flex justify-between"><span className="text-slate-300">Panneaux physiques ({currentPanels}x)</span><span>{(currentPanels > 0 ? pBoardFirst + (currentPanels - 1) * pBoardAdd : 0).toFixed(2)} € HT</span></div>}
                                            {currentHasNoAds && <div className="flex justify-between"><span className="text-slate-300">Option marque blanche (Sans mentions de eco-panneau.fr)</span><span>{pNoAds.toFixed(2)} € HT</span></div>}
                                        </>
                                    )}
                                    {isActif && (
                                        <>
                                            {originalOfferType === 'rental' && currentOfferType === 'purchase' && <div className="flex justify-between"><span className="text-slate-300">Passage à l'achat définitif</span><span>{pPurchase.toFixed(2)} € HT</span></div>}
                                            {currentPanels > originalPanels && <div className="flex justify-between"><span className="text-slate-300">Panneaux physiques supp. ({currentPanels - originalPanels}x)</span><span>{addedPanelsCost.toFixed(2)} € HT</span></div>}
                                            {currentHasNoAds && !originalHasNoAds && <div className="flex justify-between"><span className="text-slate-300">Option marque blanche (Sans mentions de eco-panneau.fr)</span><span>{pNoAds.toFixed(2)} € HT</span></div>}
                                        </>
                                    )}
                                    
                                    {discountPct > 0 && upfrontHT > 0 && (
                                        <div className="flex justify-between text-emerald-400">
                                            <span>Remise client ({discountPct}%)</span>
                                            <span>-{(upfrontHT * (discountPct / 100)).toFixed(2)} € HT</span>
                                        </div>
                                    )}

                                    {/* NOUVEAU : Affichage de la déduction de la cagnotte */}
                                    {myClientData.wallet_balance > 0 && upfrontHT > 0 && (
                                        <div className="flex justify-between text-emerald-400 border-t border-slate-700/50 mt-2 pt-2">
                                            <span>Payé avec votre solde (Avoir)</span>
                                            <span>-{Math.min(finalUpfrontTTC, myClientData.wallet_balance).toFixed(2)} € TTC</span>
                                        </div>
                                    )}

                                    <div className="border-t border-slate-700 mt-3 pt-3 flex justify-between items-end">
                                        <div>
                                            <p className="text-lg font-black">Reste à payer aujourd'hui</p>
                                            <p className="text-[10px] text-slate-400 uppercase tracking-wider mt-1">{platformHasTva ? 'TVA 20% incluse' : 'TVA non applicable'}</p>
                                        </div>
                                        <div className="text-right">
                                            <p className="text-2xl font-black text-emerald-400">{Math.max(0, finalUpfrontTTC - (myClientData.wallet_balance || 0)).toFixed(2)} €</p>
                                            {currentOfferType === 'rental' && <p className="text-xs text-slate-400 mt-1">Puis {finalMonthlyTTC.toFixed(2)} € TTC / mois</p>}
                                            {currentOfferType === 'purchase' && <p className="text-xs text-slate-400 mt-1">Puis { (pHosting * priceMultiplier * tvaMult).toFixed(2) } € TTC / an</p>}
                                        </div>
                                    </div>
                                </div>
                            </div>
                            
                            {(!purchasesAllowed && Math.max(0, finalUpfrontTTC - (myClientData.wallet_balance || 0)) > 0) && (
                                <div className="bg-orange-50 text-orange-800 p-4 rounded-xl text-sm font-bold border border-orange-200 mt-4 flex items-start gap-3">
                                    <AlertTriangle size={24} className="shrink-0" />
                                    <p>L'administration a temporairement suspendu la validation de nouvelles commandes payantes sur la plateforme. Veuillez réessayer ultérieurement.</p>
                                </div>
                            )}

                            {Math.max(0, finalUpfrontTTC - (myClientData.wallet_balance || 0)) > 0 && purchasesAllowed && (
                                <label className="flex items-start gap-3 p-4 bg-slate-50 border border-slate-200 rounded-xl cursor-pointer hover:bg-slate-100 transition mt-4">
                                    <input type="checkbox" checked={waiverAccepted} onChange={(e) => setWaiverAccepted(e.target.checked)} className="mt-0.5 w-5 h-5 accent-emerald-600 shrink-0 cursor-pointer" />
                                    <span className="text-xs font-bold text-slate-700 leading-relaxed cursor-pointer select-none">
                                        J'accepte que l'exécution du service et la fourniture du contenu numérique commencent immédiatement, et je renonce expressément à mon droit de rétractation de 14 jours. <span className="text-red-500 font-bold">(obligatoire)</span>
                                    </span>
                                </label>
                            )}

                            <div className="flex gap-3 pt-2 mt-4">
                                <button type="button" onClick={() => setModalStep('config_full')} disabled={isSaving} className="px-6 py-3 rounded-xl font-bold text-slate-500 hover:bg-slate-100 transition disabled:opacity-50">Retour</button>
                                <button onClick={handleActivationRequest} disabled={isSaving || (Math.max(0, finalUpfrontTTC - (myClientData.wallet_balance || 0)) > 0 && (!waiverAccepted || !purchasesAllowed))} className="flex-1 bg-emerald-600 text-white py-3 rounded-xl font-black uppercase tracking-widest hover:bg-emerald-700 transition shadow-lg flex items-center justify-center gap-2 disabled:opacity-50">
                                    {isSaving ? <Loader className="animate-spin w-5 h-5"/> : <CreditCard size={18}/>} Confirmer et payer
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
            )}

            {isModalOpen && modalStep === 'payment' && paymentData && (
                <window.Modal title="Activation de l'option" onClose={() => setIsModalOpen(false)} preventClose={isSaving}>
                    <StripePaymentForm clientSecret={paymentData.secret} amountCents={paymentData.amountCents} onSuccess={handlePaymentSuccess} onCancel={() => setIsModalOpen(false)} />
                </window.Modal>
            )}

            {/* MODALE DE CONFIGURATION TOTP 2FA */}
            {totpSetupData && (
                <window.Modal title="Configuration 2FA" onClose={() => { setTotpSetupData(null); setProfileData({...profileData, two_factor_method: 'none'}); }} zIndex="z-[250]">
                    <div className="flex flex-col items-center text-center space-y-4">
                        <p className="text-sm text-slate-600 font-medium">Scannez ce QR Code avec votre application d'authentification (Google Authenticator, Authy, etc.) :</p>
                        <div className="bg-white p-4 rounded-xl shadow-sm border border-slate-100">
                            <window.NativeQRCode value={totpSetupData.otpauth} size={180} />
                        </div>
                        <p className="text-xs text-slate-500">Ou saisissez cette clé manuellement :</p>
                        <code className="bg-slate-100 px-3 py-2 rounded text-slate-700 font-black tracking-widest select-all">{totpSetupData.secret}</code>
                        <div className="w-full pt-4 border-t border-slate-100 mt-2">
                            <button onClick={confirmTotp} disabled={isSaving} className="w-full bg-emerald-600 text-white py-3 rounded-xl font-black uppercase tracking-widest hover:bg-emerald-700 transition shadow-lg">
                                J'ai scanné le code, activer
                            </button>
                        </div>
                    </div>
                </window.Modal>
            )}

            {/* GESTIONNAIRE DE LIENS DÉLÉGUÉS */}
            {isModalOpen && modalStep === 'share' && (
                <window.Modal title="Saisie déléguée multicomptes" onClose={() => setIsModalOpen(false)}>
                    <div className="space-y-6">
                        <div className="bg-blue-50 p-4 rounded-xl border border-blue-100 text-blue-800 text-sm leading-relaxed">
                            Créez des liens sécurisés pour confier la saisie d'informations ou le dépôt de documents (PDF) à d'autres membres de l'équipe du chantier sans leur donner accès à votre compte ou à votre facturation.
                        </div>

                        {/* Formulaire de création */}
                        <div className="bg-white p-4 rounded-xl border border-slate-200 shadow-sm space-y-4">
                            <h4 className="font-bold text-slate-800 text-sm flex items-center gap-2"><Plus size={16}/> Créer un nouveau lien</h4>
                            <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                                <div className="space-y-1">
                                    <label className="text-xs font-bold text-slate-500 uppercase block">Nom du destinataire *</label>
                                    <input value={newLink.name} onChange={e=>setNewLink({...newLink, name: e.target.value})} placeholder="Ex: Architecte Dupont" className="w-full border border-slate-200 rounded-lg p-2 text-sm outline-none focus:border-blue-500" />
                                </div>
                                <div className="space-y-1">
                                    <label className="text-xs font-bold text-slate-500 uppercase block">Validité (jours)</label>
                                    <input type="number" min="1" max="90" value={newLink.expDays} onChange={e=>setNewLink({...newLink, expDays: parseInt(e.target.value)||7})} className="w-full border border-slate-200 rounded-lg p-2 text-sm outline-none focus:border-blue-500" />
                                </div>
                            </div>
                            <div className="space-y-2 pt-2">
                                <label className="text-xs font-bold text-slate-500 uppercase block">Verrouiller la saisie de ces champs (lecture seule) :</label>
                                <div className="flex flex-wrap gap-2">
                                    {[
                                        { id: 'name', label: 'Nom du chantier' }, { id: 'location', label: 'Lieu' },
                                        { id: 'maitreOuvrage', label: "Maître d'ouvrage" }, { id: 'permitNumber', label: 'N° de permis' },
                                        { id: 'description', label: 'Description' }, { id: 'promoterLink', label: 'Lien promoteur' },
                                        { id: 'emergencyPhone', label: 'N° d\'urgence' }, { id: 'noiseSchedule', label: 'Horaires' },
                                        { id: 'intervenants', label: 'Intervenants' }, { id: 'lots', label: 'Lots' }, { id: 'pdfId', label: 'Arrêté (PDF)' }
                                    ].map(f => (
                                        <button key={f.id} onClick={() => setNewLink(p => ({...p, lockedFields: p.lockedFields.includes(f.id) ? p.lockedFields.filter(x=>x!==f.id) : [...p.lockedFields, f.id]}))} className={`px-2 py-1 rounded-lg text-xs font-bold transition border ${newLink.lockedFields.includes(f.id) ? 'bg-red-50 text-red-600 border-red-200' : 'bg-slate-50 text-slate-500 border-slate-200 hover:bg-slate-100'}`}>
                                            {newLink.lockedFields.includes(f.id) && <Lock size={10} className="inline mr-1"/>}{f.label}
                                        </button>
                                    ))}
                                </div>
                            </div>
                            <button onClick={async () => {
                                if (!newLink.name.trim()) return showToast("Le nom du lien est obligatoire.", "error");
                                setIsSaving(true);
                                try {
                                    const linkId = crypto.randomUUID();
                                    const expTime = Math.floor(Date.now() / 1000) + (newLink.expDays * 86400);
                                    const linkObj = { id: linkId, name: newLink.name.trim(), exp: expTime, active: true, lockedFields: newLink.lockedFields };
                                    const updatedPanneau = { ...managingPanneau, delegate_links: [...(managingPanneau.delegate_links || []), linkObj] };
                                    await fetch(window.ECO_CONFIG.apiBaseUrl + 'panneaux', { method: 'POST', body: JSON.stringify({ id: updatedPanneau.id, status: updatedPanneau.status, offerType: updatedPanneau.offerType, physicalPanels: updatedPanneau.physicalPanels, details: updatedPanneau }) });
                                    setManagingPanneau(updatedPanneau);
                                    setNewLink({ name: '', expDays: 7, lockedFields: [] });
                                    refreshData();
                                    showToast("Nouveau lien de saisie créé.", "success");
                                } catch(e) { showToast("Erreur", "error"); }
                                setIsSaving(false);
                            }} disabled={isSaving || !newLink.name.trim()} className="w-full bg-blue-600 text-white py-2 rounded-lg font-bold text-sm hover:bg-blue-700 transition flex items-center justify-center gap-2">
                                <Plus size={16}/> Créer le lien
                            </button>
                        </div>

                        {/* Liste des liens existants */}
                        <div className="space-y-3">
                            <h4 className="font-bold text-slate-800 text-sm">Liens générés pour ce panneau</h4>
                            {(!managingPanneau.delegate_links || managingPanneau.delegate_links.length === 0) && (
                                <p className="text-slate-500 text-xs italic text-center py-4">Aucun lien n'a encore été créé pour ce panneau.</p>
                            )}
                            {managingPanneau.delegate_links?.map((link, idx) => {
                                const isExpired = link.exp < Date.now() / 1000;
                                return (
                                    <div key={idx} className={`p-4 rounded-xl border ${link.active && !isExpired ? 'bg-white border-slate-200 shadow-sm' : 'bg-slate-50 border-slate-200 opacity-75'}`}>
                                        <div className="flex justify-between items-start mb-2">
                                            <div>
                                                <p className="font-bold text-slate-800 text-sm">{link.name}</p>
                                                <p className="text-xs text-slate-500">Exp. : {new Date(link.exp * 1000).toLocaleDateString('fr-FR')} {isExpired && <span className="text-red-500 font-bold ml-1">(Expiré)</span>}</p>
                                            </div>
                                            <div className="flex items-center gap-2">
                                                <label className="flex items-center cursor-pointer mr-2" title="Activer / Désactiver ce lien">
                                                    <div className={`w-8 h-4 rounded-full transition-colors relative shrink-0 ${link.active ? 'bg-emerald-500' : 'bg-slate-300'}`}>
                                                        <div className={`absolute top-[2px] bg-white w-3 h-3 rounded-full transition-transform ${link.active ? 'translate-x-4' : 'translate-x-1'}`}></div>
                                                    </div>
                                                    <input type="checkbox" className="hidden" checked={link.active} onChange={async (e) => {
                                                        const newVal = e.target.checked;
                                                        setIsSaving(true);
                                                        try {
                                                            const links = [...managingPanneau.delegate_links];
                                                            links[idx] = { ...links[idx], active: newVal };
                                                            const updatedPanneau = { ...managingPanneau, delegate_links: links };
                                                            await fetch(window.ECO_CONFIG.apiBaseUrl + 'panneaux', { method: 'POST', body: JSON.stringify({ id: updatedPanneau.id, status: updatedPanneau.status, offerType: updatedPanneau.offerType, physicalPanels: updatedPanneau.physicalPanels, details: updatedPanneau }) });
                                                            setManagingPanneau(updatedPanneau); refreshData();
                                                        } catch(e) {}
                                                        setIsSaving(false);
                                                    }} />
                                                </label>
                                                <button onClick={async () => {
                                                    setIsSaving(true);
                                                    try {
                                                        const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'panneaux/delegate_link', { method: 'POST', body: JSON.stringify({ id: managingPanneau.id, link_id: link.id }) });
                                                        const d = await res.json();
                                                        if (d.status === 'success') { navigator.clipboard.writeText(d.data.link); showToast("Lien copié !"); }
                                                    } catch(e) { showToast("Erreur", "error"); }
                                                    setIsSaving(false);
                                                }} disabled={!link.active || isExpired || isSaving} className="bg-slate-100 text-slate-700 px-3 py-1.5 rounded-lg text-xs font-bold hover:bg-slate-200 transition shadow-sm disabled:opacity-50 flex items-center gap-1">
                                                    <Copy size={12}/> Copier URL
                                                </button>
                                                <button onClick={async () => {
                                                    if(!confirm("Supprimer ce lien ?")) return;
                                                    setIsSaving(true);
                                                    try {
                                                        const links = [...managingPanneau.delegate_links];
                                                        links.splice(idx, 1);
                                                        const updatedPanneau = { ...managingPanneau, delegate_links: links };
                                                        await fetch(window.ECO_CONFIG.apiBaseUrl + 'panneaux', { method: 'POST', body: JSON.stringify({ id: updatedPanneau.id, status: updatedPanneau.status, offerType: updatedPanneau.offerType, physicalPanels: updatedPanneau.physicalPanels, details: updatedPanneau }) });
                                                        setManagingPanneau(updatedPanneau); refreshData();
                                                    } catch(e) {}
                                                    setIsSaving(false);
                                                }} className="text-red-500 hover:bg-red-50 p-1.5 rounded-lg transition" title="Supprimer">
                                                    <Trash2 size={16}/>
                                                </button>
                                            </div>
                                        </div>
                                        {link.lockedFields && link.lockedFields.length > 0 && (
                                            <p className="text-[10px] text-slate-500 mt-2 border-t border-slate-100 pt-2 flex items-center gap-1">
                                                <Lock size={10} className="text-red-400"/> Bloqué : {link.lockedFields.join(', ')}
                                            </p>
                                        )}
                                    </div>
                                );
                            })}
                        </div>
                    </div>
                </window.Modal>
            )}

            {isModalOpen && modalStep === 'legal_vault' && (
                <window.Modal title="Coffre-fort légal privé" onClose={() => setIsModalOpen(false)} preventClose={isSaving}>
                    <div className="space-y-6">
                        <div className="bg-slate-50 p-4 rounded-xl border border-slate-200 flex gap-4 items-start">
                            <Lock size={24} className="text-slate-400 shrink-0"/>
                            <div>
                                <p className="text-sm font-bold text-slate-800">Preuves et constats d'huissier</p>
                                <p className="text-xs text-slate-500 mt-1">Ces documents sont chiffrés et inaccessibles au public. Ils seront inclus dans l'archive D.O.E lors de la clôture du panneau.</p>
                            </div>
                        </div>

                        {/* Zone de Drag et Drop pour le Coffre-Fort */}
                        <div 
                            onDragEnter={(e) => { e.preventDefault(); setVaultDragging(true); }}
                            onDragLeave={(e) => { e.preventDefault(); setVaultDragging(false); }}
                            onDragOver={(e) => e.preventDefault()}
                            onDrop={(e) => { 
                                e.preventDefault(); 
                                setVaultDragging(false); 
                                const handleVaultUpload = async (files) => {
                                    if (!files || files.length === 0) return;
                                    let currentTotalSize = managingPanneau.privateDocs?.reduce((acc, doc) => acc + (doc.size || 0), 0) || 0;
                                    setIsSaving(true);
                                    let newDocs = [...(managingPanneau.privateDocs || [])];
                                    for (let i = 0; i < files.length; i++) {
                                        const file = files[i];
                                        if (file.size > 100 * 1024 * 1024) { showToast(`Le fichier ${file.name} dépasse 100 Mo.`, "error"); continue; }
                                        if (currentTotalSize + file.size > 500 * 1024 * 1024) { showToast("La limite totale de 500 Mo du coffre-fort serait dépassée.", "error"); break; }
                                        try {
                                            const type = file.type.includes('pdf') ? 'pdf' : 'image';
                                            const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'upload/file', { method: 'POST', body: (() => { const fd = new FormData(); fd.append('file', file); fd.append('type', type); fd.append('is_private', 'true'); return fd; })() });
                                            const d = await res.json();
                                            if (d.status === 'success') {
                                                newDocs.push({ id: d.data.fileId, type, name: file.name, date: new Date().toLocaleDateString('fr-FR'), size: d.data.size || file.size });
                                                currentTotalSize += (d.data.size || file.size);
                                            } else showToast(d.message, "error");
                                        } catch(err) { showToast("Erreur upload", "error"); }
                                    }
                                    const updatedPanneau = {...managingPanneau, privateDocs: newDocs};
                                    setManagingPanneau(updatedPanneau);
                                    await fetch(window.ECO_CONFIG.apiBaseUrl + 'panneaux', { method: 'POST', body: JSON.stringify({ id: updatedPanneau.id, status: updatedPanneau.status, offerType: updatedPanneau.offerType, physicalPanels: updatedPanneau.physicalPanels, details: updatedPanneau }) });
                                    refreshData(); setIsSaving(false);
                                };
                                handleVaultUpload(e.dataTransfer.files); 
                            }}
                            className={`w-full min-h-[150px] border-2 border-dashed rounded-xl flex flex-col items-center justify-center p-6 transition relative ${vaultDragging ? 'border-emerald-500 bg-emerald-50/50' : 'border-slate-300 bg-slate-50 hover:bg-slate-100'}`}
                            title="Vous pouvez également coller vos fichiers (Ctrl+V) directement sur cette fenêtre."
                        >
                            {isSaving ? (
                                <div className="flex flex-col items-center text-slate-500"><Loader size={32} className="animate-spin mb-2"/> <span className="text-sm font-bold">Chiffrement en cours...</span></div>
                            ) : (
                                <>
                                    <div className="w-12 h-12 bg-white rounded-full flex items-center justify-center shadow-sm mb-3 text-slate-400"><ArrowUp size={24}/></div>
                                    <span className="text-sm font-bold text-slate-700">Glissez-déposez vos preuves ici (ou Ctrl+V)</span>
                                    <span className="text-xs text-slate-500 mt-1 text-center">Images ou PDF (Max 100 Mo/fichier, 500 Mo au total)</span>
                                    <label className="mt-4 px-4 py-2 bg-white border border-slate-200 text-slate-700 rounded-lg text-xs font-bold shadow-sm hover:bg-slate-50 cursor-pointer transition">
                                        Parcourir les fichiers
                                        <input type="file" multiple accept="application/pdf,image/*" className="hidden" onChange={(e) => {
                                            const files = e.target.files;
                                            if(!files) return;
                                            const handleVaultUpload = async (files) => {
                                                if (!files || files.length === 0) return;
                                                let currentTotalSize = managingPanneau.privateDocs?.reduce((acc, doc) => acc + (doc.size || 0), 0) || 0;
                                                setIsSaving(true);
                                                let newDocs = [...(managingPanneau.privateDocs || [])];
                                                for (let i = 0; i < files.length; i++) {
                                                    const file = files[i];
                                                    if (file.size > 100 * 1024 * 1024) { showToast(`Le fichier ${file.name} dépasse 100 Mo.`, "error"); continue; }
                                                    if (currentTotalSize + file.size > 500 * 1024 * 1024) { showToast("La limite totale de 500 Mo du coffre-fort serait dépassée.", "error"); break; }
                                                    try {
                                                        const type = file.type.includes('pdf') ? 'pdf' : 'image';
                                                        const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'upload/file', { method: 'POST', body: (() => { const fd = new FormData(); fd.append('file', file); fd.append('type', type); fd.append('is_private', 'true'); return fd; })() });
                                                        const d = await res.json();
                                                        if (d.status === 'success') {
                                                            newDocs.push({ id: d.data.fileId, type, name: file.name, date: new Date().toLocaleDateString('fr-FR'), size: d.data.size || file.size });
                                                            currentTotalSize += (d.data.size || file.size);
                                                        } else showToast(d.message, "error");
                                                    } catch(err) { showToast("Erreur upload", "error"); }
                                                }
                                                const updatedPanneau = {...managingPanneau, privateDocs: newDocs};
                                                setManagingPanneau(updatedPanneau);
                                                await fetch(window.ECO_CONFIG.apiBaseUrl + 'panneaux', { method: 'POST', body: JSON.stringify({ id: updatedPanneau.id, status: updatedPanneau.status, offerType: updatedPanneau.offerType, physicalPanels: updatedPanneau.physicalPanels, details: updatedPanneau }) });
                                                refreshData(); setIsSaving(false);
                                            };
                                            handleVaultUpload(files);
                                            e.target.value = null;
                                        }} />
                                    </label>
                                </>
                            )}
                        </div>

                        {/* Affichage Vignettes du Coffre-Fort */}
                        {managingPanneau.privateDocs && managingPanneau.privateDocs.length > 0 ? (
                            <div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-4 mt-6">
                                {managingPanneau.privateDocs.map((doc, idx) => (
                                    <div key={idx} className="relative group rounded-xl border border-slate-200 overflow-hidden bg-slate-50 shadow-sm flex flex-col cursor-pointer transition hover:border-emerald-300 hover:shadow-md" onClick={() => setViewingDoc(doc)}>
                                        <div className="h-24 w-full bg-white flex items-center justify-center p-2 shrink-0">
                                            {doc.type === 'image' ? (
                                                <img src={`?api=file/download_private&type=image&id=${doc.id}`} className="max-h-full max-w-full object-contain" alt="aperçu" />
                                            ) : (
                                                <div className="flex flex-col items-center text-slate-300"><FileCheck size={32} /><span className="text-[9px] font-bold mt-1 text-slate-400 uppercase tracking-widest">PDF</span></div>
                                            )}
                                        </div>
                                        <div className="p-2 border-t border-slate-100 flex-1 flex flex-col justify-between">
                                            <p className="text-[10px] font-bold text-slate-700 truncate" title={doc.name}>{doc.name}</p>
                                            <div className="flex justify-between items-center mt-2">
                                                <span className="text-[9px] font-bold text-slate-400">{doc.date}</span>
                                                <button onClick={(e) => { 
                                                    e.stopPropagation();
                                                    setConfirmDialog({
                                                        title: "Supprimer la preuve", message: "Voulez-vous vraiment supprimer ce document privé ?", isDestructive: true, confirmText: "Supprimer",
                                                        onConfirm: async () => {
                                                            const newDocs = [...managingPanneau.privateDocs]; newDocs.splice(idx, 1);
                                                            const updatedPanneau = {...managingPanneau, privateDocs: newDocs};
                                                            setManagingPanneau(updatedPanneau); setIsSaving(true);
                                                            await fetch(window.ECO_CONFIG.apiBaseUrl + 'panneaux', { method: 'POST', body: JSON.stringify({ id: updatedPanneau.id, status: updatedPanneau.status, offerType: updatedPanneau.offerType, physicalPanels: updatedPanneau.physicalPanels, details: updatedPanneau }) });
                                                            refreshData(); setIsSaving(false);
                                                        }
                                                    });
                                                }} className="text-red-400 hover:text-red-600 bg-red-50 hover:bg-red-100 p-1 rounded transition" title="Supprimer">
                                                    <Trash2 size={12}/>
                                                </button>
                                            </div>
                                        </div>
                                    </div>
                                ))}
                            </div>
                        ) : (
                            <p className="text-center text-sm text-slate-400 py-4 italic">Aucun document privé stocké.</p>
                        )}
                        
                        <div className="text-right">
                            <span className="text-xs font-bold text-slate-400">Total utilisé : {((managingPanneau.privateDocs?.reduce((acc, doc) => acc + (doc.size || 0), 0) || 0) / (1024*1024)).toFixed(2)} Mo / 500 Mo</span>
                        </div>
                    </div>
                </window.Modal>
            )}

            {/* Visualiseur Plein Écran Coffre-Fort (Remplacement Iframe -> PdfFullViewer) */}
            {viewingDoc && (
                <div className="fixed inset-0 z-[999999] bg-slate-900/95 backdrop-blur-sm flex flex-col animate-in fade-in duration-200" onClick={() => setViewingDoc(null)}>
                    <div className="flex justify-between items-center p-4 bg-slate-900/50 text-white shrink-0 border-b border-white/10" onClick={e => e.stopPropagation()}>
                        <button onClick={() => setViewingDoc(null)} className="flex items-center gap-2 px-4 py-2 hover:bg-white/10 rounded-xl transition text-sm font-bold">
                            <ArrowLeft size={18}/> Retour
                        </button>
                        <div className="flex items-center gap-3">
                            <span className="text-xs font-mono text-slate-400 hidden sm:inline">{viewingDoc.name}</span>
                            <a href={`?api=file/download_private&type=${viewingDoc.type}&id=${viewingDoc.id}`} download className="flex items-center gap-2 px-4 py-2 bg-emerald-600 hover:bg-emerald-700 rounded-xl transition text-sm font-bold shadow-lg">
                                <Download size={18}/> <span className="hidden sm:inline">Télécharger</span>
                            </a>
                        </div>
                    </div>
                    <div className="flex-1 flex flex-col items-center justify-center p-2 sm:p-4 min-h-0 relative w-full">
                        {viewingDoc.type === 'image' ? (
                            <img src={`?api=file/download_private&type=image&id=${viewingDoc.id}`} className="max-w-full max-h-full object-contain rounded-xl shadow-2xl shrink-0" alt="Aperçu" onClick={e => e.stopPropagation()} />
                        ) : (
                            <window.PdfFullViewer url={`?api=file/download_private&type=pdf&id=${viewingDoc.id}&inline=1`} />
                        )}
                    </div>
                </div>
            )}
            
            {/* Modale de Confirmation de Livraison */}
            {deliveryConfirmModal && (
                <window.Modal title="Confirmation de réception" onClose={() => setDeliveryConfirmModal(null)} preventClose={isSaving}>
                    <div className="space-y-4">
                        <div className="bg-emerald-50 text-emerald-800 p-5 rounded-2xl border border-emerald-200 text-sm leading-relaxed">
                            <p className="font-black mb-2 flex items-center gap-2"><Package size={18} className="shrink-0"/> Colis livré ?</p>
                            <p>En confirmant, vous indiquez avoir bien reçu l'intégralité de votre commande de panneaux physiques pour ce panneau.</p>
                        </div>
                        
                        <div className="flex flex-col sm:flex-row gap-3 mt-6">
                            <button 
                                onClick={() => setDeliveryConfirmModal(null)} 
                                disabled={isSaving} 
                                className="w-full sm:flex-1 bg-slate-100 text-slate-700 py-3 rounded-xl font-bold hover:bg-slate-200 transition disabled:opacity-50"
                            >
                                Annuler
                            </button>
                            <button 
                                onClick={handleConfirmDelivery} 
                                disabled={isSaving} 
                                className="w-full sm:flex-1 bg-emerald-600 text-white py-3 px-4 rounded-xl font-black uppercase tracking-wider hover:bg-emerald-700 transition shadow-lg flex justify-center items-center gap-2 disabled:opacity-50 text-xs sm:text-sm leading-tight"
                            >
                                {isSaving ? (
                                    <Loader size={18} className="animate-spin shrink-0" />
                                ) : (
                                    <CheckCircle size={18} className="shrink-0" />
                                )}
                                <span className="text-center">Oui, j'ai reçu mon colis</span>
                            </button>
                        </div>
                    </div>
                </window.Modal>
            )}

            {/* MODALE DOCUMENTS LÉGAUX (CGV / RGPD) */}
            {legalModal && (
                <window.Modal title={legalModal === 'cgv' ? 'Conditions générales de vente' : 'Politique de confidentialité'} onClose={() => setLegalModal(null)} zIndex="z-[250]">
                    <div 
                        dangerouslySetInnerHTML={{ 
                            __html: window.DOMPurify 
                                ? window.DOMPurify.sanitize(
                                    legalModal === 'cgv' ? (data?.settings?.cgv || "Aucune CGV définie.") : (data?.settings?.rgpd || "Aucune mention légale définie.")
                                )
                                : (legalModal === 'cgv' ? (data?.settings?.cgv || "Aucune CGV.") : (data?.settings?.rgpd || "Aucune mention.")).toString().replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#039;')
                        }} 
                        className="text-sm text-slate-600 leading-relaxed font-medium admin-html" 
                    />
                </window.Modal>
            )}

            {/* Modales de Confirmation et Prompt Universelles */}
            {confirmDialog && <window.ConfirmModal {...confirmDialog} zIndex="z-[250]" onCancel={() => setConfirmDialog(null)} />}
            {promptDialog && <window.PromptModal {...promptDialog} zIndex="z-[250]" onCancel={() => setPromptDialog(null)} />}

            {previewPanneau && <window.PreviewModal panneau={previewPanneau} interactions={interactions} onClose={() => setPreviewPanneau(null)} showToast={showToast} refreshData={refreshData} />}

            {/* MODALE GLOBALE DE GENERATION D'ARCHIVES */}
            {archiveConfig && (
                <window.ArchiveGeneratorModal
                    type={archiveConfig.type}
                    panelId={archiveConfig.panelId}
                    onClose={() => setArchiveConfig(null)}
                    showToast={showToast}
                    refreshData={refreshData}
                />
            )}
        </window.DashboardLayout>
    );
};

/* EOF ===== [_clients.jsx] =============== */