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

window.pano_AdminModalsBackups = ({ activeModal, activeDialog, closeCurrentLayer, openLocalDialog, fetchTelemetry, showToast }) => {
    const { useState, useEffect } = React;
    
    // ZÉRO-DETTE : Utilisation de notre Hook abstrait !
    const { isMounted, safeFetch } = window.pano_useSafeFetch();

    const [isSaving, setIsSaving] = useState(false);
    const [isLoadingBackups, setIsLoadingBackups] = useState(true);
    const [backupsList, setBackupsList] = useState([]);
    const [backupDesc, setBackupDesc] = useState('');
    const [showAllBackups, setShowAllBackups] = useState(false);
    const [pendingBackup, setPendingBackup] = useState(null);
    const [backupToRestore, setBackupToRestore] = useState(null);
    const [restorePwd, setRestorePwd] = useState('');
    const [confirmConfig, setConfirmConfig] = useState(null);

    // 1. - Composants et Icônes
    const { Modal, ConfirmModal, Button, FormInput } = window.pano_getComponents();
    const { ArchiveIcon, Trash2Icon, RefreshCwIcon, DownloadIcon, CheckCircleIcon, ShieldIcon, LoaderIcon } = window.pano_getIcons();

    // 2. - Chargement initial
    useEffect(() => {
        if (activeModal === 'backups') {
            loadBackups();
        }
    // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [activeModal]);

    const loadBackups = async () => {
        setIsLoadingBackups(true);
        try {
            const d = await safeFetch(`system/backups&_t=${Date.now()}`, { method: 'GET', silent: true });
            if (!isMounted.current) return; // SÉCURITÉ : Coupe-circuit
            if (d && d.status === 'success') {
                setBackupsList(d.data || []);
                setShowAllBackups(false); 
            }
        } catch (e) {
            if (!isMounted.current) return; // SÉCURITÉ
            if (window.pano_logFallback) window.pano_logFallback(`Erreur de chargement des backups: ${e.message}`);
        }
        if (isMounted.current) setIsLoadingBackups(false);
    };

    // 3. - Polling de génération d'archive (Conserve Fetch natif car c'est une boucle autonome)
    useEffect(() => {
        let interval;
        if (pendingBackup) {
            interval = setInterval(async () => {
                try {
                    // CORRECTION : Ajout du header x-silent pour rendre le polling furtif
                    const res = await fetch(`${window.pano_CONFIG.apiBaseUrl}system/backups&_t=${Date.now()}`, { headers: { 'x-silent': '1' } });
                    const d = await res.json();
                    
                    if (!isMounted.current) {
                        clearInterval(interval);
                        return;
                    } // SÉCURITÉ : Arrêt du polling si démonté

                    if (d && d.status === 'success') {
                        setBackupsList(d.data || []);
                        const found = (d.data || []).find(b => b.name === pendingBackup);
                        if (found) {
                            setPendingBackup(null);
                            clearInterval(interval);
                            if (showToast) showToast("L'archive a été générée avec succès !", "success");
                            if (fetchTelemetry) fetchTelemetry();
                        }
                    }
                } catch(e) {}
            }, 3000); 
        }
        return () => clearInterval(interval);
    }, [pendingBackup, fetchTelemetry, showToast]);

    const manualBackupsCount = backupsList.filter(b => b.label !== 'Automatique').length;
    const sortedBackups = [...backupsList].sort((a, b) => b.date - a.date);
    const displayedBackups = showAllBackups ? sortedBackups : sortedBackups.slice(0, 5);

    // 4. - Création de sauvegarde
    const handleCreateBackup = async () => {
        const d = await safeFetch('system/backups/create', {
            body: { label: backupDesc.trim() },
            setLoading: setIsSaving
        });
        
        if (!isMounted.current) return; // SÉCURITÉ : Coupe-circuit

        if (d && d.data && d.data.filename) {
            setBackupDesc('');
            closeCurrentLayer();
            setPendingBackup(d.data.filename); 
            if (showToast) showToast("La création de l'archive a débuté en arrière-plan...", "info");
        }
    };

    // 5. - Restauration
    const confirmRestore = (b) => {
        setBackupToRestore(b);
        openLocalDialog('restore_prompt');
    };

    const executeRestore = async () => {
        if (!restorePwd) {
            if (showToast) showToast("Mot de passe requis.", "error");
            return;
        }
        closeCurrentLayer();
        const d = await safeFetch('system/backups/restore', {
            body: { filename: backupToRestore.name, pwd: restorePwd },
            setLoading: setIsSaving,
            successMessage: "Restauration terminée. Le système a été réinitialisé."
        });

        if (!isMounted.current) return; // SÉCURITÉ : Coupe-circuit

        if (d) {
            setRestorePwd('');
            setBackupToRestore(null);
            setTimeout(() => window.location.reload(), 1500);
        }
    };

    // 6. - Suppression et nettoyage
    const handleDeleteBackup = (b) => {
        setConfirmConfig({
            title: "Supprimer la sauvegarde",
            message: `Voulez-vous vraiment supprimer la sauvegarde "${b.label}" ?`,
            confirmText: "Oui, supprimer",
            isDestructive: true,
            onConfirm: async () => {
                setConfirmConfig(null);
                const d = await safeFetch('system/backups/delete', {
                    body: { file: b.name },
                    setLoading: setIsSaving,
                    successMessage: "Sauvegarde supprimée."
                });

                if (!isMounted.current) return; // SÉCURITÉ : Coupe-circuit

                if (d) {
                    loadBackups();
                    if (fetchTelemetry) fetchTelemetry();
                }
            },
            onCancel: () => setConfirmConfig(null)
        });
        openLocalDialog('confirm');
    };

    const handleCleanupBackups = () => {
        setConfirmConfig({
            title: "Nettoyage des archives",
            message: "Voulez-vous vraiment supprimer toutes les sauvegardes manuelles à l'exception des 5 plus récentes ? Les sauvegardes automatiques ne seront pas affectées.",
            confirmText: "Oui, nettoyer",
            isDestructive: true,
            onConfirm: async () => {
                setConfirmConfig(null);
                const d = await safeFetch('system/backups/cleanup', {
                    method: 'POST',
                    setLoading: setIsSaving,
                    successMessage: "Archives manuelles obsolètes purgées avec succès."
                });

                if (!isMounted.current) return; // SÉCURITÉ : Coupe-circuit

                if (d) {
                    loadBackups();
                    if (fetchTelemetry) fetchTelemetry();
                }
            },
            onCancel: () => setConfirmConfig(null)
        });
        openLocalDialog('confirm');
    };

    // 7. - Rendu UI
    return (
        <>
            {activeModal === 'backups' && (
                <Modal 
                    title="Gestion des sauvegardes" 
                    onClose={closeCurrentLayer} 
                    icon={ArchiveIcon} 
                    maxWidth="max-w-4xl"
                    actions={(close) => (
                        <>
                            <Button variant="secondary" icon={Trash2Icon} onClick={handleCleanupBackups} disabled={isSaving || manualBackupsCount <= 5} title="Ne garder que les 5 archives manuelles les plus récentes" className="flex-1 py-3 justify-center text-xs">Purger</Button>
                            <Button variant="primary" icon={ArchiveIcon} onClick={() => openLocalDialog('backup_prompt')} disabled={isSaving || isLoadingBackups || pendingBackup} className="flex-[2] py-3 justify-center shadow-md uppercase tracking-widest text-xs">Nouvelle archive</Button>
                        </>
                    )}
                >
                    <div className="space-y-6 min-w-0 w-full overflow-x-hidden">
                        <div className="bg-slate-50 border border-slate-200 p-5 rounded-2xl flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4 shadow-sm min-w-0">
                            <div className="min-w-0">
                                <h3 className="font-black text-slate-800 text-base break-words">Archives de la plateforme</h3>
                                <p className="text-sm text-slate-500 mt-1 break-words leading-relaxed">
                                    Sauvegardes automatisées et manuelles de la base de données (JSON) et des fichiers vitaux.
                                </p>
                            </div>
                        </div>
                        
                        <div className="bg-white rounded-2xl border border-slate-200 shadow-sm min-w-0">
                            <div className="max-h-[60vh] overflow-y-auto custom-scrollbar divide-y divide-slate-100 flex flex-col min-w-0">
                                
                                {isLoadingBackups ? (
                                    <div className="p-12 flex flex-col items-center justify-center text-slate-400 gap-3 min-w-0">
                                        <LoaderIcon size={32} className="animate-spin text-emerald-500" />
                                        <span className="text-sm font-bold uppercase tracking-widest animate-pulse break-words text-center">Chargement des archives...</span>
                                    </div>
                                ) : (
                                    <>
                                        <div className="flex justify-between items-center p-4 bg-slate-50 min-w-0">
                                            <span className="text-sm font-bold text-slate-700 break-words">
                                                {window.pano_formatPlural(sortedBackups.length, 'archive disponible', 'archives disponibles')}
                                            </span>
                                            <Button variant="ghost" icon={RefreshCwIcon} onClick={loadBackups} disabled={isSaving} className="text-xs text-slate-500 shadow-none border-none py-1">
                                                Actualiser
                                            </Button>
                                        </div>

                                        {pendingBackup && (
                                            <div className="p-4 flex flex-col sm:flex-row justify-between sm:items-center gap-4 bg-emerald-50 border-b border-emerald-100 min-w-0">
                                                <div className="flex items-center gap-3 min-w-0">
                                                    <div className="w-10 h-10 rounded-xl flex items-center justify-center shrink-0 bg-emerald-100 text-emerald-600">
                                                        <LoaderIcon size={20} className="animate-spin" />
                                                    </div>
                                                    <div className="min-w-0">
                                                        <p className="font-bold text-slate-800 text-sm flex items-center gap-2 break-words">
                                                            Génération en cours...
                                                        </p>
                                                        <p className="text-xs text-slate-500 mt-0.5 break-words">Le fichier apparaîtra ici automatiquement dans quelques instants.</p>
                                                    </div>
                                                </div>
                                            </div>
                                        )}

                                        {displayedBackups.map((b, i) => {
                                            const isAuto = b.label === 'Automatique' || b.name.includes('Automatique');
                                            const iconColorClass = isAuto ? 'bg-purple-100 text-purple-600' : 'bg-blue-100 text-blue-600';
                                            
                                            return (
                                                <div key={i} className="p-4 flex flex-col sm:flex-row justify-between sm:items-center gap-4 hover:bg-slate-50 transition min-w-0">
                                                    <div className="flex items-center gap-3 min-w-0">
                                                        <div className={`w-10 h-10 rounded-xl flex items-center justify-center shrink-0 ${iconColorClass}`}>
                                                            <ArchiveIcon size={20}/>
                                                        </div>
                                                        <div className="min-w-0 flex-1 pr-2">
                                                            <p className="font-bold text-slate-800 text-sm flex items-center gap-2 break-all leading-tight">
                                                                {b.label}
                                                                {i === 0 && !showAllBackups && !pendingBackup && <span className="text-[9px] bg-emerald-500 text-white px-2 py-0.5 rounded-full uppercase tracking-wider shrink-0">Actuelle</span>}
                                                            </p>
                                                            <p className="text-xs text-slate-500 mt-0.5 break-words leading-tight">{new Date(b.date).toLocaleString('fr-FR')} • <span className="font-mono text-[10px] bg-slate-100 px-1.5 rounded">{b.size}</span></p>
                                                        </div>
                                                    </div>
                                                    <div className="flex gap-2 shrink-0">
                                                        <a 
                                                            href={`${window.pano_CONFIG.apiBaseUrl}system/backups/download&file=${encodeURIComponent(b.name)}`} 
                                                            download={`eco-panneau.fr_${b.name}`}
                                                            title="Télécharger (.zip)" 
                                                            className="text-xs font-bold transition flex items-center justify-center gap-2 rounded-xl shrink-0 aspect-square p-2 bg-slate-100 text-slate-700 hover:bg-slate-200"
                                                        >
                                                            {DownloadIcon && <DownloadIcon size={16} className="shrink-0" />}
                                                        </a>
                                                        <Button variant="warning" shape="round" icon={RefreshCwIcon} onClick={() => confirmRestore(b)} disabled={isSaving || pendingBackup} title="Restaurer" className="p-2 border-none shadow-none"/>
                                                        <Button variant="danger" shape="round" icon={Trash2Icon} onClick={() => handleDeleteBackup(b)} disabled={isSaving || (i === 0 && !showAllBackups) || pendingBackup} title="Supprimer" className="p-2 border-none shadow-none"/>
                                                    </div>
                                                </div>
                                            );
                                        })}
                                        
                                        {!showAllBackups && sortedBackups.length > 5 && (
                                            <div className="p-4 flex justify-center bg-slate-50 border-t border-slate-100 min-w-0">
                                                <Button variant="secondary" onClick={() => setShowAllBackups(true)} className="text-xs font-bold py-2 px-6">
                                                    Afficher {window.pano_formatPlural(sortedBackups.length - 5, 'sauvegarde plus ancienne', 'sauvegardes plus anciennes')}
                                                </Button>
                                            </div>
                                        )}
                                        
                                        {sortedBackups.length === 0 && !pendingBackup && (
                                            <div className="p-8 text-center text-slate-500 italic text-sm break-words">Aucune sauvegarde trouvée sur le serveur.</div>
                                        )}
                                    </>
                                )}
                            </div>
                        </div>
                    </div>
                </Modal>
            )}

            {activeDialog === 'backup_prompt' && (
                <Modal 
                    title="Nouvelle sauvegarde" 
                    onClose={closeCurrentLayer} 
                    preventClose={isSaving} 
                    actions={(close) => (
                        <>
                            <Button variant="secondary" onClick={close} disabled={isSaving} className="flex-1 py-3 justify-center">Annuler</Button>
                            <Button type="submit" form="backup-form" variant="primary" icon={isSaving ? LoaderIcon : CheckCircleIcon} disabled={isSaving} className="flex-[2] py-3 justify-center uppercase tracking-widest text-xs shadow-md">
                                {isSaving ? 'Création en cours...' : 'Créer l\'archive'}
                            </Button>
                        </>
                    )}
                >
                    <form id="backup-form" onSubmit={(e) => { e.preventDefault(); handleCreateBackup(); }} className="space-y-4 min-w-0">
                        <p className="text-sm text-slate-600 break-words leading-relaxed">Donnez une description courte à cette archive (ex: "Avant mise à jour V2"). <span className="italic text-slate-400">Optionnel</span>.</p>
                        <input type="text" value={backupDesc} onChange={e => setBackupDesc(e.target.value)} disabled={isSaving} placeholder="Description de l'archive (Optionnel)..." className="w-full border-2 border-slate-200 rounded-xl p-3 focus:border-emerald-500 outline-none transition font-bold min-w-0" autoFocus />
                    </form>
                </Modal>
            )}

            {activeDialog === 'restore_prompt' && backupToRestore && (
                <Modal 
                    title="Confirmation de restauration" 
                    onClose={closeCurrentLayer} 
                    actions={(close) => (
                        <>
                            <Button variant="secondary" onClick={close} disabled={isSaving} className="flex-1 py-3 justify-center">Annuler</Button>
                            <Button type="submit" form="restore-form" variant="warningSolid" icon={RefreshCwIcon} disabled={isSaving || !restorePwd} className="flex-[2] py-3 justify-center uppercase tracking-widest text-xs shadow-md">
                                Confirmer et restaurer
                            </Button>
                        </>
                    )}
                >
                    <form id="restore-form" onSubmit={(e) => { e.preventDefault(); executeRestore(); }} className="space-y-4 min-w-0">
                        <div className="bg-amber-50 border border-amber-200 p-4 rounded-xl text-amber-800 text-sm font-medium min-w-0">
                            <p className="break-words leading-relaxed">
                                Vous êtes sur le point d'écraser la base de données actuelle avec l'archive du <strong className="font-bold">{new Date(backupToRestore.date).toLocaleString('fr-FR')}</strong>. 
                                Toutes les données générées depuis cette date seront définitivement perdues.
                            </p>
                        </div>
                        <FormInput 
                            label="Mot de passe administrateur requis" 
                            icon={<ShieldIcon size={18}/>} 
                            type="password" 
                            value={restorePwd} 
                            onChange={e => setRestorePwd(e.target.value)} 
                            placeholder="Saisissez votre mot de passe principal..." 
                            required 
                            autoFocus 
                            className="min-w-0 w-full"
                        />
                    </form>
                </Modal>
            )}

            {activeDialog === 'confirm' && confirmConfig && ConfirmModal && <ConfirmModal {...confirmConfig} onCancel={closeCurrentLayer} />}
        </>
    );
};

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