/**
 * =========================================================================
 * PLATEFORME ECO-PANNEAU.FR - VERSION 1.0.0
 * Interface Administrateur - Onglet Tableau de bord (Supervision)
 * =========================================================================
 */

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

window.AdminDashboardTab = ({ data, refreshData, showToast, setActiveTab, openLocalModal, openLocalDialog, closeCurrentLayer, activeModal, activeDialog, targetId }) => {
    const { useState, useEffect, useMemo } = React;
    
    // FACTORISATION : Utilisation du Hook global de gestion des modales par URL
    const { activeModal: urlModal, activeDialog: urlDialog, openModal, openDialog, closeCurrentLayer: urlCloseLayer } = window.useUrlModal();
    const routerActiveModal = activeModal || urlModal;
    const routerActiveDialog = activeDialog || urlDialog;
    const routerOpenModal = openLocalModal || openModal;
    const routerOpenDialog = openLocalDialog || openDialog;
    const routerCloseLayer = closeCurrentLayer || urlCloseLayer;

    const [isSaving, setIsSaving] = useState(false);
    const [diagnostics, setDiagnostics] = useState(null);
    const [logs, setLogs] = useState('');
    const [backups, setBackups] = useState([]);
    const [codeStats, setCodeStats] = useState(null); 
    const [sortConfig, setSortConfig] = useState({ key: 'lines', direction: 'desc' });
    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 [pwdRequestData, setPwdRequestData] = useState(null); 
    const [confirmConfig, setConfirmConfig] = useState(null);
    const [backupLabel, setBackupLabel] = useState('');

    // FACTORISATION : Récupération sécurisée et propre des icônes
    const { 
        ActivityIcon, UsersIcon, BuildingIcon, EyeIcon, MessageSquareIcon, 
        TerminalIcon, ArchiveIcon, SaveIcon, DownloadIcon, RefreshCwIcon, 
        Trash2Icon, LoaderIcon, FileDigitIcon, EditIcon 
    } = window.getIcons();

    // Composants globaux
    const StatCard = window.StatCard || (() => null);
    const Modal = window.Modal || (() => null);
    const PasswordPromptModal = window.PasswordPromptModal || (() => null);
    const ConfirmModal = window.ConfirmModal || (() => null);
    const Button = window.Button;

    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);
        };
    }, []);

    useEffect(() => {
        let interval;
        if (routerActiveModal === 'diagnostics') {
            interval = setInterval(() => {
                fetch(window.ECO_CONFIG.apiBaseUrl + 'system/diagnostics&silent=1&_t=' + Date.now(), { cache: 'no-store', headers: { 'x-silent': '1' } })
                .then(r => r.json())
                .then(d => {
                    if (d.status === 'success') setDiagnostics(d.data);
                }).catch(()=>{});
            }, 1000);
        }
        return () => clearInterval(interval);
    }, [routerActiveModal]);

    const fetchDiagnostics = async () => { 
        routerOpenModal('diagnostics'); 
        setDiagnostics(null); 
        const d = await window.apiFetch('system/diagnostics&_t=' + Date.now(), { method: 'GET' });
        if (d) setDiagnostics(d.data); 
    };

    const fetchLogs = async () => { 
        routerOpenModal('logs'); 
        setLogs('Chargement...'); 
        const d = await window.apiFetch('system/logs&_t=' + Date.now(), { method: 'GET' });
        setLogs(d?.data?.logs || 'Aucun journal trouvé.'); 
    };

    const fetchCodeStats = async () => {
        routerOpenModal('code_stats');
        setCodeStats(null);
        const d = await window.apiFetch('system/code_stats&_t=' + Date.now(), { method: 'GET' });
        if (d) setCodeStats(d.data);
    };

    const triggerCron = () => {
        setConfirmConfig({
            title: "Exécution manuelle du CRON",
            message: "Voulez-vous vraiment lancer les tâches de fond (Nettoyage BDD, relances clients, purges des brouillons inactifs, rotation des sauvegardes) ? Cette opération peut prendre quelques instants.",
            confirmText: "Oui, exécuter",
            cancelText: "Annuler",
            onConfirm: async () => {
                routerCloseLayer();
                const d = await window.apiFetch('system/cron_cleanup', {
                    method: 'GET',
                    setLoading: setIsSaving,
                    successMessage: "Tâches planifiées exécutées avec succès."
                });
                if (d) fetchTelemetry();
            }
        });
        routerOpenDialog('confirm');
    };

    const clearLogs = async () => { 
        const d = await window.apiFetch('system/logs/clear');
        if (d) { fetchLogs(); fetchTelemetry(); }
    };
    
    const loadBackups = async () => { 
        routerOpenModal('backups'); 
        setShowAllBackups(false); 
        const d = await window.apiFetch('system/backups&_t=' + Date.now(), { 
            method: 'GET', 
            setLoading: setIsLoadingBackups 
        });
        if (d) setBackups(d.data); 
    };
    
    const createBackup = () => {
        setBackupLabel('');
        routerOpenDialog('backup_prompt');
    };

    const restoreBackup = (filename) => {
        setPwdRequestData({
            title: "Restauration système",
            desc: "ATTENTION CRITIQUE : La restauration écrasera la base de données actuelle. Saisissez le mot de passe admin :",
            onConfirm: async (pwd) => {
                const d = await window.apiFetch('system/backups/restore', {
                    body: { filename, pwd },
                    setLoading: setIsSaving,
                    successMessage: "Restauration réussie. L'application va recharger."
                });
                if (d) {
                    setTimeout(() => window.location.reload(), 2000);
                } else {
                    routerCloseLayer();
                }
            }
        });
        routerOpenDialog('pwd_request');
    };

    const deleteBackup = (filename) => {
        setPwdRequestData({
            title: "Suppression d'archive",
            desc: "Saisissez le mot de passe admin pour supprimer définitivement cette sauvegarde :",
            onConfirm: async (pwd) => {
                const d = await window.apiFetch('system/backups/delete', {
                    body: { filename, pwd },
                    setLoading: setIsSaving
                });
                if (d) {
                    loadBackups();
                    fetchTelemetry();
                    routerCloseLayer();
                }
            }
        });
        routerOpenDialog('pwd_request');
    };
    
    const requestSort = (key) => {
        let direction = 'asc';
        if (sortConfig && sortConfig.key === key && sortConfig.direction === 'desc') {
            direction = 'asc';
        } else {
            direction = 'desc';
        }
        setSortConfig({ key, direction });
    };

    const sortedCodeStatsDetails = useMemo(() => {
        if (!codeStats || !codeStats.details) return [];
        let sortableItems = [...codeStats.details];
        if (sortConfig !== null) {
            sortableItems.sort((a, b) => {
                if (a[sortConfig.key] < b[sortConfig.key]) {
                    return sortConfig.direction === 'asc' ? -1 : 1;
                }
                if (a[sortConfig.key] > b[sortConfig.key]) {
                    return sortConfig.direction === 'asc' ? 1 : -1;
                }
                return 0;
            });
        }
        return sortableItems;
    }, [codeStats, sortConfig]);

    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 clients = data.clients || [];
    const panneaux = data.panneaux || [];
    
    // CALCULS DES STATISTIQUES POUR L'ADMIN
    const activePanneaux = panneaux.filter(p => p.status === 'Actif' && p.id !== 'demo-panneau');
    const draftPanneaux = panneaux.filter(p => p.status === 'Brouillon' && 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 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 <a href="https://eco-panneau.fr" target="_blank" rel="noopener noreferrer" className="text-emerald-600 hover:underline font-bold">eco-panneau.fr</a>.</p>
                </div>
                
                <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-5 gap-4">
                    <StatCard title="MRR (revenus loc.)" value={`${mrr} €`} icon={<ActivityIcon size={24}/>} variant="success" />
                    <StatCard title="Clients inscrits" value={clients.length} icon={<UsersIcon size={24}/>} variant="info" onClick={() => setActiveTab('clients')} />
                    <StatCard title="Panneaux actifs" value={activePanneaux.length} icon={<BuildingIcon size={24}/>} variant="indigo" onClick={() => setActiveTab('panneaux')} />
                    <StatCard title="Brouillons (Non payés)" value={draftPanneaux.length} icon={<EditIcon size={24}/>} variant="secondary" />
                    <StatCard title="Total scans QR" value={data.stats?.totalViews || 0} icon={<EyeIcon size={24}/>} variant="warning" />
                </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"><MessageSquareIcon size={18} className="text-emerald-600"/> Derniers messages</h3>
                            <span role="button" onClick={() => setActiveTab('messages')} className="text-xs font-bold text-emerald-600 hover:underline cursor-pointer">Voir tout</span>
                        </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);
                                        setActiveTab('messages');
                                    }}>
                                        <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"><TerminalIcon size={18} className="text-emerald-600"/> Serveur et maintenance</h3>
                        <div className="space-y-3 flex-1 flex flex-col justify-start">
                            <div role="button" tabIndex={0} 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 cursor-pointer ${getColorClass(sysSummary.backupStatus)}`}>
                                <div className="flex items-center gap-4"><ArchiveIcon 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>
                            </div>
                            <div role="button" tabIndex={0} 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 cursor-pointer ${getColorClass(sysSummary.diagStatus)}`}>
                                <div className="flex items-center gap-4"><ActivityIcon 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>
                            </div>
                            <div role="button" tabIndex={0} onClick={fetchLogs} title="Consulter les journaux PHP" className={`w-full flex items-center justify-between p-4 rounded-xl border transition group text-left cursor-pointer ${getColorClass(sysSummary.logStatus)}`}>
                                <div className="flex items-center gap-4"><TerminalIcon size={24} className="group-hover:scale-110 transition-transform"/><div><p className="font-bold text-sm">Journaux 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>
                            </div>
                            <div role="button" tabIndex={0} onClick={fetchCodeStats} title="Statistiques du code source" className="w-full flex items-center justify-between p-4 rounded-xl border transition group text-left cursor-pointer text-slate-700 border-slate-200 bg-slate-50 hover:border-blue-400 hover:bg-blue-50">
                                <div className="flex items-center gap-4">
                                    <FileDigitIcon size={24} className="group-hover:scale-110 transition-transform text-blue-600"/>
                                    <div>
                                        <p className="font-bold text-sm">Statistiques du code source</p>
                                        <p className="text-xs mt-1 opacity-80">Analyse des fichiers du projet</p>
                                    </div>
                                </div>
                            </div>
                            <div role="button" tabIndex={0} onClick={triggerCron} title="Exécuter les tâches planifiées" className="w-full flex items-center justify-between p-4 rounded-xl border transition group text-left cursor-pointer text-slate-700 border-slate-200 bg-slate-50 hover:border-emerald-400 hover:bg-emerald-50">
                                <div className="flex items-center gap-4">
                                    <RefreshCwIcon size={24} className="group-hover:scale-110 transition-transform text-emerald-600"/>
                                    <div>
                                        <p className="font-bold text-sm">Exécuter le CRON manuellement</p>
                                        <p className="text-xs mt-1 opacity-80">Purges, relances et sauvegardes automatiques</p>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            {/* MODALES SYSTÈME (EN DEHORS DE LA DIV ANIMÉE) */}
            {routerActiveModal === 'code_stats' && Modal && (
                <Modal title="Statistiques du code source" onClose={routerCloseLayer} zIndex="z-[250]">
                    {!codeStats ? (
                        <div className="py-12 text-center text-slate-500">
                            <LoaderIcon size={32} className="animate-spin inline-block mb-4 text-blue-600"/>
                            <p className="text-sm font-bold uppercase tracking-widest">Analyse en cours...</p>
                        </div>
                    ) : (
                        <div className="space-y-6">
                            <div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
                                <div className="bg-slate-50 p-4 rounded-xl border border-slate-200 flex flex-col items-center justify-center min-h-[100px]">
                                    <p className="text-[10px] font-bold text-slate-500 uppercase tracking-widest mb-1 text-center">Fichiers inclus</p>
                                    <p className="text-2xl font-black text-slate-800 text-center">{codeStats.total_files.toLocaleString('fr-FR')}</p>
                                </div>
                                <div className="bg-slate-50 p-4 rounded-xl border border-slate-200 flex flex-col items-center justify-center min-h-[100px]">
                                    <p className="text-[10px] font-bold text-slate-500 uppercase tracking-widest mb-1 text-center">Total Lignes</p>
                                    <p className="text-2xl font-black text-slate-800 text-center">{codeStats.total_lines.toLocaleString('fr-FR')}</p>
                                </div>
                                <div className="bg-slate-50 p-4 rounded-xl border border-slate-200 flex flex-col items-center justify-center min-h-[100px]">
                                    <p className="text-[10px] font-bold text-slate-500 uppercase tracking-widest mb-1 text-center">Total Caractères</p>
                                    <p className="text-2xl font-black text-slate-800 text-center">{codeStats.total_chars.toLocaleString('fr-FR')}</p>
                                </div>
                            </div>
                            
                            <div className="border border-slate-200 rounded-xl overflow-hidden bg-white shadow-sm flex flex-col">
                                <div className="flex items-center bg-slate-50 border-b border-slate-200 shadow-sm z-10 text-[10px] uppercase tracking-widest text-slate-500 font-bold shrink-0">
                                    <div className="flex-1 p-3 cursor-pointer hover:bg-slate-200 transition select-none" onClick={() => requestSort('path')}>
                                        Fichier {sortConfig?.key === 'path' ? (sortConfig.direction === 'asc' ? '↑' : '↓') : ''}
                                    </div>
                                    <div className="w-24 p-3 text-right cursor-pointer hover:bg-slate-200 transition select-none shrink-0" onClick={() => requestSort('lines')}>
                                        Lignes {sortConfig?.key === 'lines' ? (sortConfig.direction === 'asc' ? '↑' : '↓') : ''}
                                    </div>
                                    <div className="w-28 p-3 text-right cursor-pointer hover:bg-slate-200 transition select-none shrink-0" onClick={() => requestSort('chars')}>
                                        Caractères {sortConfig?.key === 'chars' ? (sortConfig.direction === 'asc' ? '↑' : '↓') : ''}
                                    </div>
                                </div>
                                
                                <div className="divide-y divide-slate-100 max-h-[50vh] overflow-hidden overflow-y-auto custom-scrollbar flex-1 min-h-0">
                                    {sortedCodeStatsDetails.map((stat, i) => (
                                        <div key={i} className="flex items-center hover:bg-slate-50 transition w-full">
                                            <div className="flex-1 p-3 text-xs font-mono text-slate-700 truncate min-w-0" title={stat.path}>
                                                {stat.path}
                                            </div>
                                            <div className="w-24 p-3 text-xs font-medium text-slate-600 text-right shrink-0" title={stat.lines.toLocaleString('fr-FR')}>
                                                {stat.lines.toLocaleString('fr-FR')}
                                            </div>
                                            <div className="w-28 p-3 text-xs font-medium text-slate-400 text-right shrink-0" title={stat.chars.toLocaleString('fr-FR')}>
                                                {stat.chars.toLocaleString('fr-FR')}
                                            </div>
                                        </div>
                                    ))}
                                </div>
                            </div>
                        </div>
                    )}
                </Modal>
            )}

            {routerActiveModal === 'diagnostics' && Modal && (
                <Modal title="Diagnostics système" onClose={routerCloseLayer} zIndex="z-[250]">
                    {!diagnostics ? <div className="p-10 text-center"><LoaderIcon 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>
                    )}
                </Modal>
            )}

            {routerActiveModal === 'logs' && Modal && (
                <Modal title="Journaux d'erreurs (PHP)" onClose={routerCloseLayer} zIndex="z-[250]">
                    <Button variant="danger" icon={Trash2Icon} onClick={clearLogs} className="w-full py-3 mb-4 justify-center">Vider les journaux</Button>
                    <div className="bg-slate-900 rounded-xl p-4 overflow-hidden overflow-y-auto max-h-[60vh] custom-scrollbar">
                        <pre className="text-[10px] text-emerald-400 font-mono whitespace-pre-wrap">{logs}</pre>
                    </div>
                </Modal>
            )}

            {routerActiveModal === 'backups' && Modal && (
                <Modal title="Gestion des sauvegardes système" onClose={() => {if (!isSaving && !isLoadingBackups) routerCloseLayer();}} preventClose={isSaving || isLoadingBackups} zIndex="z-[250]">
                    <div className="space-y-4">
                        {isLoadingBackups ? (
                            <div className="py-12 text-center text-slate-500">
                                <LoaderIcon 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 
                                    variant="dark" 
                                    icon={isSaving ? LoaderIcon : SaveIcon} 
                                    onClick={createBackup} 
                                    disabled={isSaving} 
                                    className="w-full py-4 mb-6 uppercase tracking-widest justify-center"
                                >
                                    {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">
                                            <Button variant="info" icon={DownloadIcon} onClick={() => window.location.href = `?api=system/backups/download&file=${encodeURIComponent(b.name)}`} title="Télécharger l'archive" className="p-2" />
                                            <Button variant="warning" icon={RefreshCwIcon} onClick={() => restoreBackup(b.name)} disabled={isSaving} title="Restaurer (Écraser la BDD actuelle)" className="p-2" />
                                            <Button variant="danger" icon={Trash2Icon} onClick={() => deleteBackup(b.name)} disabled={isSaving} title="Supprimer définitivement" className="p-2" />
                                        </div>
                                    </div>
                                ))}

                                {backups.length > 5 && !showAllBackups && (
                                    <Button variant="secondary" onClick={() => setShowAllBackups(true)} className="w-full py-3 justify-center">
                                        Voir les {backups.length - 5} anciennes archives...
                                    </Button>
                                )}
                                {backups.length === 0 && <p className="text-center text-slate-400 text-sm py-4">Aucune sauvegarde trouvée.</p>}
                            </>
                        )}
                    </div>
                </Modal>
            )}

            {/* MODALE DÉDIÉE À LA SAUVEGARDE MANUELLE */}
            {routerActiveDialog === 'backup_prompt' && Modal && (
                <Modal title="Nouvelle sauvegarde" type="confirm" onClose={routerCloseLayer} preventClose={isSaving} zIndex="z-[300]">
                    <form onSubmit={async (e) => { 
                        e.preventDefault();
                        const d = await window.apiFetch('system/backups/create', {
                            body: { label: backupLabel },
                            setLoading: setIsSaving,
                            successMessage: "Sauvegarde créée avec succès."
                        });
                        if (d) {
                            await loadBackups(); 
                            fetchTelemetry(); 
                            routerCloseLayer();
                            setBackupLabel('');
                        }
                    }} className="space-y-6">
                        <p className="text-slate-600 font-medium leading-relaxed">Saisissez un marqueur personnalisé pour identifier cette sauvegarde manuelle (Optionnel) :</p>
                        <input 
                            type="text" 
                            value={backupLabel} 
                            onChange={e => setBackupLabel(e.target.value)} 
                            placeholder="Ex. : Avant la mise à jour..." 
                            className="w-full border-2 border-slate-200 rounded-xl p-3 focus:border-emerald-500 outline-none transition font-bold" 
                            autoFocus 
                        />
                        <div className="flex gap-3 pt-2 border-t border-slate-100">
                            <Button variant="secondary" type="button" onClick={routerCloseLayer} disabled={isSaving} className="flex-1 py-3 justify-center">Annuler</Button>
                            <Button type="submit" variant="dark" disabled={isSaving} icon={isSaving ? LoaderIcon : null} className="flex-1 py-3 uppercase tracking-widest justify-center">Sauvegarder</Button>
                        </div>
                    </form>
                </Modal>
            )}

            {routerActiveDialog === 'pwd_request' && pwdRequestData && PasswordPromptModal && (
                <PasswordPromptModal
                    title={pwdRequestData.title}
                    desc={pwdRequestData.desc}
                    onConfirm={pwdRequestData.onConfirm}
                    onCancel={routerCloseLayer}
                    isSaving={isSaving}
                />
            )}

            {routerActiveDialog === 'confirm' && confirmConfig && ConfirmModal && <ConfirmModal {...confirmConfig} onCancel={routerCloseLayer} zIndex="z-[350]" />}
        </>
    );
};

/* EOF ========== [_react/_admin_dashboard.jsx] */