/**
 * =========================================================================
 * PLATEFORME ECO-PANNEAU.FR - VERSION 1.0.0
 * Interface Administrateur (Super Admin)
 * Gestion globale, Logistique, Tarification et Maintenance Système
 * =========================================================================
 */

const { useState, useEffect, useRef } = React;
const { 
    Home, Users, Building, Settings, Activity, ShieldAlert, KeyRound, 
    Database, Save, LogOut, Package, Eye, MessageSquare, 
    AlertTriangle, CheckCircle, Trash2, Download, Terminal, Loader, 
    Zap, HardDrive, Shield, AlertOctagon, Archive, Power, Edit, FileText, MapPin, ExternalLink, Plus, Mail, ArrowLeft, Search, CreditCard, RefreshCw
} = window;

const decodeHTML = (html) => {
    const txt = document.createElement("textarea");
    txt.innerHTML = html;
    return txt.value;
};

window.AdminView = ({ data, refreshData, showToast }) => {
    const [activeTab, setActiveTab] = useState('dashboard');
    const [isSaving, setIsSaving] = useState(false);
    const [mobileChatView, setMobileChatView] = useState(false);

    const [settingsData, setSettingsData] = useState({ 
        ...data.settings, 
        ...data.prices,
        hostingYr: data.prices?.hostingYr ?? 1,
        billing_legalText: data.settings?.billing_legalText ?? '',
        site_banner_active: data.settings?.site_banner_active ?? '0',
        site_banner_msg: data.settings?.site_banner_msg ?? '',
        panel_banner_active: data.settings?.panel_banner_active ?? '0',
        panel_banner_msg: data.settings?.panel_banner_msg ?? '',
        allow_new_purchases: data.settings?.allow_new_purchases ?? '1',
        simp_opt_description: data.settings?.simp_opt_description ?? '1',
        simp_opt_image: data.settings?.simp_opt_image ?? '1',
        simp_opt_theme: data.settings?.simp_opt_theme ?? '1',
        simp_opt_link: data.settings?.simp_opt_link ?? '1',
        simp_opt_emergency: data.settings?.simp_opt_emergency ?? '1',
        simp_opt_schedule: data.settings?.simp_opt_schedule ?? '1',
        blacklist: data.settings?.blacklist ?? 'putain, connard, salope',
        greylist: data.settings?.greylist ?? 'merde, chier',
        sec_ip_limit: data.settings?.sec_ip_limit ?? 5,
        sec_global_limit: data.settings?.sec_global_limit ?? 1000,
        sec_lock_min: data.settings?.sec_lock_min ?? 10,
        sec_lock_max: data.settings?.sec_lock_max ?? 60
    });
    const [hasTva, setHasTva] = useState(true);
    const [showTvaWarning, setShowTvaWarning] = useState(false);

    const [diagnostics, setDiagnostics] = useState(null);
    const [logs, setLogs] = useState('');
    const [backups, setBackups] = useState([]);
    const [isLoadingBackups, setIsLoadingBackups] = useState(false);
    const [showAllBackups, setShowAllBackups] = useState(false);
    
    const [sysSummary, setSysSummary] = useState({ 
        loaded: false, diagStatus: 'emerald', backupStatus: 'emerald', logStatus: 'emerald', 
        php: '', ram: '', db: '', disk: '', backupsCount: 0, logDesc: '', backupDesc: '' 
    });
    
    const [modalView, setModalView] = useState(null);
    const [pwdRequest, setPwdRequest] = useState(null); 
    const [promptDialog, setPromptDialog] = useState(null);
    const [confirmDialog, setConfirmDialog] = useState(null);
    const [accessRequestModal, setAccessRequestModal] = useState(null);

    // NOUVELLES MODALES DE FACTURATION
    const [creditModal, setCreditModal] = useState(null);
    const [refundModal, setRefundModal] = useState(null);

    const [archiveConfig, setArchiveConfig] = useState(null);

    const [managingPanneau, setManagingPanneau] = useState(null);
    const [isModalOpen, setIsModalOpen] = useState(false);
    const [editingEntity, setEditingEntity] = useState(null);
    const [draggedItem, setDraggedItem] = useState(null);
    const [previewPanneau, setPreviewPanneau] = useState(null);
    const [moderationData, setModerationData] = useState(null);
    
    const [shippingModal, setShippingModal] = useState(null);
    const [trackingData, setTrackingData] = useState({ number: '', link: '' });

    const settingsLoadedRef = useRef(false);

    useEffect(() => { 
        if (data.settings && !settingsLoadedRef.current) {
            setSettingsData({ 
                ...data.settings, 
                ...data.prices,
                hostingYr: data.prices?.hostingYr ?? 1,
                billing_legalText: data.settings?.billing_legalText ?? '',
                site_banner_active: data.settings?.site_banner_active ?? '0',
                site_banner_msg: data.settings?.site_banner_msg ?? '',
                panel_banner_active: data.settings?.panel_banner_active ?? '0',
                panel_banner_msg: data.settings?.panel_banner_msg ?? '',
                allow_new_purchases: data.settings?.allow_new_purchases ?? '1',
                simp_opt_description: data.settings?.simp_opt_description ?? '1',
                simp_opt_image: data.settings?.simp_opt_image ?? '1',
                simp_opt_theme: data.settings?.simp_opt_theme ?? '1',
                simp_opt_link: data.settings?.simp_opt_link ?? '1',
                simp_opt_emergency: data.settings?.simp_opt_emergency ?? '1',
                simp_opt_schedule: data.settings?.simp_opt_schedule ?? '1',
                blacklist: data.settings?.blacklist ?? 'putain, connard, salope',
                greylist: data.settings?.greylist ?? 'merde, chier',
                sec_ip_limit: data.settings?.sec_ip_limit ?? 5,
                sec_global_limit: data.settings?.sec_global_limit ?? 1000,
                sec_lock_min: data.settings?.sec_lock_min ?? 10,
                sec_lock_max: data.settings?.sec_lock_max ?? 60
            }); 
            setHasTva(data.settings?.billing_has_tva !== '0');
            settingsLoadedRef.current = true;
        }
    }, [data]);

    const fetchTelemetry = async (silent = false) => {
        try {
            const cacheBuster = '&_t=' + Date.now();
            const fetchOpts = silent ? { cache: 'no-store', headers: { 'x-silent': '1' } } : { cache: 'no-store' };
            const [diagRes, backRes, logRes] = await Promise.all([
                fetch(window.ECO_CONFIG.apiBaseUrl + 'system/diagnostics' + cacheBuster + (silent ? '&silent=1' : ''), fetchOpts).then(r => r.json()),
                fetch(window.ECO_CONFIG.apiBaseUrl + 'system/backups' + cacheBuster + (silent ? '&silent=1' : ''), fetchOpts).then(r => r.json()),
                fetch(window.ECO_CONFIG.apiBaseUrl + 'system/logs' + cacheBuster + (silent ? '&silent=1' : ''), fetchOpts).then(r => r.json())
            ]);
            
            if (diagRes.status === 'success') {
                const dbDetail = diagRes.data.find(d => d.id === 'db')?.detail || '0 ms';
                const diskDetail = diagRes.data.find(d => d.id === 'disk')?.detail || '0 GB';
                const dbVal = parseFloat(dbDetail);
                const diskVal = parseFloat(diskDetail);
                
                let diagStatus = 'emerald';
                if (dbVal > 500 || diskVal < 1) diagStatus = 'red';
                else if (dbVal > 200 || diskVal < 5) diagStatus = 'amber';
                
                const backupsData = backRes.data || [];
                const backupsCount = backupsData.length;
                let backupStatus = 'emerald';
                let backupDesc = `${backupsCount} archive(s)`;

                if (backupsCount === 0) {
                    backupStatus = 'red';
                    backupDesc = "Alerte : Aucune sauvegarde";
                } else {
                    const latestBackup = backupsData.reduce((max, b) => b.date > max.date ? b : max, backupsData[0]);
                    const hoursSinceLast = (Date.now() - latestBackup.date) / (1000 * 60 * 60);

                    if (hoursSinceLast > 48) { backupStatus = 'red'; backupDesc = `Critique : Retard de ${Math.floor(hoursSinceLast/24)} jours`; } 
                    else if (hoursSinceLast > 24) { backupStatus = 'amber'; backupDesc = `Attention : Retard de ${Math.floor(hoursSinceLast)}h`; } 
                    else { backupStatus = 'emerald'; backupDesc = `À jour (${backupsCount} archives)`; }
                }
                
                const logsContent = logRes.data?.logs || '';
                let logStatus = 'emerald';
                let logDesc = 'Journal vierge (Sain)';
                const lowerLogs = logsContent.toLowerCase();
                
                if (lowerLogs.includes('fatal error') || lowerLogs.includes('exception')) { logStatus = 'red'; logDesc = 'Erreurs critiques détectées !'; } 
                else if (logsContent.length > 5) { logStatus = 'amber'; logDesc = 'Avertissements enregistrés'; }
                
                setSysSummary({
                    loaded: true, diagStatus, backupStatus, logStatus,
                    php: diagRes.data.find(d => d.id === 'php')?.detail || 'OK',
                    ram: diagRes.data.find(d => d.id === 'ram')?.detail || 'OK',
                    db: dbDetail, disk: diskDetail, backupsCount, logDesc, backupDesc
                });
            }
        } catch(e) {}
    };

    useEffect(() => { 
        fetchTelemetry(); 
        
        let telemetryInterval;
        let currentDelay = 10000; 
        let lastActivityTime = Date.now();
        let isTabVisible = !document.hidden;

        const performTelemetrySync = async () => {
            if (!isTabVisible) return;
            await fetchTelemetry(true); 

            const idleTime = Date.now() - lastActivityTime;
            if (idleTime > 120000) currentDelay = 60000;      
            else if (idleTime > 30000) currentDelay = 30000;  
            else currentDelay = 10000;                        

            scheduleNextPoll(currentDelay);
        };

        const scheduleNextPoll = (delay) => {
            clearTimeout(telemetryInterval);
            if (isTabVisible) telemetryInterval = setTimeout(performTelemetrySync, delay);
        };

        const handleVisibilityChange = () => {
            isTabVisible = !document.hidden;
            if (isTabVisible) {
                lastActivityTime = Date.now();
                currentDelay = 10000;
                performTelemetrySync();
            } else {
                clearTimeout(telemetryInterval);
            }
        };

        const handleUserInteraction = () => {
            if (currentDelay > 10000) {
                lastActivityTime = Date.now();
                currentDelay = 10000;
                scheduleNextPoll(10000);
            } else {
                lastActivityTime = Date.now();
            }
        };

        document.addEventListener('visibilitychange', handleVisibilityChange);
        document.addEventListener('click', handleUserInteraction);
        document.addEventListener('keydown', handleUserInteraction);

        scheduleNextPoll(currentDelay);

        return () => {
            clearTimeout(telemetryInterval);
            document.removeEventListener('visibilitychange', handleVisibilityChange);
            document.removeEventListener('click', handleUserInteraction);
            document.removeEventListener('keydown', handleUserInteraction);
        };
    }, []);

    const clients = data.clients || [];
    const panneaux = data.panneaux || [];
    const activePanneaux = panneaux.filter(p => p.status === 'Actif' && p.id !== 'demo-panneau');
    const mrr = activePanneaux.filter(p => p.offerType === 'rental').reduce((sum, p) => sum + (p.currentRate || 0), 0);
    const interactions = data.interactions || [];
    const totalUnread = interactions.filter(m => m.target === 'Admin' && !m.resolved).length;

    const navItems = [
        { id: 'dashboard', icon: <Home size={18}/>, label: 'Vue globale' },
        { id: 'clients', icon: <Users size={18}/>, label: 'Base clients' },
        { id: 'messages', icon: <MessageSquare size={18}/>, label: 'Messagerie et support', badge: totalUnread },
        { id: 'panneaux', icon: <Building size={18}/>, label: 'Tous les panneaux', badge: activePanneaux.length },
        { id: 'logistique', icon: <Package size={18}/>, label: 'Logistique', badge: panneaux.filter(p => p.physicalPanels > 0 && p.shipping_status !== 'Livré').length },
        { id: 'invoices', icon: <FileText size={18}/>, label: 'Facturation globale' },
        { id: 'settings', icon: <Settings size={18}/>, label: 'Système et tarifs' },
    ];

    const sendAccessRequest = async (uid, mode) => {
        setIsSaving(true);
        try {
            const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'clients/request_access', { 
                method: 'POST', 
                body: JSON.stringify({ uid, mode }) 
            });
            if ((await res.json()).status === 'success') {
                showToast("Demande d'accès envoyée avec succès.", "success");
                setAccessRequestModal(null);
                refreshData();
            } else {
                showToast("Erreur lors de la demande", "error");
            }
        } catch (e) {
            showToast("Erreur réseau", "error");
        } finally { setIsSaving(false); }
    };

    const revokeAccess = async (uid) => {
        setConfirmDialog({
            title: "Révocation d'accès",
            message: "Êtes-vous sûr de vouloir révoquer l'autorisation d'accès technique pour ce client ?",
            confirmText: "Oui, révoquer",
            isDestructive: true,
            onConfirm: async () => {
                setIsSaving(true);
                try {
                    const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'clients/revoke_access', { 
                        method: 'POST', 
                        body: JSON.stringify({ uid }) 
                    });
                    if ((await res.json()).status === 'success') {
                        showToast("Accès révoqué.", "success");
                        refreshData();
                    } else showToast("Erreur lors de la révocation", "error");
                } finally { setIsSaving(false); }
            }
        });
    };

    const impersonateClient = async (uid) => {
        setIsSaving(true);
        try {
            const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'auth/impersonate', { method: 'POST', body: JSON.stringify({ uid }) });
            if ((await res.json()).status === 'success') window.location.href = '?'; 
            else showToast("Erreur d'accès", "error");
        } finally { setIsSaving(false); }
    };

    const deleteClient = (uid, clientName) => {
        setPwdRequest({
            title: `Suppression du compte : ${clientName}`,
            desc: (<span>ATTENTION : Saisissez le mot de passe administrateur pour détruire définitivement le compte de <strong className="text-red-600 font-black text-base">{clientName}</strong> et toutes ses données associées. Cette action est irréversible.</span>),
            onConfirm: async (pwd) => {
                setIsSaving(true);
                try {
                    const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'clients/admin_delete', { method: 'POST', body: JSON.stringify({ uid, pwd }) });
                    if ((await res.json()).status === 'success') { showToast("Client supprimé avec succès."); refreshData(); } 
                    else showToast("Erreur de suppression (Mot de passe incorrect ?)", 'error');
                } finally { setIsSaving(false); }
            }
        });
    };

    const togglePanneauStatus = (id, currentStatus) => {
        const newStatus = currentStatus === 'Actif' ? 'Hors ligne' : 'Actif';
        setConfirmDialog({
            title: "Changement de statut",
            message: `Passer ce panneau en statut : ${newStatus} ?`,
            confirmText: "Confirmer",
            isDestructive: newStatus === 'Hors ligne' || newStatus === 'Désactivé',
            onConfirm: async () => {
                setIsSaving(true);
                try {
                    await fetch(window.ECO_CONFIG.apiBaseUrl + 'panneaux/status', { method: 'POST', body: JSON.stringify({ id, status: newStatus }) });
                    refreshData();
                } finally { setIsSaving(false); }
            }
        });
    };

    const updateShipping = async (id, status, tracking_number, tracking_link = '') => {
        setIsSaving(true);
        try {
            await fetch(window.ECO_CONFIG.apiBaseUrl + 'panneaux/shipping', { 
                method: 'POST', 
                body: JSON.stringify({ id, shipping_status: status, tracking_number, tracking_link }) 
            });
            showToast(`Statut logistique mis à jour : ${status}`);
            setShippingModal(null);
            refreshData();
        } finally { setIsSaving(false); }
    };

    const handleAddCredit = async (e) => {
        e.preventDefault();
        const amount = parseFloat(e.target.amount.value);
        const reason = e.target.reason.value;
        if (amount <= 0) return showToast("Montant invalide", "error");
        
        setIsSaving(true);
        try {
            const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'invoices/credit', {
                method: 'POST',
                body: JSON.stringify({ client_uid: creditModal.client_uid, amount, reason })
            });
            const d = await res.json();
            if (d.status === 'success') {
                showToast("Crédit ajouté avec succès !", "success");
                setCreditModal(null);
                refreshData();
            } else {
                showToast(d.message, 'error');
            }
        } catch (err) {
            showToast("Erreur réseau", "error");
        }
        setIsSaving(false);
    };

    const handleRefund = async (e) => {
        e.preventDefault();
        const amount = parseFloat(e.target.amount.value);
        const reason = e.target.reason.value;
        const mode = e.target.mode.value;
        if (amount <= 0 || amount > refundModal.invoice.amount) return showToast("Montant invalide", "error");
        
        setIsSaving(true);
        try {
            const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'invoices/refund', {
                method: 'POST',
                body: JSON.stringify({ invoice_ref: refundModal.invoice.invoiceNumber, amount, mode, reason })
            });
            const d = await res.json();
            if (d.status === 'success') {
                showToast("Remboursement ou avoir traité avec succès !", "success");
                setRefundModal(null);
                refreshData();
            } else {
                showToast(d.message, 'error');
            }
        } catch (err) {
            showToast("Erreur réseau", "error");
        }
        setIsSaving(false);
    };

    const handleA1Upload = async (c, e) => {
        const file = e.target.files[0];
        if(!file) return;
        setIsSaving(true);
        try {
            const id = await window.uploadFile(file, 'pdf');
            const payload = { id: c.id, status: c.status, offerType: c.offerType, currentRate: c.currentRate, physicalPanels: c.physicalPanels, details: { ...c, a1PdfId: id } };
            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("Fichier A1 attaché avec succès !", "success"); refreshData(); } 
            else showToast(d.message, 'error');
        } catch(err) { showToast("Erreur d'upload", "error"); }
        setIsSaving(false);
        e.target.value = null;
    };

    const handleA1Delete = (c) => {
        setConfirmDialog({
            title: "Retirer la maquette",
            message: "Retirer ce fichier A1 de la commande ?",
            confirmText: "Retirer",
            isDestructive: true,
            onConfirm: async () => {
                setIsSaving(true);
                try {
                    const payload = { id: c.id, status: c.status, offerType: c.offerType, currentRate: c.currentRate, physicalPanels: c.physicalPanels, details: { ...c, a1PdfId: '' } };
                    const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'panneaux', { method: 'POST', body: JSON.stringify(payload) });
                    if((await res.json()).status === 'success') { showToast("Fichier A1 retiré.", "success"); refreshData(); }
                } catch(err) {}
                setIsSaving(false);
            }
        });
    };

    const handleAutoFill = () => {
        setPromptDialog({
            title: "Saisie automatique",
            message: "Saisissez le SIRET (14 chiffres) ou SIREN (9 chiffres) de l'entreprise qui gère la plateforme (Vous) :",
            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 : Aucune entreprise correspondante.", "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}`;

                        setSettingsData({ ...settingsData, billing_company: company.nom_complet, billing_address: address, billing_siret: foundSiret, billing_tva: calculatedTva });
                        setHasTva(true);
                        showToast("Informations récupérées avec succès !", "success");
                    } else showToast("Aucune entreprise trouvée.", "error");
                } catch (err) { showToast("Le service gouvernemental est momentanément indisponible.", "error"); }
                setIsSaving(false);
            }
        });
    };

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

    const confirmTvaExemption = () => {
        setHasTva(false);
        setSettingsData({ ...settingsData, billing_tva: '' });
        setShowTvaWarning(false);
    };

    const handleSaveSettings = () => {
        setPwdRequest({
            title: "Modification globale",
            desc: "Saisissez le mot de passe administrateur pour confirmer la modification des paramètres de la plateforme.",
            onConfirm: async (pwd) => {
                setIsSaving(true);
                try {
                    const payload = { 
                        ...settingsData, pwd, 
                        billing_has_tva: hasTva ? '1' : '0', 
                        price_rentalMo: settingsData.rentalMo, price_purchase: settingsData.purchase, 
                        price_boardFirst: settingsData.boardFirst, price_boardAdd: settingsData.boardAdd, 
                        price_noAds: settingsData.noAds,
                        price_hostingYr: settingsData.hostingYr,
                        billing_legalText: settingsData.billing_legalText,
                        sec_ip_limit: settingsData.sec_ip_limit,
                        sec_global_limit: settingsData.sec_global_limit,
                        sec_lock_min: settingsData.sec_lock_min,
                        sec_lock_max: settingsData.sec_lock_max
                    };
                    const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'settings/update', { method: 'POST', body: JSON.stringify(payload) });
                    if ((await res.json()).status === 'success') { showToast("Paramètres globaux mis à jour."); refreshData(); } 
                    else showToast("Mot de passe invalide", 'error');
                } finally { setIsSaving(false); }
            }
        });
    };

    const handleSavePanneau = async () => {
        setIsSaving(true);
        try {
            const payload = { id: 'demo-panneau', status: 'Actif', offerType: 'demo', currentRate: 0, physicalPanels: 0, details: managingPanneau };
            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("Panneau de démonstration mis à jour !"); setIsModalOpen(false); refreshData(); }
            else showToast(d.message, 'error');
        } catch(e) { showToast("Erreur de sauvegarde", "error"); }
        setIsSaving(false);
    };

    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 fetchDiagnostics = async () => { setModalView('diagnostics'); setDiagnostics(null); const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'system/diagnostics&_t=' + Date.now(), { cache: 'no-store' }); const d = await res.json(); if(d.status === 'success') setDiagnostics(d.data); };
    const fetchLogs = async () => { setModalView('logs'); setLogs('Chargement...'); const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'system/logs&_t=' + Date.now(), { cache: 'no-store' }); const d = await res.json(); setLogs(d.data?.logs || 'Aucun log trouvé.'); };
    const clearLogs = async () => { await fetch(window.ECO_CONFIG.apiBaseUrl + 'system/logs/clear', { method: 'POST' }); fetchLogs(); fetchTelemetry(); };
    const loadBackups = async () => { setModalView('backups'); setShowAllBackups(false); setIsLoadingBackups(true); try { const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'system/backups&_t=' + Date.now(), { cache: 'no-store' }); const d = await res.json(); if(d.status === 'success') setBackups(d.data); } catch(e) { showToast("Erreur lors du chargement des sauvegardes", "error"); } finally { setIsLoadingBackups(false); } };
    
    const createBackup = () => {
        setPromptDialog({
            title: "Nouvelle sauvegarde",
            message: "Saisissez un marqueur ou label personnalisé pour identifier cette sauvegarde manuelle :",
            placeholder: "Ex : Avant la mise à jour...",
            confirmText: "Sauvegarder",
            onConfirm: async (label) => {
                setIsSaving(true);
                try {
                    const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'system/backups/create', { method: 'POST', body: JSON.stringify({ label }) });
                    if ((await res.json()).status === 'success') { showToast("Sauvegarde créée avec succès.", "success"); loadBackups(); fetchTelemetry(); } 
                    else showToast("Erreur de sauvegarde", "error");
                } catch(e) { showToast("Erreur réseau", "error"); } finally { setIsSaving(false); }
            }
        });
    };

    const restoreBackup = (filename) => { setPwdRequest({ title: "Restauration système", desc: "ATTENTION CRITIQUE : La restauration écrasera la base de données actuelle. Saisissez le mot de passe administrateur :", onConfirm: async (pwd) => { setIsSaving(true); try { const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'system/backups/restore', { method: 'POST', body: JSON.stringify({ filename, pwd }) }); if ((await res.json()).status === 'success') { alert("Restauration réussie. L'application va recharger."); window.location.reload(); } else showToast("Mot de passe incorrect ou erreur.", "error"); } finally { setIsSaving(false); } } }); };
    const deleteBackup = (filename) => { setPwdRequest({ title: "Suppression d'archive", desc: "Saisissez le mot de passe administrateur pour supprimer définitivement cette sauvegarde :", onConfirm: async (pwd) => { const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'system/backups/delete', { method: 'POST', body: JSON.stringify({ filename, pwd }) }); if ((await res.json()).status === 'success') { loadBackups(); fetchTelemetry(); } else { showToast("Mot de passe incorrect", "error"); } } }); };
    
    const getColorClass = (status) => { 
        if (!sysSummary.loaded) return 'text-slate-500 border-slate-200 bg-slate-50'; 
        if (status === 'red') return 'text-red-700 border-red-200 bg-red-50 hover:border-red-400'; 
        if (status === 'amber') return 'text-amber-700 border-amber-200 bg-amber-50 hover:border-amber-400'; 
        return 'text-emerald-700 border-emerald-200 bg-emerald-50 hover:border-emerald-400'; 
    };

    const checkPanelViolations = (p) => {
        const blacklist = (data.settings?.blacklist || '').split(',').map(s=>s.trim().toLowerCase()).filter(Boolean);
        const greylist = (data.settings?.greylist || '').split(',').map(s=>s.trim().toLowerCase()).filter(Boolean);
        let blackCount = 0; let greyCount = 0;
        const textToSearch = [p.name, p.location, p.description, p.maitreOuvrage].filter(Boolean).join(' ').toLowerCase();
        const detected = { black: [], grey: [] };
        
        blacklist.forEach(word => { if(textToSearch.includes(word)) { blackCount++; detected.black.push(word); } });
        greylist.forEach(word => { if(textToSearch.includes(word)) { greyCount++; detected.grey.push(word); } });
        
        return { isViolation: blackCount > 0 || greyCount > 2, detected };
    };

    const handlePreviewAndMarkSeen = async (p) => {
        setPreviewPanneau(p);
        if (!p.admin_seen) {
            try {
                const payload = {
                    id: p.id, status: p.status, offerType: p.offerType, currentRate: p.currentRate, physicalPanels: p.physicalPanels,
                    details: { ...p, admin_seen: true }
                };
                await fetch(window.ECO_CONFIG.apiBaseUrl + 'panneaux', { method: 'POST', body: JSON.stringify(payload) });
                refreshData();
            } catch(e) {}
        }
    };

    const renderDashboard = () => {
        const recentMessages = [...interactions].filter(m => m.target === 'Admin').reverse().slice(0, 5);
        return (
            <div className="space-y-8 animate-in fade-in slide-in-from-bottom-4">
                <div><h1 className="text-3xl font-black text-slate-800">Supervision</h1><p className="text-slate-500 font-medium">Vue d'ensemble de la plateforme SaaS.</p></div>
                <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
                    <window.StatCard title="MRR (revenus loc.)" value={`${mrr} €`} icon={<Activity size={24}/>} color="text-emerald-600" bg="bg-emerald-100" />
                    <window.StatCard title="Clients inscrits" value={clients.length} icon={<Users size={24}/>} color="text-blue-600" bg="bg-blue-100" onClick={() => setActiveTab('clients')} />
                    <window.StatCard title="Panneaux actifs" value={activePanneaux.length} icon={<Building size={24}/>} color="text-indigo-600" bg="bg-indigo-100" onClick={() => setActiveTab('panneaux')} />
                    <window.StatCard title="Total scans QR" value={data.stats?.totalViews || 0} icon={<Eye size={24}/>} color="text-amber-600" bg="bg-amber-100" />
                </div>
                <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
                    <div className="bg-white rounded-3xl p-6 shadow-sm border border-slate-100">
                        <div className="flex justify-between items-center mb-6"><h3 className="font-black text-slate-800 flex items-center gap-2"><MessageSquare size={18} className="text-emerald-600"/> Derniers messages</h3><button onClick={() => setActiveTab('messages')} className="text-xs font-bold text-emerald-600 hover:underline">Voir tout</button></div>
                        <div className="space-y-4">
                            {recentMessages.map((m, i) => {
                                let displayAuthor = m.author;
                                
                                if (m.panneauId === 'CONTACT_PUBLIC') {
                                    if (m.author === 'Admin') displayAuthor = 'Service client';
                                    else if (m.author === 'Système' || m.author === 'Systeme') displayAuthor = 'Système';
                                    else displayAuthor = `Visiteur ${m.author}`;
                                } else {
                                    if (m.author === 'Admin') displayAuthor = 'Support';
                                    else if (m.author === 'Client') {
                                        if (m.panneauId.startsWith('SUPPORT_')) {
                                            const cUid = m.panneauId.split('_')[1];
                                            const c = clients.find(cl => cl.id === cUid);
                                            if (c && c.name) displayAuthor = c.name;
                                        } else displayAuthor = 'Client';
                                    } else if (m.author === 'Système' || m.author === 'Systeme') displayAuthor = 'Système';
                                }

                                return (
                                    <div key={i} className="flex flex-col p-4 rounded-xl border border-slate-100 bg-slate-50 cursor-pointer hover:border-emerald-200 transition" onClick={() => {
                                        let tId = m.panneauId;
                                        if (m.panneauId === 'CONTACT_PUBLIC') {
                                             tId = `CONTACT_PUBLIC_${m.author}`;
                                        } else if (m.panneauId.startsWith('SUPPORT_')) {
                                             tId = m.panneauId;
                                        } else if (m.author !== 'Client' && m.author !== 'Admin') {
                                             tId = `${m.panneauId}_${m.author}`;
                                        } else if (m.target !== 'Client' && m.target !== 'Admin' && m.target) {
                                             tId = `${m.panneauId}_${m.target}`;
                                        }
                                        const u = new URL(window.location);
                                        if (tId) u.searchParams.set('chat_id', tId);
                                        window.history.replaceState({}, '', u);
                                        setMobileChatView(true);
                                        setActiveTab('messages');
                                    }}>
                                        {/* CORRECTION BUG SAFARI */}
                                        <div className="flex justify-between items-start mb-2"><div className="flex items-center gap-2"><span className={`w-2 h-2 rounded-full ${m.isAlert ? 'bg-red-500' : (m.resolved ? 'bg-slate-300' : 'bg-emerald-500')}`}></span><p className="font-bold text-xs text-slate-700">{displayAuthor}</p></div><span className="text-[10px] font-bold text-slate-400">{new Date(String(m.created_at || '').replace(' ', 'T')).toLocaleDateString('fr-FR')}</span></div>
                                        <p className="text-sm text-slate-600 line-clamp-2">{m.detail.replace(/\[ATTACHMENT:[^\]]+\]/g, '[Pièce jointe]').replace(/<[^>]*>?/gm, '')}</p>
                                        <p className="text-[10px] text-slate-400 mt-2 pt-2 border-t border-slate-200 font-bold">{m.panneauId === 'CONTACT_PUBLIC' ? 'ORIGINE : Nous contacter' : 'ORIGINE : Espace client (Support)'}</p>
                                    </div>
                                );
                            })}
                            {recentMessages.length === 0 && <p className="text-sm text-slate-400 italic text-center py-4">Aucune interaction récente.</p>}
                        </div>
                    </div>
                    <div className="bg-white rounded-3xl p-6 shadow-sm border border-slate-100 flex flex-col">
                        <h3 className="font-black text-slate-800 mb-6 flex items-center gap-2"><Terminal size={18} className="text-emerald-600"/> Serveur et maintenance</h3>
                        <div className="space-y-3 flex-1 flex flex-col justify-start">
                            <button onClick={loadBackups} title="Gérer les sauvegardes du site" className={`w-full flex items-center justify-between p-4 rounded-xl border transition group text-left ${getColorClass(sysSummary.backupStatus)}`}>
                                <div className="flex items-center gap-4"><Archive size={24} className="group-hover:scale-110 transition-transform"/><div><p className="font-bold text-sm">Sauvegardes système</p><p className={`text-xs mt-1 ${sysSummary.loaded ? 'opacity-80' : 'opacity-50 animate-pulse'}`}>{sysSummary.loaded ? sysSummary.backupDesc : 'Vérification...'}</p></div></div>
                            </button>
                            <button onClick={fetchDiagnostics} title="Voir l'état des services" className={`w-full flex items-center justify-between p-4 rounded-xl border transition group text-left ${getColorClass(sysSummary.diagStatus)}`}>
                                <div className="flex items-center gap-4"><Activity size={24} className="group-hover:scale-110 transition-transform"/><div><p className="font-bold text-sm">Diagnostics système</p><p className={`text-xs mt-1 ${sysSummary.loaded ? 'opacity-80' : 'opacity-50 animate-pulse'}`}>{sysSummary.loaded ? `RAM: ${sysSummary.ram} • DB: ${sysSummary.db}` : 'Analyse en cours...'}</p></div></div>
                            </button>
                            <button onClick={fetchLogs} title="Consulter les erreurs backend" className={`w-full flex items-center justify-between p-4 rounded-xl border transition group text-left ${getColorClass(sysSummary.logStatus)}`}>
                                <div className="flex items-center gap-4"><Terminal size={24} className="group-hover:scale-110 transition-transform"/><div><p className="font-bold text-sm">Logs d'erreurs (PHP)</p><p className={`text-xs mt-1 ${sysSummary.loaded ? 'opacity-80' : 'opacity-50 animate-pulse'}`}>{sysSummary.loaded ? sysSummary.logDesc : 'Chargement...'}</p></div></div>
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        );
    };

    const renderClients = () => (
        <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">Base clients</h1><p className="text-slate-500 font-medium">Gestion des comptes et prise de contrôle.</p></div>
            </div>
            
            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                {clients.map(c => {
                    // CORRECTION : Contournement bug Safari Date
                    const isImpersonable = c.admin_access_until && new Date(String(c.admin_access_until || '').replace(' ', 'T')) > new Date();
                    const isSuspended = c.paymentStatus === 'suspended';
                    return (
                        <div key={c.id} className="bg-white rounded-3xl p-5 shadow-sm border border-slate-200 flex flex-col gap-4 transition hover:shadow-md hover:border-blue-200 group">
                            <div className="flex justify-between items-start">
                                <div className="flex gap-3 min-w-0">
                                    <div className="w-12 h-12 rounded-2xl bg-blue-50 text-blue-600 flex items-center justify-center shrink-0">
                                        <Users size={24} />
                                    </div>
                                    <div className="min-w-0">
                                        <p className="font-black text-base text-slate-800 truncate" title={c.name}>{c.name}</p>
                                        <p className="text-xs text-slate-500 truncate" title={c.email}>{c.email}</p>
                                        <p className="text-[10px] text-slate-400 font-mono mt-1">ID : {c.id.substring(0,8)}</p>
                                    </div>
                                </div>
                            </div>
                            
                            <div className="flex items-center gap-2">
                                <span className={`px-2 py-1 inline-flex items-center justify-center text-[10px] font-black uppercase tracking-wider rounded-lg ${isSuspended ? 'bg-red-100 text-red-700' : 'bg-emerald-100 text-emerald-700'}`}>
                                    {isSuspended ? 'Suspendu' : 'Actif'}
                                </span>
                                {c.discount > 0 && <span className="px-2 py-1 bg-purple-100 text-purple-700 text-[10px] font-black tracking-wider uppercase rounded-lg">Remise {c.discount}%</span>}
                            </div>
                            
                            <div className="flex gap-2 pt-4 border-t border-slate-100 mt-auto">
                                {isImpersonable ? (
                                    <div className="flex-1 flex gap-2">
                                        <button onClick={() => impersonateClient(c.id)} title="Prendre le contrôle du compte client" className="flex-1 py-2 bg-emerald-600 text-white rounded-xl text-xs font-bold hover:bg-emerald-700 transition flex justify-center items-center gap-2 shadow-sm"><KeyRound size={14}/> Contrôler</button>
                                        <button onClick={() => revokeAccess(c.id)} title="Révoquer l'accès" className="px-3 py-2 bg-orange-100 text-orange-600 rounded-xl text-xs font-bold hover:bg-orange-200 transition flex justify-center items-center"><ShieldAlert size={14}/></button>
                                    </div>
                                ) : (
                                    <button onClick={() => setAccessRequestModal(c.id)} title="Demander l'accès au compte" className="flex-1 py-2 bg-slate-100 text-slate-600 rounded-xl text-xs font-bold hover:bg-slate-200 transition flex justify-center items-center gap-2"><Shield size={14}/> Accès</button>
                                )}
                                
                                {/* NOUVEAU BOUTON : Créditer le client */}
                                <button onClick={() => setCreditModal({ client_uid: c.id, clientName: c.name || c.email })} title="Ajouter un crédit (Bon d'achat)" className="px-4 py-2 bg-emerald-50 text-emerald-600 rounded-xl hover:bg-emerald-100 transition flex justify-center items-center"><Zap size={16}/></button>

                                <button onClick={() => {
                                    const u = new URL(window.location);
                                    u.searchParams.set('chat_id', 'SUPPORT_' + c.id);
                                    window.history.replaceState({}, '', u);
                                    setActiveTab('messages');
                                }} title="Ouvrir la messagerie avec ce client" className="px-4 py-2 bg-blue-50 text-blue-600 rounded-xl hover:bg-blue-100 transition flex justify-center items-center"><MessageSquare size={16}/></button>
                                <button onClick={() => deleteClient(c.id, c.name || c.email)} title="Supprimer définitivement ce compte" className="px-4 py-2 bg-red-50 text-red-600 rounded-xl hover:bg-red-100 transition flex justify-center items-center"><Trash2 size={16}/></button>
                            </div>
                        </div>
                    );
                })}
                {clients.length === 0 && (
                    <div className="col-span-full text-center p-12 bg-white rounded-3xl border border-slate-200 border-dashed">
                        <Users size={48} className="mx-auto text-slate-300 mb-4" />
                        <p className="text-slate-500 italic">Aucun client enregistré.</p>
                    </div>
                )}
            </div>
        </div>
    );

    const renderPanneaux = () => {
        const demoPanneau = panneaux.find(p => p.id === 'demo-panneau') || { id: 'demo-panneau', status: 'Actif', offerType: 'demo', name: 'Panneau de démonstration', location: 'Paris', themeColor: '#059669', hasNoAds: false };
        const regularPanneaux = panneaux.filter(p => p.id !== 'demo-panneau');
        
        const unseenPanels = regularPanneaux.filter(p => !p.admin_seen);
        const seenPanels = regularPanneaux.filter(p => p.admin_seen);

        const PanelCard = ({ c }) => {
            const client = clients.find(cl => cl.id === c.clientName);
            const { isViolation, detected } = checkPanelViolations(c);
            
            return (
                <div className={`bg-white rounded-3xl p-5 shadow-sm border flex flex-col gap-4 transition hover:shadow-md ${isViolation ? 'border-red-400 bg-red-50/30' : 'border-slate-200 hover:border-emerald-200'} group`}>
                    <div className="flex justify-between items-start gap-2">
                        <div className="flex gap-3 min-w-0">
                            <div className={`w-12 h-12 rounded-2xl flex items-center justify-center shrink-0 ${c.status === 'Actif' ? 'bg-emerald-50 text-emerald-600' : 'bg-slate-100 text-slate-400'}`}>
                                <Building size={24} />
                            </div>
                            <div className="min-w-0">
                                <p className="font-black text-base text-slate-800 truncate" title={c.name}>{c.name}</p>
                                <p className="text-xs text-slate-500 truncate" title={c.location}>{c.location}</p>
                                <div className="mt-1.5 flex flex-wrap gap-1">
                                    <span className="text-[9px] font-bold text-emerald-700 bg-emerald-50 border border-emerald-100 px-2 py-0.5 rounded-md truncate max-w-full" title={`Client : ${client ? client.name : c.clientName}`}>Client : {client ? client.name : c.clientName}</span>
                                </div>
                            </div>
                        </div>
                        {isViolation && (
                            <button onClick={() => setModerationData({ panneau: c, detected })} className="p-2 bg-red-100 text-red-600 rounded-xl hover:bg-red-200 transition" title="Alerte modération détectée">
                                <AlertTriangle size={18}/>
                            </button>
                        )}
                    </div>
                    
                    <div className="grid grid-cols-2 gap-2 mt-auto">
                        <div className="bg-slate-50 p-2 rounded-xl border border-slate-100 text-center">
                            <p className="text-[9px] font-bold text-slate-400 uppercase tracking-widest">Abonnement</p>
                            <p className="text-sm font-black text-slate-800 mt-0.5">{c.offerType === 'rental' ? 'Loc.' : 'Achat'} <span className="text-xs text-slate-500 font-medium">({c.currentRate}€)</span></p>
                        </div>
                        <div className="bg-slate-50 p-2 rounded-xl border border-slate-100 text-center">
                            <p className="text-[9px] font-bold text-slate-400 uppercase tracking-widest">Statut</p>
                            <p className={`text-sm font-black mt-0.5 ${c.status === 'Actif' ? 'text-emerald-600' : 'text-slate-600'}`}>{c.status}</p>
                        </div>
                    </div>

                    <div className="pt-4 border-t border-slate-100 flex gap-2">
                        <button onClick={() => handlePreviewAndMarkSeen(c)} title="Contrôler le panneau public" className="flex-1 py-2 bg-blue-50 text-blue-700 rounded-xl text-xs font-bold hover:bg-blue-100 transition flex justify-center items-center gap-2">
                            <Eye size={14}/> Contrôler
                        </button>
                        <button onClick={() => togglePanneauStatus(c.id, c.status)} title={c.status === 'Actif' ? 'Désactiver le panneau (coupe abonnement)' : 'Activer le panneau'} className={`flex-1 py-2 rounded-xl text-xs font-bold transition flex justify-center items-center gap-2 ${c.status === 'Actif' ? 'bg-red-50 text-red-600 hover:bg-red-100' : 'bg-emerald-50 text-emerald-600 hover:bg-emerald-100'}`}>
                            <Power size={14}/> {c.status === 'Actif' ? 'Désactiver' : 'Activer'}
                        </button>
                    </div>
                </div>
            );
        };

        return (
            <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">Tous les panneaux</h1><p className="text-slate-500 font-medium">Supervision des affichages légaux.</p></div>
                </div>
                
                <div className="bg-purple-50 border border-purple-200 rounded-3xl p-5 flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4 shadow-sm">
                    <div className="flex gap-4 items-center">
                        <div className="w-12 h-12 bg-purple-200 text-purple-700 rounded-2xl flex items-center justify-center shrink-0"><Eye size={24}/></div>
                        <div>
                            <h3 className="font-black text-purple-900 text-lg leading-tight">Panneau de démonstration</h3>
                            <p className="text-xs text-purple-700 font-medium mt-1">Gérez le contenu du faux panneau affiché sur la page d'accueil publique.</p>
                        </div>
                    </div>
                    <button onClick={() => { setManagingPanneau({...demoPanneau}); setModalView('config_demo'); setIsModalOpen(true); }} title="Éditer le panneau de démonstration" className="w-full sm:w-auto bg-purple-600 text-white px-6 py-3 rounded-xl text-sm font-bold shadow-lg hover:bg-purple-700 transition flex items-center justify-center gap-2"><Edit size={16}/> Éditer le panneau</button>
                </div>

                {unseenPanels.length > 0 && (
                    <div className="space-y-4">
                        <h2 className="text-xl font-black text-slate-800 flex items-center gap-2 pt-4"><AlertOctagon size={20} className="text-amber-500"/> À contrôler (nouveaux ou modifiés)</h2>
                        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                            {unseenPanels.map(c => <PanelCard key={c.id} c={c} />)}
                        </div>
                    </div>
                )}

                {seenPanels.length > 0 && (
                    <div className="space-y-4">
                        <h2 className="text-xl font-black text-slate-800 flex items-center gap-2 pt-4 border-t border-slate-200 mt-6"><CheckCircle size={20} className="text-emerald-500"/> Déjà contrôlés</h2>
                        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 opacity-90 hover:opacity-100 transition-opacity">
                            {seenPanels.map(c => <PanelCard key={c.id} c={c} />)}
                        </div>
                    </div>
                )}

                {regularPanneaux.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" />
                        <p className="text-slate-500 italic">Aucun panneau client enregistré.</p>
                    </div>
                )}
            </div>
        );
    };

    const renderLogistique = () => {
        const logiPanneaux = panneaux.filter(p => p.physicalPanels > 0 && p.id !== 'demo-panneau');
        return (
            <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">Logistique</h1><p className="text-slate-500 font-medium">Gestion des expéditions de panneaux physiques A1.</p></div>
                </div>
                
                <div className="grid grid-cols-1 gap-4">
                    {logiPanneaux.map(c => {
                        const client = clients.find(cl => cl.id === c.clientName);
                        
                        const status = c.shipping_status || 'Validation en cours';
                        const isValidation = status === 'Validation en cours';
                        const isPrinting = status === "Attente d'impression";
                        const isShipped = status === 'Expédié';
                        const isDelivered = status === 'Livré';

                        return (
                            <div key={c.id} className="bg-white rounded-3xl p-5 shadow-sm border border-slate-200 flex flex-col md:flex-row gap-4 md:items-center transition hover:shadow-md">
                                {/* Identité */}
                                <div className="flex-1 min-w-0 flex items-start gap-4">
                                    <div className={`w-12 h-12 rounded-2xl flex items-center justify-center shrink-0 ${isDelivered ? 'bg-emerald-50 text-emerald-600' : (isShipped ? 'bg-blue-50 text-blue-600' : 'bg-slate-100 text-slate-500')}`}>
                                        {isDelivered ? <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 font-bold text-emerald-600 mt-0.5 truncate" title={client?.name}>Client : {client?.name || 'Inconnu'}</p>
                                        <p className="text-xs text-slate-500 mt-1 flex items-start gap-1">
                                            <MapPin size={14} className="shrink-0 opacity-70" />
                                            <span className="line-clamp-2 leading-tight" title={client?.address}>{client?.address || 'Adresse non renseignée'}</span>
                                        </p>
                                    </div>
                                </div>

                                {/* Quantité */}
                                <div className="md:w-24 shrink-0 flex flex-col items-start md:items-center border-t md:border-t-0 md:border-l border-slate-100 pt-4 md:pt-0 md:px-4">
                                    <p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest mb-2">Quantité</p>
                                    <div className="w-12 h-12 flex items-center justify-center bg-emerald-50 text-emerald-600 rounded-xl font-black text-xl">{c.physicalPanels}</div>
                                </div>

                                {/* Statut et Boutons d'Action Logistique */}
                                <div className="md:w-64 shrink-0 flex flex-col gap-2 border-t md:border-t-0 md:border-l border-slate-100 pt-4 md:pt-0 md:px-4">
                                    <div className="flex justify-between items-center mb-1">
                                        <p className="text-[10px] font-bold uppercase tracking-widest text-slate-500">Statut</p>
                                        <span className={`px-2 py-0.5 rounded-md text-[10px] font-black uppercase ${isDelivered ? 'bg-emerald-100 text-emerald-700' : (isShipped ? 'bg-blue-100 text-blue-700' : 'bg-amber-100 text-amber-700')}`}>
                                            {status}
                                        </span>
                                    </div>
                                    
                                    {isValidation && (
                                        <button onClick={() => updateShipping(c.id, "Attente d'impression", '', '')} disabled={isSaving} className="w-full py-2 bg-amber-50 text-amber-700 font-bold rounded-xl hover:bg-amber-100 transition text-xs flex justify-center items-center gap-1 disabled:opacity-50"><RefreshCw size={14}/> Passer en impression</button>
                                    )}
                                    {isPrinting && (
                                        <button onClick={() => { setShippingModal(c); setTrackingData({number: '', link: ''}); }} disabled={isSaving} className="w-full py-2 bg-blue-50 text-blue-700 font-bold rounded-xl hover:bg-blue-100 transition text-xs flex justify-center items-center gap-1 disabled:opacity-50"><Package size={14}/> Déclarer expédié</button>
                                    )}
                                    {isShipped && (
                                        <div className="text-center bg-slate-50 p-3 rounded-xl border border-slate-100 flex flex-col gap-1">
                                            <p className="text-[10px] font-bold text-slate-500 uppercase tracking-widest">En cours d'acheminement</p>
                                            <p className="text-sm font-mono text-blue-600 font-bold select-all">{c.tracking_number}</p>
                                            <button 
                                                onClick={() => { setShippingModal(c); setTrackingData({number: c.tracking_number || '', link: c.tracking_link || ''}); }} 
                                                disabled={isSaving} 
                                                className="mt-2 w-full py-1.5 bg-white border border-slate-200 text-slate-600 font-bold rounded-lg hover:bg-slate-50 transition text-[10px] flex justify-center items-center gap-1 shadow-sm"
                                            >
                                                <Edit size={12}/> Modifier le suivi
                                            </button>
                                        </div>
                                    )}
                                    {isDelivered && (
                                        <div className="text-center bg-emerald-50 p-2 rounded-xl border border-emerald-100 flex items-center justify-center gap-1">
                                            <CheckCircle size={14} className="text-emerald-600"/>
                                            <p className="text-xs font-bold text-emerald-700">Réception confirmée</p>
                                        </div>
                                    )}
                                </div>

                                {/* Fichier A1 */}
                                <div className="md:w-32 shrink-0 flex items-center justify-end md:justify-center border-t md:border-t-0 md:border-l border-slate-100 pt-4 md:pt-0 md:pl-4">
                                    {c.a1PdfId ? (
                                        <div className="flex flex-col gap-2 w-full">
                                            <a href={`?api=file/download&type=pdf&id=${c.a1PdfId}`} target="_blank" className="flex flex-col items-center justify-center p-2 w-full bg-blue-50 text-blue-600 rounded-xl hover:bg-blue-100 transition group" title="Télécharger le fichier A1">
                                                <FileText size={18} className="group-hover:scale-110 transition-transform mb-1 text-blue-600" />
                                                <span className="text-[10px] font-black uppercase tracking-wider mt-1 text-center">PDF Validé</span>
                                            </a>
                                            <button onClick={() => handleA1Delete(c)} disabled={isSaving} className="text-[10px] text-red-500 font-bold hover:text-red-700 transition w-full text-center">
                                                Retirer
                                            </button>
                                        </div>
                                    ) : (
                                        <div className="flex flex-col gap-2 w-full">
                                            <div className="flex flex-col gap-1 w-full">
                                                <button onClick={async () => {
                                                    setIsSaving(true);
                                                    try {
                                                        const blob = await window.generateA1PDF(c);
                                                        const link = document.createElement('a');
                                                        link.href = URL.createObjectURL(blob);
                                                        link.download = `Panneau_A1_${c.id}.pdf`;
                                                        link.click();
                                                    } catch(e) { showToast("Erreur PDF", "error"); }
                                                    setIsSaving(false);
                                                }} disabled={isSaving} className="py-1.5 px-2 bg-slate-100 text-slate-700 font-bold rounded-lg text-[10px] hover:bg-slate-200 transition w-full flex justify-center items-center gap-1 shadow-sm" title="Télécharger le PDF généré automatiquement pour vérification">
                                                    <Download size={12}/> Contrôler
                                                </button>
                                                
                                                <button onClick={() => {
                                                    setConfirmDialog({
                                                        title: "Validation de la maquette",
                                                        message: "Valider ce PDF généré automatiquement pour l'impression ?",
                                                        confirmText: "Valider",
                                                        onConfirm: async () => {
                                                            setIsSaving(true);
                                                            try {
                                                                const blob = await window.generateA1PDF(c);
                                                                const file = new File([blob], `A1_${c.id}.pdf`, { type: 'application/pdf' });
                                                                const id = await window.uploadFile(file, 'pdf');
                                                                const payload = { id: c.id, status: c.status, offerType: c.offerType, currentRate: c.currentRate, physicalPanels: c.physicalPanels, details: { ...c, a1PdfId: id } };
                                                                const res = await fetch(window.ECO_CONFIG.apiBaseUrl + 'panneaux', { method: 'POST', body: JSON.stringify(payload) });
                                                                if((await res.json()).status === 'success') { showToast("PDF généré et validé !"); refreshData(); }
                                                            } catch(e) { showToast("Erreur validation", "error"); }
                                                            setIsSaving(false);
                                                        }
                                                    });
                                                }} disabled={isSaving} className="py-1.5 px-2 bg-emerald-50 text-emerald-700 font-bold rounded-lg text-[10px] hover:bg-emerald-100 transition w-full flex justify-center items-center gap-1 shadow-sm" title="Valider et attacher la maquette générée automatiquement">
                                                    <CheckCircle size={12}/> Valider
                                                </button>
                                            </div>
                                            
                                            <div className="relative w-full text-center my-0.5">
                                                <div className="absolute inset-0 flex items-center"><div className="w-full border-t border-slate-200"></div></div>
                                                <div className="relative flex justify-center"><span className="bg-white px-1 text-[8px] uppercase tracking-widest text-slate-400">Ou</span></div>
                                            </div>

                                            <label className="cursor-pointer flex flex-col items-center justify-center p-2 w-full bg-white text-slate-500 hover:text-blue-600 hover:bg-blue-50 rounded-lg transition border border-dashed border-slate-300 hover:border-blue-300" title="Uploader une maquette PDF modifiée manuellement">
                                                <Plus size={14} className="mb-0.5" />
                                                <span className="text-[9px] font-black uppercase tracking-wider">Manquant</span>
                                                <input type="file" accept="application/pdf" className="hidden" disabled={isSaving} onChange={(e) => handleA1Upload(c, e)} />
                                            </label>
                                        </div>
                                    )}
                                </div>
                            </div>
                        );
                    })}
                    {logiPanneaux.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 commande</h3>
                            <p className="text-slate-500 text-sm mt-1">Les commandes de panneaux physiques apparaîtront ici.</p>
                        </div>
                    )}
                </div>
            </div>
        );
    };

    const renderInvoices = () => (
        <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">Facturation globale</h1><p className="text-slate-500 font-medium">Historique des paiements de tous les clients.</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>
            
            <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) => {
                            const client = clients.find(c => c.id === inv.clientName);
                            return (
                                <tr key={i} className="hover:bg-slate-50 transition group">
                                    <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]" title={inv.panneauName}>{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>
                                        {/* NOUVEAU BOUTON : Rembourser / Avoir */}
                                        {!inv.type.includes('Avoir') && (
                                            <button onClick={() => setRefundModal({ invoice: inv, clientName: client?.name || 'Client' })} title="Émettre un avoir / Rembourser" className="inline-flex p-2 ml-2 bg-orange-50 text-orange-600 rounded-lg hover:bg-orange-100 transition"><RefreshCw size={16}/></button>
                                        )}
                                    </td>
                                </tr>
                            );
                        })}
                    </tbody>
                </table>
                {(!data.invoices || data.invoices.length === 0) && (
                    <div className="col-span-full text-center p-12 bg-white rounded-3xl border border-slate-200 border-dashed">
                        <FileText size={48} className="mx-auto text-slate-300 mb-4" />
                        <p className="text-slate-500 italic">Aucune facture émise.</p>
                    </div>
                )}
            </div>
        </div>
    );

    const renderMessages = () => {
        const threadsMap = {};
        interactions.forEach(m => {
            let threadId = null; let title = ''; let targetEmail = '';
            if (m.panneauId === 'CONTACT_PUBLIC') { targetEmail = (m.target === 'Admin') ? m.author : m.target; if (!targetEmail) return; threadId = `CONTACT_PUBLIC_${targetEmail}`; title = `Nous contacter : ${targetEmail}`; } 
            else if (m.panneauId.startsWith('SUPPORT_')) { threadId = m.panneauId; const cUid = m.panneauId.split('_')[1]; const cName = clients.find(c => c.id === cUid)?.name || 'Client Inconnu'; title = `Support : ${cName}`; targetEmail = 'Client'; }
            if (threadId) { if (!threadsMap[threadId]) threadsMap[threadId] = { id: threadId, title, targetEmail, messages: [], unread: 0 }; threadsMap[threadId].messages.push(m); if (m.target === 'Admin' && !m.resolved) threadsMap[threadId].unread++; }
        });

        const requestedChatId = new URLSearchParams(window.location.search).get('chat_id');
        if (requestedChatId && requestedChatId.startsWith('SUPPORT_') && !threadsMap[requestedChatId]) {
            const cUid = requestedChatId.split('_')[1];
            const clientObj = clients.find(c => c.id === cUid);
            if (clientObj) {
                threadsMap[requestedChatId] = {
                    id: requestedChatId,
                    title: `Support : ${clientObj.name || 'Client Inconnu'}`,
                    targetEmail: 'Client',
                    messages: [],
                    unread: 0
                };
            }
        }

        const threads = Object.values(threadsMap).sort((a,b) => {
            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 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 handleSendAdmin = async (text) => {
            if (!selectedThread) return;
            
            const optimisticMsg = {
                id: 'temp_' + Date.now(),
                panneauId: selectedThread.id.startsWith('CONTACT_PUBLIC') ? 'CONTACT_PUBLIC' : selectedThread.id,
                author: 'Admin',
                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.id.startsWith('CONTACT_PUBLIC') ? 'CONTACT_PUBLIC' : selectedThread.id, detail: text, author: 'Admin', targetEmail: selectedThread.targetEmail };
            fetch(window.ECO_CONFIG.apiBaseUrl + 'interactions', { method: 'POST', body: JSON.stringify(payload) });
        };

        const currentClient = selectedThread?.id.startsWith('SUPPORT_') ? clients.find(c => c.id === selectedThread.id.split('_')[1]) : null;
        const isImpersonable = currentClient && currentClient.admin_access_until && new Date(String(currentClient.admin_access_until || '').replace(' ', 'T')) > new Date();

        let chatClientName = 'Client';
        if (currentClient && currentClient.name) {
            chatClientName = currentClient.name;
        }

        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="font-bold text-sm text-slate-800 truncate">{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>
                                {selectedThread.id.startsWith('SUPPORT_') && (
                                    isImpersonable ? (
                                        <div className="flex items-center gap-2 shrink-0 ml-auto">
                                            <button onClick={() => impersonateClient(currentClient.id)} className="text-xs font-bold bg-emerald-600 text-white hover:bg-emerald-700 px-3 py-1.5 rounded-lg flex items-center gap-2 transition shadow-sm">
                                                <KeyRound size={14}/> <span className="hidden sm:inline">Contrôler</span>
                                            </button>
                                            <button onClick={() => revokeAccess(currentClient.id)} className="text-xs font-bold bg-orange-100 text-orange-600 hover:bg-orange-200 px-3 py-1.5 rounded-lg flex items-center gap-2 transition shadow-sm border border-orange-200">
                                                <ShieldAlert size={14}/> <span className="hidden sm:inline">Révoquer</span>
                                            </button>
                                        </div>
                                    ) : (
                                        <button onClick={() => setAccessRequestModal(currentClient.id)} className="ml-auto text-xs font-bold bg-slate-100 text-slate-600 hover:bg-slate-200 px-3 py-1.5 rounded-lg flex items-center gap-2 transition shadow-sm border border-slate-200 shrink-0">
                                            <Shield size={14}/> <span className="hidden sm:inline">Demander l'accès</span>
                                        </button>
                                    )
                                )}
                            </div>
                            <div className="flex-1 min-h-0 relative">
                                <div className="absolute inset-0">
                                    <window.ChatBox 
                                        messages={selectedThread.messages} 
                                        currentUserRole="admin" 
                                        panneauId={selectedThread.id.startsWith('CONTACT_PUBLIC') ? 'CONTACT_PUBLIC' : selectedThread.id} 
                                        refreshData={refreshData} 
                                        onSend={handleSendAdmin}
                                        clientName={chatClientName}
                                    />
                                </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 renderSettings = () => (
        <div className="space-y-6 animate-in fade-in slide-in-from-bottom-4 max-w-4xl mx-auto">
            <div><h1 className="text-3xl font-black text-slate-800">Paramètres système</h1><p className="text-slate-500 font-medium">Tarification globale et mentions légales.</p></div>

            <div className="bg-white rounded-3xl p-6 shadow-sm border border-slate-200 mt-6">
                <h3 className="font-black text-slate-800 mb-6 flex items-center gap-2"><ShieldAlert size={18} className="text-red-600"/> Cyberdéfense et pare-feu (Panic Mode)</h3>
                <p className="text-xs text-slate-500 mb-6">Paramétrez les seuils de déclenchement du confinement automatique en cas d'attaque réseau.</p>
                
                <div className="grid grid-cols-1 sm:grid-cols-2 gap-6 mb-6">
                    <div className="p-4 bg-slate-50 border border-slate-100 rounded-xl">
                        <label className="text-xs font-bold text-slate-700 uppercase block mb-1">Limite d'échecs par IP</label>
                        <p className="text-[10px] text-slate-500 mb-3">Nombre d'erreurs de mot de passe avant bannissement de l'IP (15 min).</p>
                        <input type="number" min="1" max="50" value={settingsData.sec_ip_limit} onChange={e => setSettingsData({...settingsData, sec_ip_limit: e.target.value})} className="w-full border-2 border-slate-200 rounded-xl p-2 text-sm focus:border-red-500 outline-none transition" />
                    </div>
                    
                    <div className="p-4 bg-slate-50 border border-slate-100 rounded-xl">
                        <label className="text-xs font-bold text-slate-700 uppercase block mb-1">Seuil d'alerte globale (DDoS / Botnet)</label>
                        <p className="text-[10px] text-slate-500 mb-3">Nombre d'IPs malveillantes simultanées avant confinement du site.</p>
                        <input type="number" min="50" max="10000" value={settingsData.sec_global_limit} onChange={e => setSettingsData({...settingsData, sec_global_limit: e.target.value})} className="w-full border-2 border-slate-200 rounded-xl p-2 text-sm focus:border-red-500 outline-none transition" />
                    </div>
                    
                    <div className="p-4 bg-slate-50 border border-slate-100 rounded-xl">
                        <label className="text-xs font-bold text-slate-700 uppercase block mb-1">Durée minimum du confinement</label>
                        <p className="text-[10px] text-slate-500 mb-3">En minutes (Valeur aléatoire entre le min et le max).</p>
                        <input type="number" min="1" max="120" value={settingsData.sec_lock_min} onChange={e => setSettingsData({...settingsData, sec_lock_min: e.target.value})} className="w-full border-2 border-slate-200 rounded-xl p-2 text-sm focus:border-red-500 outline-none transition" />
                    </div>

                    <div className="p-4 bg-slate-50 border border-slate-100 rounded-xl">
                        <label className="text-xs font-bold text-slate-700 uppercase block mb-1">Durée maximum du confinement</label>
                        <p className="text-[10px] text-slate-500 mb-3">En minutes.</p>
                        <input type="number" min="2" max="1440" value={settingsData.sec_lock_max} onChange={e => setSettingsData({...settingsData, sec_lock_max: e.target.value})} className="w-full border-2 border-slate-200 rounded-xl p-2 text-sm focus:border-red-500 outline-none transition" />
                    </div>
                </div>
            </div>

            <div className="bg-white rounded-3xl p-6 shadow-sm border border-slate-200 mt-6">
                <h3 className="font-black text-slate-800 mb-6 flex items-center gap-2"><CreditCard size={18} className="text-emerald-600"/> Paramètres des ventes</h3>
                
                <div className="p-4 bg-orange-50 border border-orange-200 rounded-xl mb-6">
                    <label className="flex items-center justify-between cursor-pointer">
                        <div>
                            <span className="text-sm font-bold text-orange-900">Autoriser les nouvelles commandes (Ventes)</span>
                            <p className="text-[10px] text-orange-700 mt-1">Désactivez ceci pour empêcher temporairement les clients de payer/créer de nouveaux panneaux.</p>
                        </div>
                        <div className={`w-12 h-6 rounded-full transition-colors relative shrink-0 ml-4 ${settingsData.allow_new_purchases === '1' ? 'bg-emerald-500' : 'bg-slate-300'}`}>
                            <div className={`absolute top-1 bg-white w-4 h-4 rounded-full transition-transform ${settingsData.allow_new_purchases === '1' ? 'translate-x-7' : 'translate-x-1'}`}></div>
                        </div>
                        <input type="checkbox" checked={settingsData.allow_new_purchases === '1'} onChange={e => setSettingsData({...settingsData, allow_new_purchases: e.target.checked ? '1' : '0'})} className="hidden" />
                    </label>
                </div>

                <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 mb-6">
                    <window.PriceInput label="Abonnement mensuel" value={settingsData.rentalMo} onChange={v => setSettingsData({...settingsData, rentalMo: v})} />
                    <window.PriceInput label="Achat définitif" value={settingsData.purchase} onChange={v => setSettingsData({...settingsData, purchase: v})} />
                    <window.PriceInput label="Hébergement annuel" value={settingsData.hostingYr} onChange={v => setSettingsData({...settingsData, hostingYr: v})} />
                    
                    <window.PriceInput label="Panneau physique (1er)" value={settingsData.boardFirst} onChange={v => setSettingsData({...settingsData, boardFirst: v})} />
                    <window.PriceInput label="Panneau physique (suivants)" value={settingsData.boardAdd} onChange={v => setSettingsData({...settingsData, boardAdd: v})} />
                    <window.PriceInput label="Option marque blanche" value={settingsData.noAds} onChange={v => setSettingsData({...settingsData, noAds: v})} />
                </div>
                
                <h3 className="font-black text-slate-800 mb-6 flex items-center gap-2 border-t pt-6"><FileText size={18} className="text-emerald-600"/> Mentions légales (CGV et RGPD)</h3>
                <div className="space-y-4 mb-6">
                    <div className="space-y-1"><label className="text-xs font-bold text-slate-500 uppercase block">Conditions générales de vente</label><textarea value={settingsData.cgv || ''} onChange={e=>setSettingsData({...settingsData, cgv: e.target.value})} rows="4" className="w-full border-2 border-slate-200 rounded-xl p-3 text-sm focus:border-emerald-500 outline-none transition custom-scrollbar"></textarea></div>
                    <div className="space-y-1"><label className="text-xs font-bold text-slate-500 uppercase block">Politique de confidentialité (RGPD)</label><textarea value={settingsData.rgpd || ''} onChange={e=>setSettingsData({...settingsData, rgpd: e.target.value})} rows="4" className="w-full border-2 border-slate-200 rounded-xl p-3 text-sm focus:border-emerald-500 outline-none transition custom-scrollbar"></textarea></div>
                </div>

                <div className="bg-slate-50 rounded-2xl p-4 sm:p-6 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"/> Émetteur (facturation)</h3>
                        <button onClick={handleAutoFill} className="text-xs font-bold text-blue-700 bg-blue-100 hover:bg-blue-200 px-3 py-1.5 rounded-lg flex items-center gap-1 transition shadow-sm"><Zap size={14}/> Saisie automatique</button>
                    </div>
                    <div className="grid grid-cols-1 sm:grid-cols-2 gap-4 mb-4">
                        <div className="space-y-1"><label className="text-xs font-bold text-slate-500 uppercase block">Raison sociale</label><input value={settingsData.billing_company || ''} onChange={e=>setSettingsData({...settingsData, billing_company: e.target.value})} className="w-full border border-slate-200 rounded-lg p-2 text-sm outline-none focus:border-slate-400 bg-white" /></div>
                        <div className="space-y-1"><label className="text-xs font-bold text-slate-500 uppercase block">SIRET</label><input value={settingsData.billing_siret || ''} onChange={e=>setSettingsData({...settingsData, billing_siret: e.target.value})} className="w-full border border-slate-200 rounded-lg p-2 text-sm outline-none focus:border-slate-400 bg-white" /></div>
                        <div className="space-y-1 sm:col-span-2"><label className="text-xs font-bold text-slate-500 uppercase block">Adresse</label><input value={settingsData.billing_address || ''} onChange={e=>setSettingsData({...settingsData, billing_address: e.target.value})} className="w-full border border-slate-200 rounded-lg p-2 text-sm outline-none focus:border-slate-400 bg-white" /></div>
                        <div className="space-y-1 sm:col-span-2 mt-2">
                            <label className="text-xs font-bold text-slate-500 uppercase block">Texte légal (bas de facture)</label>
                            <textarea value={settingsData.billing_legalText || ''} onChange={e=>setSettingsData({...settingsData, billing_legalText: e.target.value})} rows="2" className="w-full border border-slate-200 rounded-lg p-2 text-sm outline-none focus:border-slate-400 bg-white custom-scrollbar" placeholder="Ex: SAS au capital de..."></textarea>
                        </div>
                    </div>

                    <div className="pt-4 border-t border-slate-200 mt-2">
                        <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 sur la plateforme.</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-3 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={settingsData.billing_tva || ''} onChange={e=>setSettingsData({...settingsData, billing_tva: e.target.value})} placeholder="FR..." className="w-full border border-slate-200 rounded-lg p-2 text-sm outline-none focus:border-slate-400 uppercase bg-white" />
                            </div>
                        )}
                    </div>
                </div>

                <div className="bg-white rounded-3xl p-6 shadow-sm border border-slate-200 mt-6">
                    <h3 className="font-black text-slate-800 mb-6 flex items-center gap-2"><AlertTriangle size={18} className="text-emerald-600"/> Bandeaux d'information</h3>
                    <p className="text-xs text-slate-500 mb-4">Affichez des messages importantes aux utilisateurs de la plateforme.</p>
                    <div className="space-y-6">
                        <div className="p-4 bg-orange-50 border border-orange-200 rounded-xl">
                            <label className="flex items-center justify-between cursor-pointer mb-3">
                                <span className="text-sm font-bold text-orange-900">Bandeau global (Orange)</span>
                                <input type="checkbox" checked={settingsData.site_banner_active === '1'} onChange={e => setSettingsData({...settingsData, site_banner_active: e.target.checked ? '1' : '0'})} className="w-5 h-5 accent-orange-600" />
                            </label>
                            <p className="text-[10px] text-orange-700 mb-2">Visible par les clients et visiteurs (sauf espace riverain).</p>
                            <textarea value={settingsData.site_banner_msg || ''} onChange={e=>setSettingsData({...settingsData, site_banner_msg: e.target.value})} rows="2" placeholder="Ex: Maintenance prévue ce soir à 20h..." className="w-full border-2 border-orange-200 rounded-xl p-3 text-sm focus:border-orange-500 outline-none transition custom-scrollbar"></textarea>
                        </div>
                        
                        <div className="p-4 bg-blue-50 border border-blue-200 rounded-xl">
                            <label className="flex items-center justify-between cursor-pointer mb-3">
                                <span className="text-sm font-bold text-blue-900">Bandeau espace riverain (Bleu)</span>
                                <input type="checkbox" checked={settingsData.panel_banner_active === '1'} onChange={e => setSettingsData({...settingsData, panel_banner_active: e.target.checked ? '1' : '0'})} className="w-5 h-5 accent-blue-600" />
                            </label>
                            <p className="text-[10px] text-blue-700 mb-2">Visible uniquement par les riverains qui scannent un panneau.</p>
                            <textarea value={settingsData.panel_banner_msg || ''} onChange={e=>setSettingsData({...settingsData, panel_banner_msg: e.target.value})} rows="2" placeholder="Ex: Bienvenue sur l'espace d'information..." className="w-full border-2 border-blue-200 rounded-xl p-3 text-sm focus:border-blue-500 outline-none transition custom-scrollbar"></textarea>
                        </div>
                    </div>
                </div>

                <div className="bg-white rounded-3xl p-6 shadow-sm border border-slate-200 mt-6">
                    <h3 className="font-black text-slate-800 mb-6 flex items-center gap-2"><ShieldAlert size={18} className="text-red-600"/> Modération et mots-clés</h3>
                    <p className="text-xs text-slate-500 mb-4">Ces listes permettent de détecter les panneaux ou messages ne respectant pas les règles de bienséance. (Mots séparés par des virgules)</p>
                    <div className="space-y-4">
                        <div>
                            <label className="text-xs font-bold text-red-600 uppercase block mb-1">Liste noire (bloquante)</label>
                            <textarea value={settingsData.blacklist || ''} onChange={e=>setSettingsData({...settingsData, blacklist: e.target.value})} rows="3" className="w-full border-2 border-red-200 rounded-xl p-3 text-sm focus:border-red-500 outline-none transition custom-scrollbar"></textarea>
                        </div>
                        <div>
                            <label className="text-xs font-bold text-amber-600 uppercase block mb-1">Liste grise (alerte si {'>'} 2)</label>
                            <textarea value={settingsData.greylist || ''} onChange={e=>setSettingsData({...settingsData, greylist: e.target.value})} rows="3" className="w-full border-2 border-amber-200 rounded-xl p-3 text-sm focus:border-amber-500 outline-none transition custom-scrollbar"></textarea>
                        </div>
                    </div>
                </div>

                <div className="bg-white rounded-3xl mt-6 p-6 shadow-sm border border-slate-200">
                    <h3 className="font-black text-slate-800 mb-2 flex items-center gap-2"><Settings size={18} className="text-emerald-600"/> Options du mode simplifié</h3>
                    <p className="text-xs text-slate-500 mb-6">Sélectionnez les fonctionnalités accessibles aux clients utilisant l'interface "Simplifiée".</p>
                    
                    <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                        {[
                            { key: 'simp_opt_description', label: 'Description des travaux' },
                            { key: 'simp_opt_image', label: 'Image du panneau' },
                            { key: 'simp_opt_theme', label: 'Couleur du thème' },
                            { key: 'simp_opt_link', label: 'Lien promoteur' },
                            { key: 'simp_opt_emergency', label: 'N° d\'urgence' },
                            { key: 'simp_opt_schedule', label: 'Horaires des nuisances' }
                        ].map(opt => (
                            <label key={opt.key} className="flex items-center justify-between p-4 border border-slate-200 rounded-xl cursor-pointer hover:bg-slate-50 transition">
                                <span className="text-sm font-bold text-slate-700">{opt.label}</span>
                                <input type="checkbox" checked={settingsData[opt.key] === '1'} onChange={e => setSettingsData({...settingsData, [opt.key]: e.target.checked ? '1' : '0'})} className="w-5 h-5 accent-emerald-600" />
                            </label>
                        ))}
                    </div>
                </div>

                <div className="border-t pt-6 mt-6">
                    <label className="flex items-center gap-3 p-4 bg-red-50 border border-red-200 rounded-xl cursor-pointer">
                        <input type="checkbox" checked={settingsData.maintenance} onChange={e => setSettingsData({...settingsData, maintenance: e.target.checked})} className="w-5 h-5 accent-red-600" />
                        <div><p className="text-sm font-bold text-red-900">Activer le mode maintenance</p><p className="text-xs text-red-700">Déconnecte tous les clients et bloque l'accès public.</p></div>
                    </label>
                </div>
                
                <button onClick={handleSaveSettings} disabled={isSaving} className="mt-6 w-full bg-slate-900 text-white py-4 rounded-xl font-black uppercase tracking-widest hover:bg-slate-800 transition shadow-lg disabled:opacity-50 flex items-center justify-center gap-2"><Save size={18}/> Sauvegarder la configuration globale</button>
            </div>
        </div>
    );

    // --- RENDU GLOBAL ---
    return (
        <window.DashboardLayout role="Super administrateur" user="System Root" theme="purple" navItems={navItems} activeTab={activeTab} setActiveTab={setActiveTab} onLogout={async () => { await fetch(window.ECO_CONFIG.apiBaseUrl + 'auth/logout'); window.location.href='?'; }}>
            {activeTab === 'dashboard' && renderDashboard()}
            {activeTab === 'clients' && renderClients()}
            {activeTab === 'panneaux' && renderPanneaux()}
            {activeTab === 'logistique' && renderLogistique()}
            {activeTab === 'invoices' && renderInvoices()}
            {activeTab === 'messages' && renderMessages()}
            {activeTab === 'settings' && renderSettings()}

            {/* Modale de décision pour les panneaux sous alerte de modération */}
            {moderationData && (
                <window.Modal title="Alerte modération" onClose={() => setModerationData(null)} zIndex="z-[250]">
                    <div className="space-y-4">
                        <p className="text-sm font-bold text-slate-700 mb-2">
                            Mots détectés dans le panneau : <span className="text-slate-900">{moderationData.panneau.name}</span>
                        </p>
                        
                        {moderationData.detected.black.length > 0 && (
                            <div className="bg-red-100 text-red-800 p-3 rounded-lg text-sm border border-red-200">
                                <strong>Liste noire :</strong> {moderationData.detected.black.join(', ')}
                            </div>
                        )}
                        
                        {moderationData.detected.grey.length > 0 && (
                            <div className="bg-amber-100 text-amber-800 p-3 rounded-lg text-sm border border-amber-200">
                                <strong>Liste grise :</strong> {moderationData.detected.grey.join(', ')}
                            </div>
                        )}

                        <div className="flex flex-col gap-3 pt-4 border-t border-slate-100">
                            <button onClick={() => {
                                // Redirige vers le tchat support avec le client
                                const u = new URL(window.location);
                                u.searchParams.set('chat_id', 'SUPPORT_' + moderationData.panneau.clientName);
                                window.history.replaceState({}, '', u);
                                setActiveTab('messages');
                                setModerationData(null);
                            }} className="w-full bg-blue-600 text-white py-3 rounded-xl font-bold hover:bg-blue-700 flex items-center justify-center gap-2">
                                <MessageSquare size={16}/> Contacter le client
                            </button>
                            <button onClick={() => {
                                togglePanneauStatus(moderationData.panneau.id, moderationData.panneau.status);
                                setModerationData(null);
                            }} className="w-full bg-red-600 text-white py-3 rounded-xl font-bold hover:bg-red-700 flex items-center justify-center gap-2">
                                <Power size={16}/> Suspendre ce panneau
                            </button>
                            <button onClick={() => setModerationData(null)} className="w-full bg-slate-100 text-slate-700 py-3 rounded-xl font-bold hover:bg-slate-200">
                                Ignorer l'alerte
                            </button>
                        </div>
                    </div>
                </window.Modal>
            )}

            {/* Modale de choix de la demande d'accès */}
            {accessRequestModal && (
                <window.Modal title="Demande d'accès" onClose={() => setAccessRequestModal(null)} zIndex="z-[250]">
                    <div className="space-y-4">
                        <div className="bg-blue-50 p-4 rounded-xl border border-blue-100 text-blue-800 text-sm leading-relaxed">
                            Comment souhaitez-vous envoyer la demande d'autorisation d'accès temporaire (24h) à ce client ?
                        </div>
                        <div className="flex flex-col gap-3">
                            <button onClick={() => sendAccessRequest(accessRequestModal, 'chat')} disabled={isSaving} className="w-full py-3 bg-white border border-slate-200 text-slate-700 font-bold rounded-xl hover:bg-slate-50 transition text-sm flex items-center justify-center gap-2 shadow-sm">
                                <MessageSquare size={16}/> Dans la messagerie (Recommandé)
                            </button>
                            <button onClick={() => sendAccessRequest(accessRequestModal, 'email')} disabled={isSaving} className="w-full py-3 bg-white border border-slate-200 text-slate-700 font-bold rounded-xl hover:bg-slate-50 transition text-sm flex items-center justify-center gap-2 shadow-sm">
                                <Mail size={16}/> Par e-mail
                            </button>
                            <button onClick={() => sendAccessRequest(accessRequestModal, 'both')} disabled={isSaving} className="w-full py-3 bg-emerald-600 text-white font-bold rounded-xl hover:bg-emerald-700 shadow-md transition text-sm flex items-center justify-center gap-2">
                                <CheckCircle size={16}/> Les deux
                            </button>
                        </div>
                    </div>
                </window.Modal>
            )}

            {/* Modale d'expédition logistique */}
            {shippingModal && (
                <window.Modal title={shippingModal.shipping_status === 'Expédié' ? "Mise à jour du suivi" : "Expédition de la commande"} onClose={() => setShippingModal(null)} preventClose={isSaving}>
                    <div className="space-y-4">
                        <div className="bg-blue-50 p-4 rounded-xl border border-blue-100 mb-4">
                            <p className="text-sm text-blue-800 font-medium">
                                {shippingModal.shipping_status === 'Expédié' 
                                    ? "Corrigez le numéro ou le lien de suivi. Le client recevra un e-mail avec les nouvelles informations."
                                    : "Saisissez les informations de suivi pour notifier le client. Le lien de suivi est obligatoire pour valider l'expédition."}
                            </p>
                        </div>
                        <div className="space-y-1">
                            <label className="text-xs font-bold text-slate-500 uppercase">Numéro de suivi *</label>
                            <input type="text" value={trackingData.number} onChange={e=>setTrackingData({...trackingData, number: e.target.value})} className="w-full border-2 border-slate-200 rounded-xl p-3 text-sm focus:border-blue-500 outline-none transition" placeholder="Ex : 6A123456789" />
                        </div>
                        <div className="space-y-1">
                            <label className="text-xs font-bold text-slate-500 uppercase">Lien de suivi transporteur *</label>
                            <input type="url" value={trackingData.link} onChange={e=>setTrackingData({...trackingData, link: e.target.value})} className="w-full border-2 border-slate-200 rounded-xl p-3 text-sm focus:border-blue-500 outline-none transition" placeholder="Ex : https://www.laposte.fr/outils/suivre-vos-envois?code=..." />
                        </div>
                        <div className="flex gap-3 mt-6">
                            <button onClick={() => setShippingModal(null)} disabled={isSaving} className="flex-1 py-3 bg-slate-100 text-slate-700 font-bold rounded-xl hover:bg-slate-200 transition disabled:opacity-50">Annuler</button>
                            <button onClick={() => updateShipping(shippingModal.id, 'Expédié', trackingData.number, trackingData.link)} disabled={isSaving || !trackingData.number.trim() || !trackingData.link.trim()} className="flex-1 py-3 bg-blue-600 text-white font-black uppercase tracking-widest rounded-xl hover:bg-blue-700 transition shadow-lg disabled:opacity-50">
                                {shippingModal.shipping_status === 'Expédié' ? "Mettre à jour" : "Confirmer l'expédition"}
                            </button>
                        </div>
                    </div>
                </window.Modal>
            )}

            {/* Modale Créditer Compte Client */}
            {creditModal && (
                <window.Modal title={`Créditer le compte : ${creditModal.clientName}`} onClose={() => setCreditModal(null)} preventClose={isSaving}>
                    <form onSubmit={handleAddCredit} className="space-y-4">
                        <div className="bg-emerald-50 text-emerald-800 p-4 rounded-xl border border-emerald-100 text-sm">
                            <strong>Ajout d'un crédit (bon d'achat)</strong><br/>
                            Ce montant sera ajouté au solde du client et déduit automatiquement de ses prochains achats ou abonnements.
                        </div>
                        <div>
                            <label className="block text-xs font-bold text-slate-500 uppercase mb-1">Montant à créditer (€)</label>
                            <input type="number" step="0.01" min="0.01" name="amount" required className="w-full border-2 border-slate-200 rounded-xl p-3 text-sm outline-none focus:border-emerald-500" placeholder="Ex: 50.00" />
                        </div>
                        <div>
                            <label className="block text-xs font-bold text-slate-500 uppercase mb-1">Motif (visible par le client)</label>
                            <input type="text" name="reason" required defaultValue="Geste commercial / Bon d'achat" className="w-full border-2 border-slate-200 rounded-xl p-3 text-sm outline-none focus:border-emerald-500" />
                        </div>
                        <div className="flex gap-3 pt-4">
                            <button type="button" onClick={() => setCreditModal(null)} className="flex-1 py-3 bg-slate-100 text-slate-700 font-bold rounded-xl hover:bg-slate-200">Annuler</button>
                            <button type="submit" disabled={isSaving} className="flex-1 py-3 bg-emerald-600 text-white font-black uppercase tracking-widest rounded-xl hover:bg-emerald-700 flex justify-center items-center gap-2">
                                {isSaving ? <Loader className="animate-spin" size={18}/> : <CheckCircle size={18}/>} Valider
                            </button>
                        </div>
                    </form>
                </window.Modal>
            )}

            {/* Modale Émettre Avoir / Rembourser Facture */}
            {refundModal && (
                <window.Modal title={`Avoir / remboursement - Réf. ${refundModal.invoice.invoiceNumber}`} onClose={() => setRefundModal(null)} preventClose={isSaving}>
                    <form onSubmit={handleRefund} className="space-y-4">
                        <div className="bg-orange-50 text-orange-800 p-4 rounded-xl border border-orange-100 text-sm">
                            <strong>Facture initiale : {refundModal.invoice.amount} €</strong><br/>
                            Générez une facture d'avoir (partielle ou totale) pour annuler comptablement cette transaction.
                        </div>
                        <div>
                            <label className="block text-xs font-bold text-slate-500 uppercase mb-1">Montant de l'avoir (€)</label>
                            <input type="number" step="0.01" min="0.01" max={refundModal.invoice.amount} defaultValue={refundModal.invoice.amount} name="amount" required className="w-full border-2 border-slate-200 rounded-xl p-3 text-sm outline-none focus:border-orange-500" />
                        </div>
                        <div>
                            <label className="block text-xs font-bold text-slate-500 uppercase mb-1">Méthode de restitution</label>
                            <select name="mode" className="w-full border-2 border-slate-200 rounded-xl p-3 text-sm outline-none focus:border-orange-500">
                                <option value="wallet">Crédit sur le site (Avoir déduit des prochains achats)</option>
                                <option value="manual">Remboursement direct (Manuel via tableau de bord Stripe)</option>
                            </select>
                        </div>
                        <div>
                            <label className="block text-xs font-bold text-slate-500 uppercase mb-1">Motif de l'annulation (visible sur l'avoir)</label>
                            <input type="text" name="reason" required defaultValue="Remboursement / Annulation" className="w-full border-2 border-slate-200 rounded-xl p-3 text-sm outline-none focus:border-orange-500" />
                        </div>
                        <div className="flex gap-3 pt-4">
                            <button type="button" onClick={() => setRefundModal(null)} className="flex-1 py-3 bg-slate-100 text-slate-700 font-bold rounded-xl hover:bg-slate-200">Annuler</button>
                            <button type="submit" disabled={isSaving} className="flex-1 py-3 bg-orange-600 text-white font-black uppercase tracking-widest rounded-xl hover:bg-orange-700 flex justify-center items-center gap-2">
                                {isSaving ? <Loader className="animate-spin" size={18}/> : <CheckCircle size={18}/>} Confirmer
                            </button>
                        </div>
                    </form>
                </window.Modal>
            )}

            {showTvaWarning && (
                <window.Modal title="Avertissement légal (émetteur)" onClose={() => setShowTvaWarning(false)}>
                    <div className="space-y-4">
                        <div className="bg-orange-50 text-orange-800 p-5 rounded-2xl border border-orange-200 text-sm leading-relaxed">
                            <p className="font-black mb-2 flex items-center gap-2"><AlertTriangle size={18}/> Exonération de TVA</p>
                            <p>En désactivant ce champ, vous indiquez que votre propre société (la plateforme eco-panneau) n'est pas assujettie à la TVA (ex : auto-entrepreneur).</p>
                            <p className="mt-2 font-bold">Conséquence immédiate :</p>
                            <ul className="list-disc pl-5 mt-1 space-y-1">
                                <li>Toutes vos futures factures seront émises <strong>sans TVA</strong> (Prix TTC = Prix HT).</li>
                                <li>La mention légale <em>"TVA non applicable, art. 293 B du CGI"</em> figurera sur les factures clients.</li>
                                <li>Les montants envoyés à Stripe ne seront plus majorés de 20%.</li>
                            </ul>
                        </div>
                        <div className="flex gap-3">
                            <button onClick={() => setShowTvaWarning(false)} className="flex-1 bg-slate-100 text-slate-700 py-3 rounded-xl font-bold hover:bg-slate-200 transition">Annuler</button>
                            <button onClick={confirmTvaExemption} className="flex-1 bg-emerald-600 text-white py-3 rounded-xl font-black uppercase tracking-widest hover:bg-emerald-700 transition shadow-lg">J'ai compris, désactiver la TVA</button>
                        </div>
                    </div>
                </window.Modal>
            )}

            {pwdRequest && (
                <window.Modal title={pwdRequest.title} onClose={() => setPwdRequest(null)} zIndex="z-[250]">
                    <div className="text-sm text-slate-600 mb-6 font-medium leading-relaxed">{pwdRequest.desc}</div>
                    <form onSubmit={(e) => {
                        e.preventDefault();
                        const pwd = e.target.pwd.value;
                        if(pwd) { pwdRequest.onConfirm(pwd); setPwdRequest(null); }
                    }}>
                        <input name="pwd" type="password" autoFocus required placeholder="Mot de passe administrateur..." className="w-full border-2 border-slate-200 rounded-xl p-3 text-sm focus:border-emerald-500 outline-none transition mb-4" />
                        <button type="submit" className="w-full bg-slate-900 text-white py-3 rounded-xl font-black uppercase tracking-widest hover:bg-slate-800 transition shadow-lg">Confirmer l'action</button>
                    </form>
                </window.Modal>
            )}

            {promptDialog && <window.PromptModal {...promptDialog} zIndex="z-[250]" onCancel={() => setPromptDialog(null)} />}
            {confirmDialog && <window.ConfirmModal {...confirmDialog} zIndex="z-[250]" onCancel={() => setConfirmDialog(null)} />}

            {/* Autres Modales Système... */}
            {modalView === 'diagnostics' && (
                <window.Modal title="Diagnostics système" onClose={() => setModalView(null)}>
                    {!diagnostics ? <div className="p-10 text-center"><Loader className="animate-spin inline-block text-emerald-600 mb-2" size={32}/><p className="text-slate-500 font-bold">Analyse complète en cours...</p></div> : (
                        <div className="space-y-3">
                            {diagnostics.map(d => (
                                <div key={d.id} className="flex justify-between items-center p-4 bg-slate-50 rounded-xl border border-slate-100">
                                    <div><p className="font-bold text-sm text-slate-800">{d.label}</p><p className="text-xs text-slate-500">{d.status}</p></div>
                                    <span className="font-mono text-sm font-black text-slate-700 bg-white px-3 py-1 rounded shadow-sm">{d.detail}</span>
                                </div>
                            ))}
                        </div>
                    )}
                </window.Modal>
            )}

            {modalView === 'logs' && (
                <window.Modal title="Logs d'erreurs (PHP)" onClose={() => setModalView(null)}>
                    <button onClick={clearLogs} className="w-full bg-red-50 text-red-600 py-3 rounded-xl font-bold flex justify-center items-center gap-2 hover:bg-red-100 transition mb-4"><Trash2 size={16}/> Vider les logs</button>
                    <div className="bg-slate-900 rounded-xl p-4 overflow-x-auto">
                        <pre className="text-[10px] text-emerald-400 font-mono whitespace-pre-wrap">{logs}</pre>
                    </div>
                </window.Modal>
            )}

            {modalView === 'backups' && (
                <window.Modal title="Gestion des sauvegardes système" onClose={() => setModalView(null)} preventClose={isLoadingBackups}>
                    <div className="space-y-4">
                        {isLoadingBackups ? (
                            <div className="py-12 text-center text-slate-500">
                                <Loader size={32} className="animate-spin inline-block mb-4 text-emerald-600"/>
                                <p className="text-sm font-bold uppercase tracking-widest">Chargement en cours...</p>
                            </div>
                        ) : (
                            <>
                                <button onClick={createBackup} disabled={isSaving} className="w-full bg-slate-900 text-white py-4 rounded-xl font-black uppercase tracking-widest shadow-lg flex items-center justify-center gap-3 hover:bg-slate-800 disabled:opacity-50 transition mb-6">
                                    {(isSaving || isLoadingBackups) ? <Loader size={20} className="animate-spin"/> : <Save size={20} className="text-emerald-400"/>} 
                                    {isSaving ? 'COMPRESSION...' : 'SAUVEGARDER LE SITE'}
                                </button>
                                
                                {backups.slice(0, showAllBackups ? backups.length : 5).map(b => (
                                    <div key={b.id} className="flex flex-col sm:flex-row sm:items-center justify-between p-4 bg-slate-50 border border-slate-200 rounded-xl gap-4">
                                        <div className="min-w-0">
                                            <div className="flex items-center gap-2 mb-1">
                                                <span className={`px-2 py-0.5 rounded-md text-[10px] font-black uppercase tracking-widest ${b.label === 'Automatique' ? 'bg-purple-100 text-purple-700' : 'bg-blue-100 text-blue-700'}`}>
                                                    {b.label === 'Automatique' ? 'CRON' : 'MANUEL'}
                                                </span>
                                                <p className="font-bold text-sm text-slate-800 truncate" title={decodeHTML(b.label)}>{decodeHTML(b.label)}</p>
                                            </div>
                                            <p className="text-xs text-slate-500">{new Date(b.date).toLocaleString('fr-FR')} • {b.size}</p>
                                        </div>
                                        <div className="flex gap-2 shrink-0">
                                            <a href={`?api=system/backups/download&file=${encodeURIComponent(b.name)}`} title="Télécharger l'archive" className="p-2 bg-blue-50 text-blue-600 rounded-lg hover:bg-blue-100 transition"><Download size={16}/></a>
                                            <button onClick={() => restoreBackup(b.name)} disabled={isSaving} title="Restaurer (Écraser la BDD actuelle)" className="p-2 bg-amber-50 text-amber-600 rounded-lg hover:bg-amber-100 transition disabled:opacity-50"><RefreshCw size={16}/></button>
                                            <button onClick={() => deleteBackup(b.name)} title="Supprimer définitivement" className="p-2 bg-red-50 text-red-600 rounded-lg hover:bg-red-100 transition"><Trash2 size={16}/></button>
                                        </div>
                                    </div>
                                ))}

                                {backups.length === 0 && <p className="text-center text-sm text-slate-500 py-6 italic">Aucune sauvegarde trouvée.</p>}
                                
                                {!showAllBackups && backups.length > 5 && (
                                    <button onClick={() => setShowAllBackups(true)} className="w-full py-3 bg-slate-100 text-slate-600 font-bold rounded-xl hover:bg-slate-200 transition mt-2 text-sm">
                                        Afficher tout ({backups.length - 5} de plus)
                                    </button>
                                )}
                            </>
                        )}
                    </div>
                </window.Modal>
            )}

            {isModalOpen && modalView === 'config_demo' && (
                <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-purple-50 shrink-0">
                            <div><h2 className="text-xl font-black text-purple-900">Édition du panneau démo</h2><p className="text-xs text-purple-700 font-medium">Panneau public vitrine.</p></div>
                            <button onClick={() => document.getElementById('editor-cancel-btn')?.click()} title="Fermer" className="text-slate-400 hover:bg-white hover:text-slate-700 p-2 rounded-xl border border-transparent hover:border-slate-200 transition"><window.X size={24}/></button>
                        </div>
                        <div className="flex-1 relative overflow-hidden">
                            <window.PanneauEditorForm 
                                panneau={managingPanneau} 
                                setPanneau={setManagingPanneau} 
                                managingPanneau={managingPanneau} 
                                onCancel={() => setIsModalOpen(false)} 
                                onSaveActive={handleSavePanneau} 
                                onEditEntity={(loc, data) => setEditingEntity({location: loc, data})} 
                                draggedItem={draggedItem} 
                                handleDragStart={handleDragStart} 
                                handleDragOver={handleDragOver} 
                                handleDrop={handleDrop} 
                                deleteEntity={deleteEntity} 
                                isSaving={isSaving} 
                                uiMode="professionnel" 
                            />
                        </div>
                        {editingEntity && <window.EntityEditorModal editingEntity={editingEntity} setEditingEntity={setEditingEntity} saveEditedEntity={saveEditedEntity} />}
                    </div>
                </div>
            )}

            {/* Modale d'Aperçu de panneau */}
            {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	============================ [_www/_react/_administrateur.jsx]
*/