/* ============================================
   GAME STATE & SCORING ENGINE
   ============================================ */

/**
 * Moteur de scoring avancé
 * Calcule les points avec bonus temps et efficacité
 */
class ScoringEngine {
    constructor() {
        this.basePoints = 1000;
        this.difficultyMultiplier = 1;
        this.timeBonus = 0;
        this.efficiencyBonus = 0;
    }
    
    /**
     * Calculer le score final
     * Formule : basePoints × difficultyMultiplier + timeBonus + efficiencyBonus
     */
    calculateFinalScore(moves, timeSeconds, pairesTotal, difficulty) {
        const mode = DIFFICULTY_MODES[difficulty];
        this.difficultyMultiplier = mode.scoreMultiplier;
        
        // Bonus temps : points restants
        const timeRemaining = Math.max(0, mode.timeLimit - timeSeconds);
        this.timeBonus = Math.round((timeRemaining / mode.timeLimit) * 500);
        
        // Bonus efficacité : pénalité pour erreurs
        // Jeu parfait = pairesTotal mouvements (2 cartes par paire)
        const perfectMoves = pairesTotal;
        const efficiency = Math.max(0, 1 - ((moves - perfectMoves) / (perfectMoves * 2)));
        this.efficiencyBonus = Math.round(efficiency * 500);
        
        // Score final
        const baseScore = this.basePoints * this.difficultyMultiplier;
        const finalScore = Math.round(baseScore + this.timeBonus + this.efficiencyBonus);
        
        return {
            baseScore: baseScore,
            timeBonus: this.timeBonus,
            efficiencyBonus: this.efficiencyBonus,
            totalScore: finalScore,
            duration: timeSeconds,
            breakdown: {
                base: baseScore,
                temps: this.timeBonus,
                efficacite: this.efficiencyBonus,
                total: finalScore
            }
        };
    }
    
    /**
     * Détecter les achievements
     */
    detectAchievements(moves, timeSeconds, pairesTotal, difficulty) {
        const achievements = [];
        
        // 🏅 Jeu parfait (0 erreurs)
        if (moves === pairesTotal) {
            achievements.push({
                id: 'perfect_game',
                name: '🏅 Jeu Parfait',
                icon: '🏅',
                description: 'Trouvé toutes les paires sans erreur!'
            });
        }
        
        // ⚡ Vitesse extrême
        if (timeSeconds < DIFFICULTY_MODES[difficulty].timeLimit * 0.3) {
            achievements.push({
                id: 'speedrun',
                name: '⚡ Vitesse Éclair',
                icon: '⚡',
                description: `Complété en ${timeSeconds}s!`
            });
        }
        
        // 🔥 Difficile réussi
        if (difficulty === 'hard') {
            achievements.push({
                id: 'hard_mode',
                name: '🔥 Maître du Mode Difficile',
                icon: '🔥',
                description: 'Défi chronométré réussi!'
            });
        }
        
        // 🎯 Score parfait
        const perfectScore = 1000 * DIFFICULTY_MODES[difficulty].scoreMultiplier;
        if ((this.basePoints * this.difficultyMultiplier + this.timeBonus + this.efficiencyBonus) >= perfectScore + 900) {
            achievements.push({
                id: 'perfect_score',
                name: '🎯 Score Parfait',
                icon: '🎯',
                description: 'Score quasi-maximal!'
            });
        }
        
        // 🏃 Rapidité respectable
        if (timeSeconds < 60 && pairesTotal === 9) {
            achievements.push({
                id: 'fast_completion',
                name: '🏃 Très Rapide',
                icon: '🏃',
                description: 'Moins d\'une minute!'
            });
        }
        
        return achievements;
    }
}

/**
 * Manager pour le localStorage et persistance
 */
class StorageManager {
    static setItem(key, value, isSession = false) {
        try {
            const storage = isSession ? sessionStorage : localStorage;
            storage.setItem(key, JSON.stringify(value));
            return true;
        } catch (e) {
            console.error('Storage error:', e);
            return false;
        }
    }
    
    static getItem(key, isSession = false) {
        try {
            const storage = isSession ? sessionStorage : localStorage;
            const item = storage.getItem(key);
            return item ? JSON.parse(item) : null;
        } catch (e) {
            console.error('Storage error:', e);
            return null;
        }
    }
    
    static removeItem(key, isSession = false) {
        try {
            const storage = isSession ? sessionStorage : localStorage;
            storage.removeItem(key);
            return true;
        } catch (e) {
            console.error('Storage error:', e);
            return false;
        }
    }
    
    static clear(isSession = false) {
        try {
            const storage = isSession ? sessionStorage : localStorage;
            storage.clear();
            return true;
        } catch (e) {
            console.error('Storage error:', e);
            return false;
        }
    }
}

