/* ============================================
   LEADERBOARD & PLAYER STATISTICS
   ============================================ */

/**
 * Manager du classement
 */
class LeaderboardManager {
    static KEY_LEADERBOARD = 'nextgn_leaderboard';
    static MAX_SCORES = 100;
    
    /**
     * Ajouter un score au classement
     */
    static addScore(gameData) {
        const scores = this.getAllScores();
        
        const newScore = {
            sessionId: generateUUID(),
            playerName: getPlayerName(),
            userId: getUserId(),
            score: gameData.score,
            moves: gameData.moves,
            timeSeconds: gameData.duration,
            difficulty: gameData.difficulty,
            date: new Date().toISOString(),
            isPerfect: gameData.moves === DIFFICULTY_MODES[gameData.difficulty].paires,
            won: gameData.won !== false
        };
        
        scores.push(newScore);
        
        // Limiter à MAX_SCORES (garder les plus récents)
        if (scores.length > this.MAX_SCORES) {
            scores.sort((a, b) => new Date(b.date) - new Date(a.date));
            scores.splice(this.MAX_SCORES);
        }
        
        localStorage.setItem(this.KEY_LEADERBOARD, JSON.stringify(scores));
        
        DEBUG.log('Score added:', newScore);
        
        return newScore;
    }
    
    /**
     * Obtenir tous les scores
     */
    static getAllScores() {
        try {
            const scores = JSON.parse(localStorage.getItem(this.KEY_LEADERBOARD)) || [];
            return scores;
        } catch (e) {
            console.error('Leaderboard error:', e);
            return [];
        }
    }
    
    /**
     * Obtenir le classement (top X)
     */
    static getLeaderboard(difficulty = 'all', limit = 10) {
        let scores = this.getAllScores();
        
        // Filtrer par difficulté
        if (difficulty !== 'all') {
            scores = scores.filter(s => s.difficulty === difficulty);
        }
        
        // Trier par score (décroissant)
        scores.sort((a, b) => {
            if (b.score !== a.score) {
                return b.score - a.score;
            }
            // En cas d'égalité, par temps
            return a.timeSeconds - b.timeSeconds;
        });
        
        return scores.slice(0, limit);
    }
    
    /**
     * Obtenir les stats d'un joueur
     */
    static getPlayerStats(userId) {
        const scores = this.getAllScores().filter(s => s.userId === userId);
        
        if (scores.length === 0) {
            return {
                totalGames: 0,
                bestScore: 0,
                averageScore: 0,
                averageTime: 0,
                bestTime: Infinity,
                winRate: 0,
                perfectGames: 0
            };
        }
        
        const bestScore = Math.max(...scores.map(s => s.score), 0);
        const totalScore = scores.reduce((a, b) => a + b.score, 0);
        const totalTime = scores.reduce((a, b) => a + b.timeSeconds, 0);
        const bestTime = Math.min(...scores.map(s => s.timeSeconds), Infinity);
        const perfectGames = scores.filter(s => s.isPerfect).length;
        const winRate = (perfectGames / scores.length) * 100;
        
        return {
            totalGames: scores.length,
            bestScore: bestScore,
            averageScore: Math.round(totalScore / scores.length),
            averageTime: Math.round(totalTime / scores.length),
            bestTime: bestTime === Infinity ? 0 : bestTime,
            winRate: Math.round(winRate),
            perfectGames: perfectGames
        };
    }
    
    /**
     * Obtenir le rang d'un score
     */
    static getPlayerRank(userId, difficulty = 'all') {
        const leaderboard = this.getLeaderboard(difficulty, Infinity);
        const rank = leaderboard.findIndex(s => s.userId === userId) + 1;
        return rank > 0 ? rank : null;
    }
    
    /**
     * Vérifier si c'est un nouveau record personnel
     */
    static isPersonalRecord(userId, newScore) {
        const stats = this.getPlayerStats(userId);
        return newScore > stats.bestScore;
    }
    
