const axios = require('axios');
const { getConfig } = require('../core/database');

let isMonitoring = false;
let checkInterval = null;
let isRebooting = false;
let reconnectCallback = null; // Callback pour resync le WebSocket

const CHECK_INTERVAL_MS = 60 * 1000; // Vérifier toutes les 60 secondes

/**
 * Vérifie l'utilisation actuelle de la RAM du serveur
 */
const checkRAMUsage = async () => {
    try {
        const response = await axios.get(
            `${process.env.PTERODACTYL_API_URL}/api/client/servers/${process.env.PTERODACTYL_SERVER_ID}/resources`,
            {
                headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${process.env.PTERODACTYL_API_TOKEN}`
                }
            }
        );

        const resources = response.data.attributes.resources;
        const ramUsedMB = resources.memory_bytes / (1024 * 1024); // Convertir en MB
        const ramUsedGB = (ramUsedMB / 1024).toFixed(2); // Convertir en GB pour l'affichage
        const currentState = response.data.attributes.current_state;

        console.log(`🔍 [RAM Monitor] Utilisation RAM: ${ramUsedGB} Go / État: ${currentState}`);

        // Récupérer la configuration depuis la base de données
        const autoRebootEnabled = (await getConfig('auto_reboot_enabled')) === 'true';
        const ramThresholdGB = parseInt(await getConfig('ram_threshold_gb')) || 19;
        const RAM_THRESHOLD_MB = ramThresholdGB * 1024;

        // Vérifier si on dépasse le seuil ET que le serveur est en cours d'exécution ET que l'auto-reboot est activé
        if (autoRebootEnabled && ramUsedMB > RAM_THRESHOLD_MB && currentState === 'running' && !isRebooting) {
            console.log(`⚠️ [RAM Monitor] SEUIL DÉPASSÉ ! ${ramUsedGB} Go > ${ramThresholdGB} Go`);
            console.log(`🔄 [RAM Monitor] Déclenchement du redémarrage automatique...`);
            
            await rebootServer();
        } else if (!autoRebootEnabled && ramUsedMB > RAM_THRESHOLD_MB) {
            console.log(`⚠️ [RAM Monitor] Seuil dépassé mais auto-reboot désactivé (${ramUsedGB} Go > ${ramThresholdGB} Go)`);
        }

        return { ramUsedMB, ramUsedGB, currentState };
    } catch (error) {
        console.error('❌ [RAM Monitor] Erreur lors de la vérification RAM:', error.message);
        return null;
    }
};

/**
 * Redémarre le serveur automatiquement
 */
const rebootServer = async () => {
    if (isRebooting) {
        console.log('⚠️ [RAM Monitor] Redémarrage déjà en cours, annulation...');
        return;
    }

    isRebooting = true;

    try {
        const headers = {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${process.env.PTERODACTYL_API_TOKEN}`
        };

        const serverUrl = `${process.env.PTERODACTYL_API_URL}/api/client/servers/${process.env.PTERODACTYL_SERVER_ID}`;

        console.log('💾 [RAM Monitor] Sauvegarde du serveur...');
        await axios.post(`${serverUrl}/command`, {
            command: 'save'
        }, { headers });

        // Annoncer le redémarrage aux joueurs
        console.log('📢 [RAM Monitor] Annonce du redémarrage...');
        await axios.post(`${serverUrl}/command`, {
            command: "broadcast 'Redémarrage automatique (RAM élevée - 60 secondes)'"
        }, { headers });

        // Attendre la sauvegarde
        await new Promise(resolve => setTimeout(resolve, 3000));

        console.log('⏹️ [RAM Monitor] Arrêt du serveur...');
        await axios.post(`${serverUrl}/power`, {
            signal: 'stop'
        }, { headers });

        // Attendre 60 secondes
        console.log('⏳ [RAM Monitor] Attente de 60 secondes...');
        await new Promise(resolve => setTimeout(resolve, 60000));

        console.log('🚀 [RAM Monitor] Redémarrage du serveur...');
        await axios.post(`${serverUrl}/power`, {
            signal: 'start'
        }, { headers });

        // Attendre que le serveur soit opérationnel
        let isRunning = false;
        let attempts = 0;
        const maxAttempts = 30; // 30 tentatives * 5 secondes = 2.5 minutes max

        while (!isRunning && attempts < maxAttempts) {
            attempts++;
            await new Promise(resolve => setTimeout(resolve, 5000));

            try {
                const checkResponse = await axios.get(`${serverUrl}/resources`, { headers });
                const state = checkResponse.data.attributes.current_state;

                if (state === 'running') {
                    isRunning = true;
                    console.log('✅ [RAM Monitor] Serveur redémarré avec succès !');
                    
                    // Resynchroniser le WebSocket si un callback est défini
                    if (reconnectCallback) {
                        console.log('🔄 [RAM Monitor] Resynchronisation du WebSocket...');
                        await new Promise(resolve => setTimeout(resolve, 5000)); // Attendre 5s de plus
                        reconnectCallback();
                    }
                }
            } catch (error) {
                console.error(`❌ [RAM Monitor] Tentative ${attempts}/${maxAttempts} échouée:`, error.message);
            }
        }

        if (!isRunning) {
            console.error('❌ [RAM Monitor] Le serveur n\'a pas redémarré après le délai maximum');
        }

    } catch (error) {
        console.error('❌ [RAM Monitor] Erreur lors du redémarrage:', error.message);
    } finally {
        isRebooting = false;
    }
};

/**
 * Démarre la surveillance de la RAM
 */
const startRAMMonitoring = async (websocketReconnectCallback = null) => {
    if (isMonitoring) {
        console.log('⚠️ [RAM Monitor] Surveillance déjà active');
        return;
    }

    reconnectCallback = websocketReconnectCallback;
    
    const ramThresholdGB = parseInt(await getConfig('ram_threshold_gb')) || 19;
    
    console.log(`🚀 [RAM Monitor] Démarrage de la surveillance RAM (seuil: ${ramThresholdGB} Go)`);
    console.log(`⏱️ [RAM Monitor] Intervalle de vérification: ${CHECK_INTERVAL_MS / 1000}s`);

    isMonitoring = true;

    // Première vérification immédiate
    checkRAMUsage();

    // Vérifications périodiques
    checkInterval = setInterval(async () => {
        if (!isRebooting) {
            await checkRAMUsage();
        }
    }, CHECK_INTERVAL_MS);
};

/**
 * Arrête la surveillance de la RAM
 */
const stopRAMMonitoring = () => {
    if (!isMonitoring) {
        console.log('⚠️ [RAM Monitor] Surveillance déjà inactive');
        return;
    }

    console.log('⏹️ [RAM Monitor] Arrêt de la surveillance RAM');
    isMonitoring = false;

    if (checkInterval) {
        clearInterval(checkInterval);
        checkInterval = null;
    }
};

/**
 * Obtenir le statut de la surveillance
 */
const getMonitoringStatus = async () => {
    const ramThresholdGB = parseInt(await getConfig('ram_threshold_gb')) || 19;
    return {
        isMonitoring,
        isRebooting,
        threshold: ramThresholdGB * 1024, // En MB
        checkInterval: CHECK_INTERVAL_MS
    };
};

module.exports = {
    startRAMMonitoring,
    stopRAMMonitoring,
    checkRAMUsage,
    getMonitoringStatus
};