/**
 * Session state - données temporaires du jeu actuel
 */
class GameSessionState {
    constructor() {
        this.sessionId = generateUUID();
        this.userId = getUserId();
        this.playerName = getPlayerName();
        this.startTime = null;
        this.endTime = null;
        this.difficulty = 'normal';
        this.moves = 0;
        this.score = 0;
        this.matched = 0;
        this.isPaused = false;
        this.gameActive = false;
    }
    
    /**
     * Démarrer une nouvelle session
     */
    startSession(difficulty) {
        this.sessionId = generateUUID();
        this.startTime = Date.now();
        this.difficulty = difficulty;
        this.moves = 0;
        this.score = 0;
        this.matched = 0;
        this.gameActive = true;
        this.isPaused = false;
    }
    
    /**
     * Terminer la session
     */
    endSession() {
        this.endTime = Date.now();
        this.gameActive = false;
    }
    
    /**
     * Obtenir la durée en secondes
     */
    getDuration() {
        const end = this.endTime || Date.now();
        return Math.floor((end - this.startTime) / 1000);
    }
    
    /**
     * Sérialiser pour transmission
     */
    toJSON() {
        return {
            sessionId: this.sessionId,
            userId: this.userId,
            playerName: this.playerName,
            startTime: this.startTime,
            endTime: this.endTime,
            difficulty: this.difficulty,
            moves: this.moves,
            score: this.score,
            matched: this.matched,
            duration: this.getDuration()
        };
    }
}

/**
 * Gestionnaire des notifications
 */
class NotificationManager {
    static show(message, type = 'info', duration = 3000) {
        // Créer la notification
        const notification = document.createElement('div');
        notification.className = `notification notification-${type}`;
        notification.textContent = message;
        notification.style.cssText = `
            position: fixed;
            bottom: 20px;
            right: 20px;
            background: ${this.getTypeColor(type)};
            color: white;
            padding: 16px 24px;
            border-radius: 8px;
            font-family: 'Syne', sans-serif;
            font-size: 14px;
            font-weight: 600;
            z-index: 3000;
            animation: slideUp 0.3s ease-out;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
        `;
        
        document.body.appendChild(notification);
        
        // Auto-remove après durée
        setTimeout(() => {
            notification.style.animation = 'fadeOut 0.3s ease-out';
            setTimeout(() => notification.remove(), 300);
        }, duration);
    }
    
    static success(message) {
        this.show(message, 'success');
    }
    
    static error(message) {
        this.show(message, 'error');
    }
    
    static warning(message) {
        this.show(message, 'warning');
    }
    
    static info(message) {
        this.show(message, 'info');
    }
    
    static getTypeColor(type) {
        const colors = {
            success: '#4CAF50',
            error: '#F44336',
            warning: '#FF9800',
            info: '#2196F3'
        };
        return colors[type] || colors.info;
    }
}

/**
 * Gestionnaire des préférences utilisateur
 */
class PreferencesManager {
    static KEY_PREFERENCES = 'nextgn_preferences';
    
    static defaults = {
        soundEnabled: true,
        animationsEnabled: true,
        darkMode: false,
        showStats: true,
        notifications: true
    };
    
    static get() {
        const saved = localStorage.getItem(this.KEY_PREFERENCES);
        return saved ? JSON.parse(saved) : this.defaults;
    }
    
    static set(preferences) {
        localStorage.setItem(this.KEY_PREFERENCES, JSON.stringify(preferences));
        this.applyPreferences(preferences);
    }
    
    static update(key, value) {
        const prefs = this.get();
        prefs[key] = value;
        this.set(prefs);
    }
    
    static applyPreferences(prefs) {
        // Appliquer le dark mode
        if (prefs.darkMode) {
            document.body.style.colorScheme = 'dark';
        } else {
            document.body.style.colorScheme = 'light';
        }
        
        // Désactiver les animations si demandé
        if (!prefs.animationsEnabled) {
            document.documentElement.style.setProperty('--animation-duration', '0ms');
        }
    }
    
    static toggle(key) {
        const prefs = this.get();
        prefs[key] = !prefs[key];
        this.set(prefs);
        return prefs[key];
    }
}

// ============================================
// INITIALISATION DES SINGLETONS
// ============================================

// Créer une instance de session au chargement
const gameSession = new GameSessionState();

// Appliquer les préférences utilisateur
PreferencesManager.applyPreferences(PreferencesManager.get());

// Exporter pour utilisation globale
window.ScoringEngine = ScoringEngine;
window.StorageManager = StorageManager;
window.GameSessionState = GameSessionState;
window.NotificationManager = NotificationManager;
window.PreferencesManager = PreferencesManager;
