// ECO-PANNEAU.FR - _react/admin/_admin_modals_system.jsx

window.pano_AdminModalsSystem = ({ activeModal, closeCurrentLayer, showToast, data, sysSummary = {}, refreshData, fetchTelemetry }) => {
    const { useState, useEffect } = React;
    const [isSaving, setIsSaving] = useState(false);
    const [isLoadingLogs, setIsLoadingLogs] = useState(false);

    // 1. - SÉCURITÉ ANTI-FUITE DE MÉMOIRE (Zéro-Dette)
    const { isMounted, safeFetch } = window.pano_useSafeFetch();
    
    const { openModal, replaceCurrentLayer } = window.pano_useUrlModal ? window.pano_useUrlModal() : {};

    // GESTION DU BOUTON RETOUR VERS LE CENTRE DE CONTRÔLE
    const handleBackToDiagnostics = () => {
        if (replaceCurrentLayer) replaceCurrentLayer('modal', 'diagnostics', null, false);
        else closeCurrentLayer();
    };

    // 2. - États
    const [codeStats, setCodeStats] = useState(null);
    const [statsMode, setStatsMode] = useState('source');
    const [sortConfig, setSortConfig] = useState({ key: 'path', direction: 'asc' });
    
    const [logTab, setLogTab] = useState('php');
    const [logs, setLogs] = useState('');
    const [diagnostics, setDiagnostics] = useState([]);
    
    const [juridiqueLogs, setJuridiqueLogs] = useState([]);
    const [juridiqueClientsMap, setJuridiqueClientsMap] = useState({});
    const [hasMoreLogs, setHasMoreLogs] = useState(false);
    
    const [jFilterClient, setJFilterClient] = useState('');
    const [jFilterKeyword, setJFilterKeyword] = useState('');
    
    // Zéro-Trust : Stockage temporaire de la clé confirm
    const [aesKeyConfirm, setAesKeyConfirm] = useState('');
    const [isAesKeyVerified, setIsAesKeyVerified] = useState(false);

    // 3. - Composants et Icônes
    const { Modal, Button, CardGrid, DataCard, IconBadge } = window.pano_getComponents();
    const { 
        ActivityIcon, TerminalIcon, FileDigitIcon, Trash2Icon, CopyIcon, 
        CheckCircleIcon, ShieldCheckIcon, SearchIcon, DownloadIcon, UserIcon, LoaderIcon, FileTextIcon, LockIcon, ArchiveIcon, RefreshCwIcon, ServerIcon
    } = window.pano_getIcons();

    // 4. - Chargement dynamique des données
    useEffect(() => {
        if (activeModal === 'code_stats') loadCodeStats();
        if (activeModal === 'logs') {
            if (logTab === 'php') loadLogs();
            if (logTab === 'juridique' && isAesKeyVerified) loadJuridiqueLogs();
        }
        if (activeModal === 'diagnostics') {
            loadDiagnostics(false); // Chargement initial
            
            // SUPERVISION EN TEMPS RÉEL (Auto-Refresh silencieux toutes les 10s)
            const diagInterval = setInterval(() => {
                if (isMounted.current) loadDiagnostics(true);
            }, 10000);
            return () => clearInterval(diagInterval);
        }
    // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [activeModal, statsMode, logTab, isAesKeyVerified]);

    const loadCodeStats = async () => {
        setCodeStats(null); 
        const d = await safeFetch(`system/code_stats&filter=${statsMode}`, { method: 'GET' });
        
        if (!isMounted.current) return; // Sécurité
        
        if (d && d.status === 'success') setCodeStats(d.data);
    };

    const loadLogs = async () => {
        const d = await safeFetch('system/logs', { method: 'GET' });
        
        if (!isMounted.current) return; // Sécurité
        
        if (d && d.status === 'success') setLogs(d.data?.logs || '');
    };
    
    const loadJuridiqueLogs = async (overrideClient = null) => {
        if (!isAesKeyVerified || !aesKeyConfirm) return;
        setIsLoadingLogs(true);
        
        const currentClient = overrideClient !== null ? overrideClient : jFilterClient;
        
        const payload = {
            aes_key_confirm: aesKeyConfirm,
            client: currentClient,
            keyword: jFilterKeyword
        };
        
        const d = await safeFetch('system/juridique_logs', { method: 'POST', body: payload });
        
        if (!isMounted.current) return; // Sécurité
        
        if (d && d.status === 'success') {
            setJuridiqueLogs(d.data.logs || []);
            setJuridiqueClientsMap(d.data.clients || {});
            setHasMoreLogs(d.data.has_more || false);
        } else {
             setIsAesKeyVerified(false);
             setAesKeyConfirm('');
        }
        setIsLoadingLogs(false);
    };

    const handleVerifyAesKey = async (e) => {
        e.preventDefault();
        setIsLoadingLogs(true);
        
        const payload = {
            aes_key_confirm: aesKeyConfirm
        };
        
        const d = await safeFetch('system/juridique_logs', { method: 'POST', body: payload });
        
        if (!isMounted.current) return; // Sécurité
        
        if (d && d.status === 'success') {
            setIsAesKeyVerified(true);
            setJuridiqueLogs(d.data.logs || []);
            setJuridiqueClientsMap(d.data.clients || {});
            setHasMoreLogs(d.data.has_more || false);
            if (window.pano_showToast) window.pano_showToast("Accès au registre déverrouillé.", "success");
        } else {
             setAesKeyConfirm('');
        }
        setIsLoadingLogs(false);
    };

    const loadDiagnostics = async (isSilent = false) => {
        const options = { method: 'GET' };
        if (isSilent) {
            options.headers = { 'x-silent': '1' }; // Empêche l'affichage du Loader global pour l'UX
        }

        // CORRECTION SÉCURITÉ & UX : Ajout d'un cache-buster pour empêcher le navigateur de figer la réponse
        const d = await safeFetch(`system/diagnostics&_t=${Date.now()}`, options);
        
        if (!isMounted.current) return; // Sécurité
        
        if (d && d.status === 'success') {
            const apiDiags = d.data || [];
            
            const adminSettings = data?.settings || {};
            // CORRECTION: Validation souple des valeurs numériques ou string "0"/"1"
            const isBillingComplete = !!(
                adminSettings.billing_company?.trim() && 
                adminSettings.billing_address?.trim() && 
                adminSettings.billing_siret?.trim() &&
                (adminSettings.billing_has_tva == 0 || adminSettings.billing_tva?.trim())
            );
            const isMaintenance = adminSettings.maintenance == 1;
            const purchasesAllowed = adminSettings.allow_new_purchases != 0;

            const localDiags = [
                {
                    name: "Mode maintenance",
                    status: isMaintenance ? 'error' : 'success',
                    detail: isMaintenance ? 'Site hors ligne' : 'Désactivé'
                },
                {
                    name: "Prise de commandes",
                    status: purchasesAllowed ? 'success' : 'warning',
                    detail: purchasesAllowed ? 'Autorisée' : 'Suspendue'
                },
                {
                    name: "Profil de facturation",
                    status: isBillingComplete ? 'success' : 'error',
                    detail: isBillingComplete ? 'Conforme' : 'Incomplet'
                }
            ];

            setDiagnostics([...localDiags, ...apiDiags]);
        }
    };

    // 5. - Actions métiers (Journaux et PDF)
    const handleClearLogs = async () => {
        const d = await safeFetch('system/logs/clear', {
            method: 'POST',
            setLoading: setIsSaving,
            successMessage: "Journaux purgés."
        });
        
        if (!isMounted.current) return; // Sécurité
        
        if (d) setLogs('');
    };

    const handleCopyLogs = () => {
        navigator.clipboard.writeText(logs);
        if (window.pano_showToast) window.pano_showToast("Journaux copiés dans le presse-papiers.", "success");
    };
    
    const generateJuridiquePDF = async () => {
        setIsSaving(true);
        try {
            const jsPDF = window.jspdf ? window.jspdf.jsPDF : null;
            if (!jsPDF) throw new Error("Bibliothèque PDF introuvable.");
            
            const doc = new jsPDF({ orientation: 'landscape', unit: 'mm', format: 'a4' });
            
            const loadFont = async (fontName, fontStyle, url) => {
                const cacheKey = `${fontName}-${fontStyle}`;
                let base64 = window.pano_CONFIG?.pdfFontsCache?.[cacheKey];
                
                if (!base64) {
                    const resp = await fetch(url, { headers: { 'x-silent': '1' } });
                    const buffer = await resp.arrayBuffer();
                    let binary = ''; 
                    const bytes = new Uint8Array(buffer);
                    for (let i = 0; i < bytes.byteLength; i++) binary += String.fromCharCode(bytes[i]); 
                    base64 = window.btoa(binary);
                    if (!window.pano_CONFIG) window.pano_CONFIG = {};
                    if (!window.pano_CONFIG.pdfFontsCache) window.pano_CONFIG.pdfFontsCache = {};
                    window.pano_CONFIG.pdfFontsCache[cacheKey] = base64;
                }
                const fileName = `${cacheKey}.ttf`;
                doc.addFileToVFS(fileName, base64);
                doc.addFont(fileName, fontName, fontStyle);
            };

            const assetsUrl = (window.pano_CONFIG && window.pano_CONFIG.assetsUrl) ? window.pano_CONFIG.assetsUrl : '_assets/';
            
            await Promise.all([
                loadFont("Roboto", "normal", window.pano_CONFIG?.fonts?.robotoRegular || (assetsUrl + "roboto/Roboto-Regular.ttf")),
                loadFont("Roboto", "bold", window.pano_CONFIG?.fonts?.robotoMedium || (assetsUrl + "roboto/Roboto-Medium.ttf"))
            ]);

            if (!isMounted.current) return;

            const mainFont = "Roboto";
            
            const splitLongText = (text, maxWidth) => {
                const initialLines = doc.splitTextToSize(text, maxWidth);
                const result = [];
                initialLines.forEach(line => {
                    if (doc.getTextWidth(line) > maxWidth) {
                        let currentLine = '';
                        for (let i = 0; i < line.length; i++) {
                            if (doc.getTextWidth(currentLine + line[i]) > maxWidth && currentLine.length > 0) {
                                result.push(currentLine);
                                currentLine = line[i];
                            } else {
                                currentLine += line[i];
                            }
                        }
                        if (currentLine) result.push(currentLine);
                    } else {
                        result.push(line);
                    }
                });
                return result;
            };

            let y = 10;
            
            const addNewPage = () => {
                doc.addPage();
                y = 10;
                doc.setFont(mainFont, "bold");
                doc.setFontSize(10);
                doc.setTextColor(255, 255, 255);
                doc.setFillColor(15, 23, 42);
                doc.rect(10, y, 277, 8, 'F');
                doc.text("Date", 12, y + 5.5);
                doc.text("Type", 35, y + 5.5);
                doc.text("Client concerné", 60, y + 5.5);
                doc.text("Détails / Actions", 110, y + 5.5);
                y += 12;
            };

            doc.setFont(mainFont, "bold");
            doc.setFontSize(18);
            doc.setTextColor(15, 23, 42);
            doc.text("Registre d'audit eco-panneau.fr", 10, y + 5);
            y += 12;
            
            doc.setFontSize(10);
            doc.setFont(mainFont, "normal");
            doc.setTextColor(71, 85, 105);
            const generationDateStr = new Date().toLocaleString('fr-FR');
            doc.text(`Document généré le : ${generationDateStr}`, 10, y);
            y += 6;
            
            if (jFilterClient) {
                const cInfo = juridiqueClientsMap[jFilterClient];
                const cTitle = cInfo ? `${cInfo.name} ${cInfo.email ? `(${cInfo.email})` : ''} ${!cInfo.active ? '(Compte supprimé)' : ''}` : jFilterClient;
                doc.text(`Filtre Client : ${cTitle}`, 10, y);
                y += 6;
            }
            if (jFilterKeyword) {
                doc.text(`Filtre Mots-clés : "${jFilterKeyword}"`, 10, y);
                y += 6;
            }
            y += 4;
            
            doc.setFont(mainFont, "bold");
            doc.setTextColor(255, 255, 255);
            doc.setFillColor(15, 23, 42);
            doc.rect(10, y, 277, 8, 'F');
            doc.text("Date", 12, y + 5.5);
            doc.text("Type", 35, y + 5.5);
            doc.text("Client concerné", 60, y + 5.5);
            doc.text("Détails / Actions", 110, y + 5.5);
            y += 12;

            if (juridiqueLogs.length === 0) {
                doc.setTextColor(100, 116, 139);
                doc.setFont(mainFont, "normal");
                doc.text("Aucun enregistrement trouvé pour ces critères.", 10, y + 5);
            } else {
                for (let i = 0; i < juridiqueLogs.length; i++) {
                    const log = juridiqueLogs[i];
                    
                    const cInfo = log.client_uid ? juridiqueClientsMap[log.client_uid] : null;
                    
                    let clientText = 'Système';
                    if (cInfo) {
                        const parts = [];
                        if (cInfo.name) parts.push(cInfo.name);
                        if (cInfo.full_name) parts.push(cInfo.full_name);
                        if (cInfo.email) parts.push(cInfo.email);
                        clientText = parts.join('\n');
                        if (!cInfo.active) clientText += '\n[Supprimé]';
                    }

                    const cleanContent = (log.content || '').replace(/[\u1000-\uFFFF]/g, '');
                    
                    const contentLines = splitLongText(cleanContent, 172);
                    const clientLines = splitLongText(clientText, 45);
                    const typeLines = splitLongText(log.type || 'Autre', 23);
                    
                    const maxLines = Math.max(2, typeLines.length, contentLines.length, clientLines.length);
                    const rowHeight = Math.max(8, maxLines * 4.0); 
                    
                    if (y + rowHeight > 195) {
                        addNewPage();
                    }
                    
                    doc.setTextColor(15, 23, 42);
                    doc.setFontSize(9);
                    doc.setFont(mainFont, "normal");
                    
                    const dateStr = new Date(log.date).toLocaleString('fr-FR');
                    const [datePart, timePart] = dateStr.split(' ');
                    doc.text(datePart, 12, y + 3);
                    if (timePart) doc.text(timePart, 12, y + 7);

                    doc.setFont(mainFont, "bold");
                    doc.text(typeLines, 35, y + 3);
                    doc.setFont(mainFont, "normal");
                    
                    if (cInfo && !cInfo.active) doc.setTextColor(220, 38, 38);
                    else doc.setTextColor(15, 23, 42);
                    
                    doc.text(clientLines, 60, y + 3);
                    
                    doc.setTextColor(71, 85, 105);
                    doc.text(contentLines, 110, y + 3);
                    
                    y += rowHeight + 2; 
                    doc.setDrawColor(226, 232, 240); 
                    doc.line(10, y, 287, y);
                    y += 2; 
                }
            }
            
            const pageCount = doc.internal.getNumberOfPages();
            doc.setFont(mainFont, "normal");
            doc.setFontSize(7);
            doc.setTextColor(148, 163, 184); 
            const generatedText = `Document généré le : ${generationDateStr}`;
            for (let i = 1; i <= pageCount; i++) {
                doc.setPage(i);
                if (i > 1) {
                    doc.text(generatedText, 6, 204);
                }
                doc.text(`page ${i} sur ${pageCount}`, 291, 204, { align: 'right' });
            }
            
            doc.save(`eco-panneau_registre_audit_${Date.now()}.pdf`);
            if (window.pano_showToast) window.pano_showToast("Rapport PDF généré avec succès.", "success");
            
        } catch (err) {
            if (window.pano_showToast) window.pano_showToast("Erreur lors de la génération du PDF : " + err.message, "error");
        } finally {
            if (isMounted.current) setIsSaving(false);
        }
    };

    // 6. - Tri de l'arborescence (Mode Risque)
    const getRiskScore = (f) => {
        if (f.valid === false && !f.protected) return 3;
        if (f.valid === false && f.protected) return 2;
        return 1;
    };

    const sortedFiles = React.useMemo(() => {
        if (!codeStats || !codeStats.details) return [];
        let sortableItems = [...codeStats.details];
        
        if (sortConfig !== null) {
            sortableItems.sort((a, b) => {
                let valA, valB;

                if (sortConfig.key === 'risk') {
                    valA = getRiskScore(a);
                    valB = getRiskScore(b);
                } else {
                    valA = a[sortConfig.key] !== undefined ? a[sortConfig.key] : '';
                    valB = b[sortConfig.key] !== undefined ? b[sortConfig.key] : '';
                    
                    if (typeof valA === 'string') valA = valA.toLowerCase();
                    if (typeof valB === 'string') valB = valB.toLowerCase();
                }

                if (valA < valB) return sortConfig.direction === 'asc' ? -1 : 1;
                if (valA > valB) return sortConfig.direction === 'asc' ? 1 : -1;
                
                const pathA = a.path ? a.path.toLowerCase() : '';
                const pathB = b.path ? b.path.toLowerCase() : '';
                if (pathA < pathB) return -1;
                if (pathA > pathB) return 1;

                return 0;
            });
        }
        return sortableItems;
    }, [codeStats, sortConfig]);

    const requestSort = (key) => {
        let direction = (key === 'lines' || key === 'chars' || key === 'risk') ? 'desc' : 'asc';
        
        if (sortConfig && sortConfig.key === key) {
            direction = sortConfig.direction === 'asc' ? 'desc' : 'asc';
        }
        setSortConfig({ key, direction });
    };

    const renderSortButton = (key, label) => {
        const isActive = sortConfig?.key === key;
        const icon = isActive ? (sortConfig.direction === 'asc' ? '↓' : '↑') : '';
        
        return (
            <button 
                onClick={() => requestSort(key)}
                className={`px-3 py-1.5 rounded-lg text-[10px] font-bold transition flex items-center gap-1.5 ${isActive ? 'bg-slate-800 text-white shadow-md' : 'bg-white text-slate-600 border border-slate-200 hover:bg-slate-50'}`}
            >
                {label} <span className="w-2.5 text-center">{icon}</span>
            </button>
        );
    };

    // 7. - Rendu UI
    const getVariant = (status) => !sysSummary.loaded ? 'default' : (status === 'emerald' ? 'success' : (status === 'amber' ? 'warning' : 'danger'));
    const backupVariant = getVariant(sysSummary.backupStatus);
    const logVariant = getVariant(sysSummary.logStatus);

    return (
        <>
            {activeModal === 'code_stats' && (
                <Modal 
                    title="Statistiques et droits" 
                    onClose={handleBackToDiagnostics} 
                    maxWidth="max-w-6xl"
                    tabs={[
                        { id: 'source', label: 'Code source' },
                        { id: 'no_clients', label: 'Hors fichiers clients' },
                        { id: 'full', label: 'Site complet' }
                    ]}
                    activeTab={statsMode}
                    onTabChange={setStatsMode}
                    actions={(close) => (
                        <Button variant="secondary" onClick={close} className="w-full py-3 justify-center text-xs">
                            Retour aux diagnostics
                        </Button>
                    )}
                >
                    {!codeStats ? (
                        <div className="p-12 text-center text-slate-400 animate-pulse font-bold tracking-widest uppercase text-sm break-words">Analyse de l'arborescence en cours...</div>
                    ) : (
                        <div className="space-y-4">
                            <CardGrid minWidth="130px">
                                <div className="bg-slate-50 p-3 rounded-xl border border-slate-200 text-center">
                                    <p className="text-lg font-black text-slate-800 break-words leading-none">{(codeStats.total_lines || 0).toLocaleString('fr-FR')}</p>
                                    <p className="text-[9px] font-bold uppercase tracking-widest text-slate-500 mt-1 break-words">Lignes analysées</p>
                                </div>
                                <div className="bg-slate-50 p-3 rounded-xl border border-slate-200 text-center">
                                    <p className="text-lg font-black text-slate-800 break-words leading-none">{(codeStats.total_chars || 0).toLocaleString('fr-FR')}</p>
                                    <p className="text-[9px] font-bold uppercase tracking-widest text-slate-500 mt-1 break-words">Caractères</p>
                                </div>
                                <div className="bg-slate-50 p-3 rounded-xl border border-slate-200 text-center">
                                    <p className="text-lg font-black text-slate-800 break-words leading-none">{(codeStats.total_files || 0).toLocaleString('fr-FR')}</p>
                                    <p className="text-[9px] font-bold uppercase tracking-widest text-slate-500 mt-1 break-words">Fichiers trouvés</p>
                                </div>
                                <div className="bg-slate-50 p-3 rounded-xl border border-slate-200 text-center">
                                    <p className="text-lg font-black text-slate-800 break-words leading-none">{((codeStats.total_chars || 0) / 1024 / 1024).toFixed(2)} Mo</p>
                                    <p className="text-[9px] font-bold uppercase tracking-widest text-slate-500 mt-1 break-words">Poids du code lu</p>
                                </div>
                            </CardGrid>

                            <div className="bg-slate-50 p-3 rounded-xl border border-slate-200 flex flex-col sm:flex-row gap-3 items-center justify-between">
                                <span className="text-[10px] font-bold text-slate-500 uppercase tracking-widest break-words text-center sm:text-left">Trier l'arborescence :</span>
                                <div className="flex flex-wrap gap-1.5 justify-center">
                                    {renderSortButton('path', 'Chemin')}
                                    {renderSortButton('risk', 'Risque')}
                                    {renderSortButton('lines', 'Lignes')}
                                    {renderSortButton('chars', 'Taille')}
                                </div>
                            </div>

                            <div className="h-[50vh] overflow-y-auto custom-scrollbar pr-2 pb-2">
                                <CardGrid minWidth="240px">
                                    {sortedFiles.map((f, i) => {
                                        const isError = f.valid === false && !f.protected;
                                        const isProtectedWrongPerms = f.valid === false && f.protected;

                                        return (
                                        <div 
                                            key={i} 
                                            className={`p-3 rounded-xl border transition shadow-sm flex flex-col h-full min-w-0 ${isError ? 'bg-red-50 border-red-300' : 'bg-white border-slate-200 hover:border-blue-300 hover:shadow-md'}`}
                                            title={isError ? `Vulnérabilité détectée.` : ''}
                                        >
                                            <div className="flex gap-2 items-start min-w-0 w-full">
                                                <span className="text-lg shrink-0 leading-none mt-0.5">{f.type === 'dir' ? '📁' : '📄'}</span>
                                                <div className="min-w-0 flex-1">
                                                    <p className={`text-xs font-bold break-all whitespace-normal leading-tight min-w-0 ${f.type === 'dir' ? 'text-blue-700' : 'text-slate-700'}`}>
                                                        {f.path}
                                                    </p>
                                                </div>
                                            </div>
                                            
                                            <div className="flex flex-wrap items-center justify-between gap-3 mt-auto pt-3 border-t border-slate-100 min-w-0 w-full">
                                                <div className="flex flex-wrap items-center gap-1.5 min-w-0">
                                                    <span 
                                                        className={`px-1.5 py-0.5 rounded font-black font-mono text-[9px] border shrink-0 ${isError ? 'bg-red-100 text-red-800 border-red-300 cursor-help' : (isProtectedWrongPerms ? 'bg-amber-50 text-amber-600 border-amber-200 cursor-help' : 'bg-slate-100 text-slate-500 border-slate-200')}`} 
                                                        title={isError || isProtectedWrongPerms ? `À corriger manuellement. Actuel: ${f.perms} - Requis: ${f.expected}` : 'Permissions correctes'}
                                                    >
                                                        {f.perms || '-'}
                                                    </span>
                                                    {f.type === 'dir' && f.htaccess && (
                                                        <span 
                                                            className={`text-[8px] px-1.5 py-0.5 rounded font-bold uppercase tracking-widest border shrink-0 ${f.htaccess_deny ? 'bg-amber-100 text-amber-700 border-amber-200' : 'bg-blue-100 text-blue-700 border-blue-200'}`} 
                                                            title={f.htaccess_deny ? "Accès Web bloqué (Require all denied)" : "Règles .htaccess présentes"}
                                                        >
                                                            {f.htaccess_deny ? '🔒 Deny' : '📄 Règles'}
                                                        </span>
                                                    )}
                                                    {(f.protected && !f.htaccess_deny) && (
                                                        <span 
                                                            className="text-[8px] px-1.5 py-0.5 rounded font-bold uppercase tracking-widest border shrink-0 bg-slate-50 text-slate-400 border-slate-200" 
                                                            title="Fichier protégé de l'accès public par un dossier parent ou car il est hors de la racine Web."
                                                        >
                                                            🔒 Protégé
                                                        </span>
                                                    )}
                                                </div>
                                                
                                                {f.type !== 'dir' && f.lines > 0 && (
                                                    <div className="flex items-center gap-2 text-[10px] font-mono text-slate-500 shrink-0">
                                                        <span title={window.pano_formatPlural ? window.pano_formatPlural(f.lines || 0, 'Ligne', 'Lignes') : 'Lignes'}>📝 {(f.lines || 0).toLocaleString('fr-FR')}</span>
                                                        <span title={window.pano_formatPlural ? window.pano_formatPlural(f.chars || 0, 'Caractère', 'Caractères') : 'Caractères'}>🔡 {(f.chars || 0).toLocaleString('fr-FR')}</span>
                                                    </div>
                                                )}
                                            </div>
                                        </div>
                                    )})}
                                </CardGrid>
                            </div>
                        </div>
                    )}
                </Modal>
            )}

            {activeModal === 'logs' && (
                <Modal 
                    title="Journaux système et d'audit" 
                    onClose={handleBackToDiagnostics} 
                    maxWidth="max-w-5xl"
                    tabs={[
                        { id: 'php', label: 'Erreurs PHP' },
                        { id: 'juridique', label: 'Registre juridique' }
                    ]}
                    activeTab={logTab}
                    onTabChange={setLogTab}
                    actions={(close) => (
                        <Button variant="secondary" onClick={close} className="w-full py-3 justify-center text-xs">
                            Retour aux diagnostics
                        </Button>
                    )}
                >
                    {logTab === 'php' ? (
                        <div className="space-y-4">
                            <div className="flex flex-col sm:flex-row sm:justify-between sm:items-center gap-3">
                                <p className="text-sm text-slate-500 break-words leading-relaxed">Trace technique des erreurs et alertes serveur.</p>
                                <div className="flex gap-2 shrink-0">
                                    <Button variant="secondary" icon={CopyIcon} onClick={handleCopyLogs} disabled={!logs} className="py-2.5">Copier</Button>
                                    <Button variant="danger" shape="round" icon={Trash2Icon} onClick={handleClearLogs} disabled={isSaving || !logs} title="Purger les journaux" className="p-2.5 shadow-none border-none hover:bg-red-50" />
                                </div>
                            </div>
                            
                            <pre className="bg-slate-900 text-emerald-400 p-4 rounded-2xl font-mono text-xs overflow-y-auto h-[50vh] w-full custom-scrollbar whitespace-pre-wrap break-all shadow-inner leading-relaxed block">
                                {logs || "Aucune erreur enregistrée dans le journal (fichier error_log vide)."}
                            </pre>
                        </div>
                    ) : (
                        <div className="space-y-4">
                            {!isAesKeyVerified ? (
                                <div className="flex flex-col items-center justify-center py-12 px-4 bg-slate-50 border border-slate-200 rounded-2xl">
                                    <LockIcon size={48} className="text-slate-400 mb-4" />
                                    <h3 className="text-lg font-black text-slate-800 mb-2 text-center">Déverrouillage requis</h3>
                                    <p className="text-sm text-slate-500 mb-6 text-center max-w-md">L'accès au registre d'audit est protégé par chiffrement fort (Zero-Trust). Veuillez saisir votre clé de confirmation pour y accéder.</p>
                                    <form onSubmit={handleVerifyAesKey} className="w-full max-w-md flex flex-col gap-3">
                                        <input 
                                            type="password"
                                            value={aesKeyConfirm}
                                            onChange={e => setAesKeyConfirm(e.target.value)}
                                            placeholder="AES_KEY_CONFIRM"
                                            className="w-full border border-slate-300 rounded-xl p-3 font-mono text-sm focus:border-blue-500 outline-none text-center"
                                            required
                                        />
                                        <Button type="submit" variant="dark" disabled={isLoadingLogs || !aesKeyConfirm} icon={isLoadingLogs ? LoaderIcon : ShieldCheckIcon} className="w-full justify-center py-3">
                                            {isLoadingLogs ? 'Vérification...' : 'Déverrouiller le registre'}
                                        </Button>
                                    </form>
                                </div>
                            ) : (
                                <>
                                    <form onSubmit={(e) => { e.preventDefault(); loadJuridiqueLogs(); }} className="flex flex-col lg:flex-row gap-3 mb-4 bg-slate-50 p-3 rounded-xl border border-slate-200">
                                        <select 
                                            value={jFilterClient} 
                                            onChange={e => {
                                                const val = e.target.value;
                                                setJFilterClient(val);
                                                loadJuridiqueLogs(val);
                                            }}
                                            className="border border-slate-300 rounded-lg p-2.5 text-sm font-bold text-slate-700 focus:border-blue-500 outline-none flex-1 bg-white"
                                        >
                                            <option value="">Tous les clients</option>
                                            {Object.entries(juridiqueClientsMap).map(([uid, info]) => (
                                                <option key={uid} value={uid}>
                                                    {info.name} {info.email ? `(${info.email})` : ''} {!info.active ? '[Compte supprimé]' : ''}
                                                </option>
                                            ))}
                                        </select>
                                        <div className="relative flex-1">
                                            {SearchIcon && <SearchIcon size={18} className="absolute left-3 top-1/2 -translate-y-1/2 text-slate-400" />}
                                            <input 
                                                type="text" 
                                                value={jFilterKeyword} 
                                                onChange={e => setJFilterKeyword(e.target.value)} 
                                                placeholder="Filtrer par mot-clé (ex: suppression)..."
                                                className="w-full border border-slate-300 rounded-lg p-2.5 pl-10 text-sm font-bold text-slate-700 focus:border-blue-500 outline-none"
                                            />
                                        </div>
                                        <Button type="submit" variant="dark" icon={isLoadingLogs ? LoaderIcon : CheckCircleIcon} disabled={isLoadingLogs} className="shrink-0 py-2.5 shadow-md">
                                            <span className="hidden sm:inline">Valider</span>
                                        </Button>
                                    </form>

                                    <div className="flex flex-col sm:flex-row justify-between items-center gap-4 mb-4 pb-4 border-b border-slate-200">
                                        <div className="text-sm font-bold text-slate-700">
                                            {window.pano_formatPlural(juridiqueLogs.length, 'résultat affiché', 'résultats affichés')}
                                        </div>
                                        <div className="flex gap-2 w-full sm:w-auto shrink-0">
                                            <Button 
                                                variant="secondary" 
                                                icon={isSaving ? LoaderIcon : DownloadIcon} 
                                                onClick={() => {
                                                    let exportUrl = window.pano_CONFIG.apiBaseUrl + 'system/juridique_logs/export_csv';
                                                    exportUrl += `&aes_key_confirm=${encodeURIComponent(aesKeyConfirm)}`;
                                                    if (jFilterClient) exportUrl += '&client=' + encodeURIComponent(jFilterClient);
                                                    if (jFilterKeyword) exportUrl += '&keyword=' + encodeURIComponent(jFilterKeyword);
                                                    window.location.href = exportUrl;
                                                }} 
                                                disabled={isSaving} 
                                                className="flex-1 sm:flex-none py-2.5 shadow-sm bg-white text-xs"
                                                title="Exporter l'intégralité du registre en CSV (Supporte +50 000 lignes)"
                                            >
                                                Export CSV (Total)
                                            </Button>

                                            {!hasMoreLogs && juridiqueLogs.length > 0 && (
                                                <Button 
                                                    variant="primary" 
                                                    icon={isSaving ? LoaderIcon : FileTextIcon} 
                                                    onClick={generateJuridiquePDF} 
                                                    disabled={isSaving} 
                                                    className="flex-1 sm:flex-none py-2.5 shadow-md text-xs"
                                                    title="Générer un PDF de la vue filtrée actuelle"
                                                >
                                                    Rapport PDF
                                                </Button>
                                            )}
                                        </div>
                                    </div>
                                    
                                    <div className="bg-slate-50 border border-slate-200 rounded-xl h-[50vh] overflow-y-auto custom-scrollbar p-3 space-y-3 relative">
                                        {isLoadingLogs ? (
                                            <div className="absolute inset-0 bg-white/50 backdrop-blur-sm z-10 flex items-center justify-center rounded-xl">
                                                <LoaderIcon size={32} className="animate-spin text-emerald-600" />
                                            </div>
                                        ) : null}

                                        {juridiqueLogs.length === 0 ? (
                                            <div className="p-8 text-center text-slate-500 italic text-sm">Aucun enregistrement trouvé pour ces critères.</div>
                                        ) : (
                                            <>
                                                {juridiqueLogs.map((log, i) => {
                                                    const cInfo = log.client_uid ? juridiqueClientsMap[log.client_uid] : null;
                                                    return (
                                                        <div key={i} className="bg-white p-4 rounded-xl border border-slate-100 shadow-sm flex flex-col gap-2 transition hover:border-blue-200">
                                                            <div className="flex justify-between items-start gap-4">
                                                                <span className={`text-[10px] font-black tracking-widest px-2 py-0.5 rounded uppercase shrink-0 ${log.type === 'RGPD' ? 'bg-purple-100 text-purple-700' : (log.type === 'Modération' ? 'bg-amber-100 text-amber-700' : (log.type === 'Comptabilité' ? 'bg-emerald-100 text-emerald-700' : (log.type === 'Sécurité' ? 'bg-red-100 text-red-700' : 'bg-blue-100 text-blue-700')))}`}>
                                                                    {log.type || 'Autre'}
                                                                </span>
                                                                <span className="text-[10px] font-mono font-bold text-slate-400 shrink-0 bg-slate-50 px-2 py-0.5 rounded">
                                                                    {new Date(log.date).toLocaleString('fr-FR')}
                                                                </span>
                                                            </div>
                                                            <p className="text-sm text-slate-700 font-medium break-words leading-relaxed">{log.content}</p>
                                                            {cInfo && (
                                                                <div className="mt-2 pt-2 border-t border-slate-50 text-[10px] flex flex-col gap-0.5 font-bold">
                                                                    <div className="flex items-center gap-1.5">
                                                                        {UserIcon && <UserIcon size={12} className="text-slate-400" />}
                                                                        <span className="text-slate-500">Client :</span> 
                                                                        <span className={cInfo.active ? "text-slate-700" : "text-red-600 line-through"}>
                                                                            {cInfo.name} {cInfo.full_name ? `(${cInfo.full_name})` : ''}
                                                                        </span>
                                                                        {!cInfo.active && <span className="text-red-500 font-black ml-1">[Supprimé]</span>}
                                                                    </div>
                                                                    {cInfo.email && <div className="text-slate-400 ml-5">{cInfo.email}</div>}
                                                                </div>
                                                            )}
                                                        </div>
                                                    );
                                                })}

                                                {hasMoreLogs && (
                                                    <div className="p-5 mt-4 bg-blue-50 border border-blue-200 rounded-xl text-center shadow-inner">
                                                        <p className="text-sm text-blue-900 font-black mb-1">L'affichage est limité aux 500 résultats les plus récents.</p>
                                                        <p className="text-xs text-blue-700 font-medium">Pour consulter l'intégralité des enregistrements correspondant à votre recherche, veuillez télécharger le registre complet au format CSV.</p>
                                                    </div>
                                                )}
                                            </>
                                        )}
                                    </div>
                                </>
                            )}
                        </div>
                    )}
                </Modal>
            )}

            {activeModal === 'diagnostics' && (
                <Modal 
                    title="Diagnostics système" 
                    onClose={closeCurrentLayer} 
                    maxWidth="max-w-4xl"
                    actions={(close) => (
                        <Button variant="secondary" onClick={close} className="w-full py-3 justify-center text-xs">
                            Fermer
                        </Button>
                    )}
                >
                    <div className="space-y-8">
                        <div className="space-y-4">
                            <h2 className="text-lg font-black text-slate-800 flex items-center gap-2 border-b border-slate-200 pb-2">
                                <ActivityIcon size={20} className="text-blue-600" /> État de santé
                            </h2>
                            <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
                                {diagnostics.length > 0 ? diagnostics.map((d, i) => {
                                    let currentStatus = d.status;
                                    let currentDetail = d.detail;

                                    let statusColor = 'text-emerald-500';
                                    if (currentStatus === 'info') statusColor = 'text-blue-500';
                                    if (currentStatus === 'warning') statusColor = 'text-amber-500';
                                    if (currentStatus === 'error') statusColor = 'text-red-500';

                                    return (
                                        <div key={i} className="flex flex-col sm:flex-row justify-between sm:items-center p-4 bg-slate-50 border border-slate-200 rounded-2xl gap-2 transition hover:border-emerald-200 min-w-0">
                                            <div className="min-w-0">
                                                <p className="font-bold text-slate-800 text-sm flex items-center gap-2 break-words leading-tight">
                                                    {d.name || d.label}
                                                    {(currentStatus === 'success' || currentStatus === 'Opérationnel') && <CheckCircleIcon size={14} className={`shrink-0 ${statusColor}`} />}
                                                    {(currentStatus !== 'success' && currentStatus !== 'Opérationnel') && <ActivityIcon size={14} className={`shrink-0 ${statusColor}`} />}
                                                </p>
                                            </div>
                                            <div className="text-left sm:text-right shrink-0">
                                                <p className={`font-mono text-sm font-bold break-words leading-tight ${statusColor}`}>{currentDetail}</p>
                                            </div>
                                        </div>
                                    );
                                }) : (
                                    <div className="col-span-1 md:col-span-2 p-8 text-center text-slate-500 animate-pulse font-medium uppercase tracking-widest text-xs">Récupération des diagnostics...</div>
                                )}
                            </div>
                        </div>

                        <div className="space-y-4">
                            <h2 className="text-lg font-black text-slate-800 flex items-center gap-2 border-b border-slate-200 pb-2">
                                <TerminalIcon size={20} className="text-emerald-600" /> Serveur et maintenance
                            </h2>
                            <CardGrid minWidth="280px">
                                <DataCard variant={backupVariant} onClick={(e) => { replaceCurrentLayer('modal', 'backups', null, false); }} className="cursor-pointer group hover:scale-[1.02] transition-transform min-w-0">
                                    <div className="flex items-center gap-3 min-w-0">
                                        <IconBadge icon={ArchiveIcon} variant={backupVariant === 'default' ? 'secondary' : backupVariant} size="md" className="shrink-0" />
                                        <div className="min-w-0 flex-1">
                                            <p className={`font-bold text-sm break-words leading-tight ${backupVariant === 'danger' ? 'text-red-900' : (backupVariant === 'warning' ? 'text-amber-900' : (backupVariant === 'success' ? 'text-emerald-900' : 'text-slate-800'))}`}>Sauvegardes système</p>
                                            <p className={`text-[10px] mt-0.5 break-words leading-tight ${backupVariant === 'danger' ? 'text-red-700' : (backupVariant === 'warning' ? 'text-amber-700' : (backupVariant === 'success' ? 'text-emerald-700' : 'text-slate-500'))}`}>
                                                {sysSummary.loaded ? sysSummary.backupDesc : 'Vérification...'}
                                            </p>
                                        </div>
                                    </div>
                                </DataCard>

                                <DataCard variant={logVariant} onClick={(e) => { replaceCurrentLayer('modal', 'logs', null, false); }} className="cursor-pointer group hover:scale-[1.02] transition-transform min-w-0">
                                    <div className="flex items-center gap-3 min-w-0">
                                        <IconBadge icon={TerminalIcon} variant={logVariant === 'default' ? 'secondary' : logVariant} size="md" className="shrink-0" />
                                        <div className="min-w-0 flex-1">
                                            <p className={`font-bold text-sm break-words leading-tight ${logVariant === 'danger' ? 'text-red-900' : (logVariant === 'warning' ? 'text-amber-900' : (logVariant === 'success' ? 'text-emerald-900' : 'text-slate-800'))}`}>Journaux et Registre</p>
                                            <p className={`text-[10px] mt-0.5 break-words leading-tight ${logVariant === 'danger' ? 'text-red-700' : (logVariant === 'warning' ? 'text-amber-700' : (logVariant === 'success' ? 'text-emerald-700' : 'text-slate-500'))}`}>
                                                {sysSummary.loaded ? sysSummary.logDesc : 'Chargement...'} (Erreurs et Légal)
                                            </p>
                                        </div>
                                    </div>
                                </DataCard>

                                <DataCard variant="info" onClick={(e) => { replaceCurrentLayer('modal', 'code_stats', null, false); }} className="cursor-pointer group hover:scale-[1.02] transition-transform min-w-0">
                                    <div className="flex items-center gap-3 min-w-0">
                                        <IconBadge icon={FileDigitIcon} variant="info" size="md" className="shrink-0" />
                                        <div className="min-w-0 flex-1">
                                            <p className="font-bold text-sm break-words leading-tight text-blue-900">Statistiques du code</p>
                                            <p className="text-[10px] mt-0.5 break-words leading-tight text-blue-700">Analyse des fichiers et droits</p>
                                        </div>
                                    </div>
                                </DataCard>
                            </CardGrid>
                        </div>

                        <div className="space-y-4">
                            <h2 className="text-lg font-black text-slate-800 flex items-center gap-2 border-b border-slate-200 pb-2">
                                <ServerIcon size={20} className="text-purple-600" /> Moteur asynchrone (CRON)
                            </h2>
                            <p className="text-sm text-slate-600 font-medium break-words mb-2">Exécution manuelle forcée des tâches planifiées :</p>
                            <CardGrid minWidth="280px">
                                <DataCard variant="default" className="cursor-pointer group hover:border-blue-400 transition-transform min-w-0" onClick={async () => {
                                    const d = await safeFetch('system/cron_cleanup&mode=light', { method: 'GET', setLoading: setIsSaving, successMessage: "CRON courant exécuté avec succès." });
                                    if (!isMounted.current) return;
                                    if (d) {
                                        if (refreshData && fetchTelemetry) { refreshData(); fetchTelemetry(true); }
                                        loadDiagnostics(true); // Rafraîchissement direct avec Cache-Buster
                                    }
                                }}>
                                    <div className="flex items-start gap-4 min-w-0">
                                        <IconBadge icon={RefreshCwIcon} variant="info" size="md" className="shrink-0" />
                                        <div className="min-w-0 flex-1">
                                            <h4 className="font-black text-slate-800 text-sm break-words leading-tight">CRON Courant (Rapide)</h4>
                                            <p className="text-xs text-slate-500 mt-1 leading-relaxed break-words">Traite les e-mails en attente, les notifications push et relance les invitations. (Exécution immédiate)</p>
                                        </div>
                                    </div>
                                </DataCard>
                                
                                <DataCard variant="default" className="cursor-pointer group hover:border-purple-400 transition-transform min-w-0" onClick={async () => {
                                    const d = await safeFetch('system/cron_cleanup&mode=full', { method: 'GET', setLoading: setIsSaving, successMessage: "CRON complet exécuté avec succès." });
                                    if (!isMounted.current) return; // SÉCURITÉ
                                    if (d) {
                                        if (refreshData && fetchTelemetry) { refreshData(); fetchTelemetry(true); }
                                        loadDiagnostics(true); // Rafraîchissement direct avec Cache-Buster
                                    }
                                }}>
                                    <div className="flex items-start gap-4 min-w-0">
                                        <IconBadge icon={ServerIcon} variant="purple" size="md" className="shrink-0" />
                                        <div className="min-w-0 flex-1">
                                            <h4 className="font-black text-slate-800 text-sm break-words leading-tight">CRON Complet (Lourd)</h4>
                                            <p className="text-xs text-slate-500 mt-1 leading-relaxed break-words">Version courante + Nettoyage de la BDD, purge des brouillons expirés, purges RGPD et sauvegarde globale.</p>
                                        </div>
                                    </div>
                                </DataCard>
                            </CardGrid>
                        </div>
                    </div>
                </Modal>
            )}
        </>
    );
};

/* EOF ========== [_react/admin/_admin_modals_system.jsx] */