    /**
     * Obtenir les statistiques globales
     */
    static getGlobalStats() {
        const scores = this.getAllScores();
        
        if (scores.length === 0) {
            return {
                totalGames: 0,
                totalPlayers: 0,
                averageScore: 0,
                highestScore: 0,
                fastestCompletion: Infinity
            };
        }
        
        const uniquePlayers = new Set(scores.map(s => s.userId));
        const totalScore = scores.reduce((a, b) => a + b.score, 0);
        const highestScore = Math.max(...scores.map(s => s.score), 0);
        const fastestCompletion = Math.min(...scores.map(s => s.timeSeconds), Infinity);
        
        return {
            totalGames: scores.length,
            totalPlayers: uniquePlayers.size,
            averageScore: Math.round(totalScore / scores.length),
            highestScore: highestScore,
            fastestCompletion: fastestCompletion === Infinity ? 0 : fastestCompletion
        };
    }
    
    /**
     * Mettre à jour l'affichage du classement
     */
    static updateDisplay(difficulty = 'all') {
        const leaderboard = this.getLeaderboard(difficulty, 10);
        const leaderboardList = document.getElementById('leaderboard-list');
        
        if (!leaderboardList) return;
        
        if (leaderboard.length === 0) {
            leaderboardList.innerHTML = `
                <div class="empty-state">
                    <div class="empty-state-icon">🎮</div>
                    <div class="empty-state-text">Aucun score pour le moment</div>
                    <div class="empty-state-hint">Jouez une partie pour apparaître au classement!</div>
                </div>
            `;
            return;
        }
        
        leaderboardList.innerHTML = '';
        
        leaderboard.forEach((score, index) => {
            const rankItem = document.createElement('div');
            rankItem.className = 'rank-item';
            
            const rankNumber = this.getRankDisplay(index);
            const medal = index < 3 ? `class="rank-number medal-${index + 1}"` : 'class="rank-number"';
            
            rankItem.innerHTML = `
                <div ${medal}>${rankNumber}</div>
                <div class="rank-info">
                    <div class="player-name">${this.escapeHTML(score.playerName)}</div>
                    <div class="player-stats">
                        <span>⏱ ${formatTime(score.timeSeconds)}</span>
                        <span>🎯 ${score.moves} mouvements</span>
                        ${score.isPerfect ? '<span>✨ Parfait</span>' : ''}
                    </div>
                </div>
                <div class="rank-score">${formatNumber(score.score)}</div>
                <div class="rank-difficulty ${score.difficulty}">${DIFFICULTY_MODES[score.difficulty].name}</div>
            `;
            
            leaderboardList.appendChild(rankItem);
        });
        
        analyticsManager.track('leaderboard_viewed', { filter: difficulty });
    }
    
    /**
     * Mettre à jour les statistiques du joueur
     */
    static updatePlayerStats() {
        const userId = getUserId();
        const stats = this.getPlayerStats(userId);
        
        // Remplir les éléments HTML
        document.getElementById('total-games').textContent = stats.totalGames;
        document.getElementById('best-score').textContent = formatNumber(stats.bestScore);
        document.getElementById('best-time').textContent = stats.bestTime === Infinity ? '--' : formatTime(stats.bestTime);
        document.getElementById('win-rate').textContent = `${stats.winRate}%`;
        
        // Ajouter des classes pour animation si valeurs élevées
        if (stats.bestScore > 5000) {
            document.getElementById('best-score').parentElement.classList.add('high-value');
        }
        
        if (stats.winRate >= 50) {
            document.getElementById('win-rate').parentElement.classList.add('high-value');
        }
    }
    
    /**
     * Afficher le rang du joueur
     */
    static updatePlayerRank(difficulty = 'all') {
        const userId = getUserId();
        const rank = this.getPlayerRank(userId, difficulty);
        
        if (rank) {
            const rankDisplay = document.getElementById('player-rank');
            if (rankDisplay) {
                rankDisplay.textContent = `Vous êtes #{rank}`;
            }
        }
    }
    
    /**
     * Afficher les statistiques globales
     */
    static displayGlobalStats() {
        const globalStats = this.getGlobalStats();
        DEBUG.log('Global Statistics:', globalStats);
        
        return globalStats;
    }
    
    /**
     * Nettoyer les scores (DEBUG)
     */
    static clearAll() {
        if (confirm('Êtes-vous ABSOLUMENT certain de vouloir supprimer TOUS les scores?')) {
            localStorage.removeItem(this.KEY_LEADERBOARD);
            this.updateDisplay();
            this.updatePlayerStats();
            DEBUG.log('✓ Tous les scores ont été supprimés');
            return true;
        }
        return false;
    }
    
    /**
     * Exporter les scores en CSV
     */
    static exportCSV() {
        const scores = this.getAllScores();
        
        let csv = 'Rang,Joueur,Score,Difficulté,Temps (s),Mouvements,Parfait,Date\n';
        
        scores.forEach((score, index) => {
            csv += `${index + 1},"${score.playerName}",${score.score},"${score.difficulty}",${score.timeSeconds},${score.moves},${score.isPerfect ? 'Oui' : 'Non'},"${score.date}"\n`;
        });
        
        const blob = new Blob([csv], { type: 'text/csv' });
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.download = `leaderboard-${new Date().toISOString().slice(0, 10)}.csv`;
        link.click();
        URL.revokeObjectURL(url);
    }
    
    /**
     * Obtenir l'affichage du rang (numéro ou médaille)
     */
    static getRankDisplay(index) {
        const medals = ['🥇', '🥈', '🥉'];
        return medals[index] || `${index + 1}`;
    }
    
    /**
     * Échapper le HTML (sécurité)
     */
    static escapeHTML(str) {
        const div = document.createElement('div');
        div.textContent = str;
        return div.innerHTML;
    }
}

/**
 * Statistiques avancées
 */
class AdvancedStats {
    /**
     * Obtenir la distribution des scores par difficulté
     */
    static getDistributionByDifficulty() {
        const scores = LeaderboardManager.getAllScores();
        const distribution = {};
        
        Object.keys(DIFFICULTY_MODES).forEach(difficulty => {
            distribution[difficulty] = scores.filter(s => s.difficulty === difficulty).length;
        });
        
        return distribution;
    }
    
    /**
     * Obtenir la tendance temporelle
     */
    static getTimelineTrend(days = 7) {
        const scores = LeaderboardManager.getAllScores();
        const now = new Date();
        const timeline = {};
        
        for (let i = 0; i < days; i++) {
            const date = new Date(now);
            date.setDate(date.getDate() - i);
            const dateStr = date.toISOString().slice(0, 10);
            timeline[dateStr] = scores.filter(s => s.date.slice(0, 10) === dateStr).length;
        }
        
        return timeline;
    }
    
    /**
     * Obtenir la moyenne de temps par difficulté
     */
    static getAverageTimeByDifficulty() {
        const scores = LeaderboardManager.getAllScores();
        const averages = {};
        
        Object.keys(DIFFICULTY_MODES).forEach(difficulty => {
            const diffScores = scores.filter(s => s.difficulty === difficulty);
            if (diffScores.length > 0) {
                const totalTime = diffScores.reduce((a, b) => a + b.timeSeconds, 0);
                averages[difficulty] = Math.round(totalTime / diffScores.length);
            }
        });
        
        return averages;
    }
    
    /**
     * Taux de réussite global
     */
    static getGlobalSuccessRate() {
        const scores = LeaderboardManager.getAllScores();
        if (scores.length === 0) return 0;
        
        const perfectGames = scores.filter(s => s.isPerfect).length;
        return Math.round((perfectGames / scores.length) * 100);
    }
}

// ============================================
// INITIALISATION
// ============================================

// Exporter pour utilisation globale
window.LeaderboardManager = LeaderboardManager;
window.AdvancedStats = AdvancedStats;

DEBUG.log('Leaderboard Manager initialized');
