import Module from '../core/Module.js';
import ttsService from '../services/TTSService.js';

/**
 * WhackAMoleHard - Advanced version with multiple moles per wave
 * Hard mode features:
 * - 5x3 grid (15 holes)
 * - 3 moles per wave instead of 1
 * - Faster spawn rate
 * - Shorter display time
 * - Target word guarantee system (appears within 10 spawns)
 */
class WhackAMoleHard extends Module {
    constructor(name, dependencies, config = {}) {
        super(name || 'whack-a-mole-hard', ['eventBus']);

        // Validate dependencies
        if (!dependencies.eventBus) {
            throw new Error('WhackAMoleHard requires EventBus dependency');
        }

        // Ensure name is always defined
        if (!this.name) {
            this.name = 'whack-a-mole-hard';
        }

        this._eventBus = dependencies.eventBus;
        this._content = dependencies.content;
        this._config = {
            container: null,
            ...config
        };

        // Game state
        this._score = 0;
        this._errors = 0;
        this._maxErrors = 3;
        this._gameTime = 60; // 60 seconds
        this._timeLeft = this._gameTime;
        this._isRunning = false;
        this._gameMode = 'translation';
        this._showPronunciation = false;

        // Mole configuration (HARD MODE)
        this._holes = [];
        this._activeMoles = [];
        this._moleAppearTime = 3000; // 3 seconds display time (longer for hard mode)
        this._spawnRate = 2000; // New wave every 2 seconds
        this._molesPerWave = 3; // 3 moles per wave (HARD MODE)

        // Timers
        this._gameTimer = null;
        this._spawnTimer = null;

        // Vocabulary and game content
        this._vocabulary = [];
        this._currentWords = [];
        this._targetWord = null;

        // Target word guarantee system
        this._spawnsSinceTarget = 0;
        this._maxSpawnsWithoutTarget = 10; // Target word must appear in the next 10 moles

        // DOM references
        this._container = null;
        this._gameBoard = null;
        this._feedbackArea = null;

        // CSS injection
        this._cssInjected = false;

        Object.seal(this);
    }

    async init() {
        this._validateNotDestroyed();

        // Validate container
        if (!this._config.container) {
            throw new Error('Game container is required');
        }

        // Set up event listeners
        this._eventBus.on('whack-hard:start', this._handleStart.bind(this), this.name);
        this._eventBus.on('whack-hard:pause', this._handlePause.bind(this), this.name);
        this._eventBus.on('whack-hard:restart', this._handleRestart.bind(this), this.name);
        this._eventBus.on('whack-hard:toggle-pronunciation', this._handleTogglePronunciation.bind(this), this.name);

        // Start game immediately
        try {
            this._container = this._config.container;
            const content = this._content;

            // Extract vocabulary from content
            this._vocabulary = this._extractVocabulary(content);

            if (this._vocabulary.length === 0) {
                this._showInitError();
                return;
            }

            // Inject CSS
            this._injectCSS();

            // Create game interface
            this._createGameBoard();
            this._setupEventListeners();

            // Emit game ready event
            this._eventBus.emit('game:ready', {
                gameId: 'whack-a-mole-hard',
                instanceId: this.name,
                vocabulary: this._vocabulary.length
            }, this.name);

        } catch (error) {
            console.error('Error starting Whack A Mole Hard:', error);
            this._showInitError();
        }

        this._setInitialized();
    }

    async destroy() {
        this._validateNotDestroyed();

        // Stop game and cleanup
        this._stopGame();

        // Remove injected CSS
        this._removeCSS();

        // Clear DOM
        if (this._container) {
            this._container.innerHTML = '';
        }

        this._setDestroyed();
    }

    // Public interface methods
    render(container, content) {
        this._validateInitialized();

        this._container = container;
        this._content = content;

        // Extract vocabulary from content
        this._vocabulary = this._extractVocabulary(content);

        if (this._vocabulary.length === 0) {
            this._showInitError();
            return;
        }

        // Inject CSS
        this._injectCSS();

        // Create game interface
        this._createGameBoard();
        this._setupEventListeners();
    }

    startGame() {
        this._validateInitialized();
        this._start();
    }

    pauseGame() {
        this._validateInitialized();
        this._pause();
    }

    restartGame() {
        this._validateInitialized();
        this._restart();
    }

    // Private implementation methods
    _injectCSS() {
        if (this._cssInjected) return;

        const styleSheet = document.createElement('style');
        styleSheet.id = 'whack-hard-styles';
        styleSheet.textContent = `
            .whack-game-wrapper {
                display: flex;
                flex-direction: column;
                align-items: center;
                padding: 20px;
                max-width: 1200px;
                margin: 0 auto;
                font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
            }

            .mode-selector {
                display: flex;
                gap: 10px;
                margin-bottom: 20px;
            }

            .mode-btn {
                padding: 10px 20px;
                border: 2px solid #e5e7eb;
                border-radius: 8px;
                background: white;
                cursor: pointer;
                font-size: 14px;
                font-weight: 500;
                transition: all 0.2s;
            }

            .mode-btn:hover {
                border-color: #3b82f6;
                transform: translateY(-2px);
            }

            .mode-btn.active {
                background: #3b82f6;
                color: white;
                border-color: #3b82f6;
            }

            .game-info {
                display: flex;
                flex-direction: column;
                justify-content: center;
                align-items: center;
                gap: clamp(12px, 3vw, 20px);
                width: 100%;
                max-width: 100%;
                margin-bottom: clamp(15px, 4vw, 30px);
                padding: clamp(12px, 3vw, 20px);
                background: #f8fafc;
                border-radius: 12px;
                box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
            }

            .game-stats {
                display: flex;
                gap: clamp(15px, 3vw, 30px);
                flex-wrap: wrap;
                justify-content: center;
                width: 100%;
            }

            .stat-item {
                text-align: center;
                min-width: clamp(60px, 20vw, 100px);
            }

            .stat-value {
                display: block;
                font-size: clamp(18px, 4vw, 24px);
                font-weight: bold;
                color: #1f2937;
                margin-bottom: 5px;
            }

            .stat-label {
                font-size: clamp(10px, 2vw, 12px);
                color: #6b7280;
                text-transform: uppercase;
                letter-spacing: 0.5px;
            }

            .game-controls {
                display: flex;
                gap: 10px;
            }

            .control-btn {
                padding: 8px 16px;
                border: none;
                border-radius: 6px;
                background: #3b82f6;
                color: white;
                cursor: pointer;
                font-size: 14px;
                font-weight: 500;
                transition: all 0.2s;
            }

            .control-btn:hover:not(:disabled) {
                background: #2563eb;
                transform: translateY(-1px);
            }

            .control-btn:disabled {
                background: #9ca3af;
                cursor: not-allowed;
                transform: none;
            }

            .control-btn.active {
                background: #10b981;
            }

            .whack-game-board.hard-mode {
                display: grid;
                grid-template-columns: repeat(5, 1fr);
                grid-template-rows: repeat(3, 1fr);
                gap: 15px;
                padding: 30px;
                background: #1f2937;
                border-radius: 20px;
                box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
                margin-bottom: 30px;
                width: 100%;
                max-width: 800px;
                aspect-ratio: 5/3;
            }

            .whack-hole {
                position: relative;
                background: #374151;
                border-radius: 50%;
                box-shadow: inset 0 4px 8px rgba(0, 0, 0, 0.3);
                cursor: pointer;
                overflow: hidden;
                transition: all 0.2s;
            }

            .whack-hole:hover {
                transform: scale(1.05);
            }

            .whack-mole {
                position: absolute;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                background: linear-gradient(45deg, #3b82f6, #1d4ed8);
                color: white;
                padding: 8px 12px;
                border-radius: 12px;
                font-size: 14px;
                font-weight: bold;
                text-align: center;
                box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4);
                opacity: 0;
                transform: translate(-50%, -50%) scale(0);
                transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
                cursor: pointer;
                max-width: 90%;
                word-wrap: break-word;
            }

            .whack-mole.active {
                opacity: 1;
                transform: translate(-50%, -50%) scale(1);
            }

            .whack-mole.hit {
                background: linear-gradient(45deg, #10b981, #059669);
                animation: hitAnimation 0.5s ease;
            }

            @keyframes hitAnimation {
                0% { transform: translate(-50%, -50%) scale(1); }
                50% { transform: translate(-50%, -50%) scale(1.2); }
                100% { transform: translate(-50%, -50%) scale(1); }
            }

            .whack-mole .pronunciation {
                font-size: 0.8em;
                color: #93c5fd;
                font-style: italic;
                margin-bottom: 5px;
                font-weight: 500;
            }

            .whack-mole .word {
                font-size: 1em;
                font-weight: bold;
            }

            .feedback-area {
                width: 100%;
                max-width: 800px;
                min-height: 60px;
                display: flex;
                align-items: center;
                justify-content: center;
                padding: 20px;
                border-radius: 12px;
                background: #f8fafc;
                border: 2px solid #e5e7eb;
            }

            .instruction {
                font-size: 16px;
                font-weight: 500;
                text-align: center;
                color: #374151;
            }

            .instruction.info {
                color: #3b82f6;
                border-color: #3b82f6;
            }

            .instruction.success {
                color: #10b981;
                background: #ecfdf5;
                border-color: #10b981;
            }

            .instruction.error {
                color: #ef4444;
                background: #fef2f2;
                border-color: #ef4444;
            }

            .score-popup {
                position: fixed;
                pointer-events: none;
                font-size: 18px;
                font-weight: bold;
                padding: 8px 16px;
                border-radius: 8px;
                color: white;
                z-index: 1000;
                animation: scorePopup 1s ease-out forwards;
            }

            .score-popup.correct-answer {
                background: #10b981;
            }

            .score-popup.wrong-answer {
                background: #ef4444;
            }

            @keyframes scorePopup {
                0% {
                    opacity: 1;
                    transform: translateY(0);
                }
                100% {
                    opacity: 0;
                    transform: translateY(-50px);
                }
            }

            .game-error {
                text-align: center;
                padding: 40px;
                background: #fef2f2;
                border: 2px solid #ef4444;
                border-radius: 12px;
                color: #dc2626;
            }

            .game-error h3 {
                margin: 0 0 16px 0;
                font-size: 20px;
            }

            .game-error p {
                margin: 8px 0;
                color: #7f1d1d;
            }

            .back-btn {
                padding: 12px 24px;
                background: #3b82f6;
                color: white;
                border: none;
                border-radius: 8px;
                font-weight: 500;
                cursor: pointer;
                margin-top: 20px;
            }

            .back-btn:hover {
                background: #2563eb;
            }

            /* Responsive design */
            @media (max-width: 768px) {
                .whack-game-board.hard-mode {
                    max-width: 95%;
                    gap: 10px;
                    padding: 20px;
                }

                .game-info {
                    flex-direction: column;
                    gap: 20px;
                    text-align: center;
                }

                .game-controls {
                    justify-content: center;
                }

                .whack-mole {
                    font-size: 12px;
                    padding: 6px 10px;
                }
            }

            /* Victory Popup Styles */
            .victory-popup {
                position: fixed;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                background: rgba(0, 0, 0, 0.8);
                display: flex;
                align-items: center;
                justify-content: center;
                z-index: 10000;
                animation: fadeIn 0.3s ease-out;
            }

            .victory-content {
                background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                border-radius: 20px;
                padding: 40px;
                text-align: center;
                color: white;
                max-width: 500px;
                width: 90%;
                box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
                animation: slideUp 0.4s ease-out;
            }

            .victory-header {
                margin-bottom: 30px;
            }

            .victory-icon {
                font-size: 4rem;
                margin-bottom: 15px;
                animation: bounce 0.6s ease-out;
            }

            .victory-title {
                font-size: 2rem;
                font-weight: bold;
                margin: 0 0 10px 0;
                text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
            }

            .new-best-badge {
                background: linear-gradient(45deg, #f093fb 0%, #f5576c 100%);
                color: white;
                padding: 8px 20px;
                border-radius: 25px;
                font-size: 0.9rem;
                font-weight: bold;
                display: inline-block;
                margin-top: 10px;
                animation: glow 1s ease-in-out infinite alternate;
            }

            .victory-scores {
                display: flex;
                justify-content: space-around;
                margin: 30px 0;
                gap: 20px;
            }

            .score-display {
                background: rgba(255, 255, 255, 0.1);
                border-radius: 15px;
                padding: 20px;
                flex: 1;
                backdrop-filter: blur(10px);
                border: 1px solid rgba(255, 255, 255, 0.2);
            }

            .score-label {
                font-size: 0.9rem;
                opacity: 0.9;
                margin-bottom: 8px;
                text-transform: uppercase;
                letter-spacing: 1px;
            }

            .score-value {
                font-size: 2rem;
                font-weight: bold;
                text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
            }

            .victory-stats {
                background: rgba(255, 255, 255, 0.1);
                border-radius: 15px;
                padding: 20px;
                margin: 30px 0;
                backdrop-filter: blur(10px);
                border: 1px solid rgba(255, 255, 255, 0.2);
            }

            .stat-row {
                display: flex;
                justify-content: space-between;
                align-items: center;
                padding: 8px 0;
                border-bottom: 1px solid rgba(255, 255, 255, 0.1);
            }

            .stat-row:last-child {
                border-bottom: none;
            }

            .stat-name {
                font-size: 0.95rem;
                opacity: 0.9;
            }

            .stat-value {
                font-weight: bold;
                font-size: 1rem;
            }

            .victory-buttons {
                display: flex;
                flex-direction: column;
                gap: 12px;
                margin-top: 30px;
            }

            .victory-btn {
                padding: 15px 30px;
                border: none;
                border-radius: 25px;
                font-size: 1rem;
                font-weight: bold;
                cursor: pointer;
                transition: all 0.3s ease;
                text-transform: uppercase;
                letter-spacing: 1px;
            }

            .victory-btn.primary {
                background: linear-gradient(45deg, #4facfe 0%, #00f2fe 100%);
                color: white;
                box-shadow: 0 8px 25px rgba(79, 172, 254, 0.3);
            }

            .victory-btn.primary:hover {
                transform: translateY(-2px);
                box-shadow: 0 12px 35px rgba(79, 172, 254, 0.4);
            }

            .victory-btn.secondary {
                background: linear-gradient(45deg, #a8edea 0%, #fed6e3 100%);
                color: #333;
                box-shadow: 0 8px 25px rgba(168, 237, 234, 0.3);
            }

            .victory-btn.secondary:hover {
                transform: translateY(-2px);
                box-shadow: 0 12px 35px rgba(168, 237, 234, 0.4);
            }

            .victory-btn.tertiary {
                background: rgba(255, 255, 255, 0.2);
                color: white;
                border: 2px solid rgba(255, 255, 255, 0.3);
                backdrop-filter: blur(10px);
            }

            .victory-btn.tertiary:hover {
                background: rgba(255, 255, 255, 0.3);
                transform: translateY(-2px);
            }

            @keyframes fadeIn {
                from { opacity: 0; }
                to { opacity: 1; }
            }

            @keyframes slideUp {
                from {
                    opacity: 0;
                    transform: translateY(30px) scale(0.9);
                }
                to {
                    opacity: 1;
                    transform: translateY(0) scale(1);
                }
            }

            @keyframes bounce {
                0%, 20%, 50%, 80%, 100% {
                    transform: translateY(0);
                }
                40% {
                    transform: translateY(-10px);
                }
                60% {
                    transform: translateY(-5px);
                }
            }

            @keyframes glow {
                from {
                    box-shadow: 0 0 20px rgba(245, 87, 108, 0.5);
                }
                to {
                    box-shadow: 0 0 30px rgba(245, 87, 108, 0.8);
                }
            }

            @media (max-width: 768px) {
                .victory-content {
                    padding: 30px 20px;
                    width: 95%;
                }

                .victory-scores {
                    flex-direction: column;
                    gap: 15px;
                }

                .victory-icon {
                    font-size: 3rem;
                }

                .victory-title {
                    font-size: 1.5rem;
                }

                .victory-buttons {
                    gap: 10px;
                }

                .victory-btn {
                    padding: 12px 25px;
                    font-size: 0.9rem;
                }
            }
        `;
        document.head.appendChild(styleSheet);
        this._cssInjected = true;
    }

    _removeCSS() {
        const styleSheet = document.getElementById('whack-hard-styles');
        if (styleSheet) {
            styleSheet.remove();
            this._cssInjected = false;
        }
    }

    _createGameBoard() {
        this._container.innerHTML = `
            <div class="whack-game-wrapper">
                <!-- Mode Selection -->
                <div class="mode-selector">
                    <button class="mode-btn active" data-mode="translation">
                        🔤 Translation
                    </button>
                    <button class="mode-btn" data-mode="image">
                        🖼️ Image (soon)
                    </button>
                    <button class="mode-btn" data-mode="sound">
                        🔊 Sound (soon)
                    </button>
                </div>

                <!-- Game Info -->
                <div class="game-info">
                    <div class="game-stats">
                        <div class="stat-item">
                            <span class="stat-value" id="time-left">${this._timeLeft}</span>
                            <span class="stat-label">Time</span>
                        </div>
                        <div class="stat-item">
                            <span class="stat-value" id="errors-count">${this._errors}</span>
                            <span class="stat-label">Errors</span>
                        </div>
                        <div class="stat-item">
                            <span class="stat-value" id="target-word">---</span>
                            <span class="stat-label">Find</span>
                        </div>
                    </div>
                    <div class="game-controls">
                        <button class="control-btn" id="pronunciation-btn" title="Toggle pronunciation">🔊 Pronunciation</button>
                        <button class="control-btn" id="start-btn">🎮 Start</button>
                        <button class="control-btn" id="pause-btn" disabled>⏸️ Pause</button>
                        <button class="control-btn" id="restart-btn">🔄 Restart</button>
                    </div>
                </div>

                <!-- Game Board -->
                <div class="whack-game-board hard-mode" id="game-board">
                    <!-- 15 holes will be generated here (5x3 grid) -->
                </div>

                <!-- Feedback Area -->
                <div class="feedback-area" id="feedback-area">
                    <div class="instruction">
                        Select a mode and click Start!
                    </div>
                </div>
            </div>
        `;

        this._gameBoard = this._container.querySelector('#game-board');
        this._feedbackArea = this._container.querySelector('#feedback-area');
        this._createHoles();
    }

    _createHoles() {
        this._gameBoard.innerHTML = '';
        this._holes = [];

        for (let i = 0; i < 15; i++) { // 5x3 = 15 holes for hard mode
            const hole = document.createElement('div');
            hole.className = 'whack-hole';
            hole.dataset.holeId = i;

            hole.innerHTML = `
                <div class="whack-mole" data-hole="${i}">
                    <div class="pronunciation" style="display: none;"></div>
                    <div class="word"></div>
                </div>
            `;

            this._gameBoard.appendChild(hole);
            this._holes.push({
                element: hole,
                mole: hole.querySelector('.whack-mole'),
                wordElement: hole.querySelector('.word'),
                pronunciationElement: hole.querySelector('.pronunciation'),
                isActive: false,
                word: null,
                timer: null
            });
        }
    }

    _setupEventListeners() {
        // Mode selection
        this._container.querySelectorAll('.mode-btn').forEach(btn => {
            btn.addEventListener('click', (e) => {
                if (this._isRunning) return;

                this._container.querySelectorAll('.mode-btn').forEach(b => b.classList.remove('active'));
                btn.classList.add('active');
                this._gameMode = btn.dataset.mode;

                if (this._gameMode !== 'translation') {
                    this._showFeedback('This mode will be available soon!', 'info');
                    // Return to translation mode
                    this._container.querySelector('.mode-btn[data-mode="translation"]').classList.add('active');
                    btn.classList.remove('active');
                    this._gameMode = 'translation';
                }
            });
        });

        // Game controls
        this._container.querySelector('#pronunciation-btn').addEventListener('click', () => this._togglePronunciation());
        this._container.querySelector('#start-btn').addEventListener('click', () => this._start());
        this._container.querySelector('#pause-btn').addEventListener('click', () => this._pause());
        this._container.querySelector('#restart-btn').addEventListener('click', () => this._restart());

        // Mole clicks - click on hole OR mole text
        this._holes.forEach((hole, index) => {
            // Click on the entire hole (easier to target)
            hole.element.addEventListener('click', () => this._hitMole(index));
        });
    }

    _start() {
        if (this._isRunning) return;

        this._isRunning = true;
        this._score = 0;
        this._errors = 0;
        this._timeLeft = this._gameTime;

        this._updateUI();
        this._setNewTarget();
        this._startTimers();

        this._container.querySelector('#start-btn').disabled = true;
        this._container.querySelector('#pause-btn').disabled = false;

        this._showFeedback(`Find the word: "${this._targetWord.translation}"`, 'info');

        // Notify EventBus
        this._eventBus.emit('whack-hard:game-started', {
            mode: this._gameMode,
            vocabulary: this._vocabulary.length,
            difficulty: 'hard'
        }, this.name);
    }

    _pause() {
        if (!this._isRunning) return;

        this._isRunning = false;
        this._stopTimers();
        this._hideAllMoles();

        this._container.querySelector('#start-btn').disabled = false;
        this._container.querySelector('#pause-btn').disabled = true;

        this._showFeedback('Game paused', 'info');

        this._eventBus.emit('whack-hard:game-paused', { score: this._score }, this.name);
    }

    _restart() {
        this._stopGame();
        this._resetGame();
        setTimeout(() => this._start(), 100);
    }

    _togglePronunciation() {
        this._showPronunciation = !this._showPronunciation;
        const btn = this._container.querySelector('#pronunciation-btn');

        if (this._showPronunciation) {
            btn.textContent = '🔊 Pronunciation ON';
            btn.classList.add('active');
        } else {
            btn.textContent = '🔊 Pronunciation OFF';
            btn.classList.remove('active');
        }

        this._updateMoleDisplay();
    }

    _updateMoleDisplay() {
        this._holes.forEach(hole => {
            if (hole.isActive && hole.word) {
                if (this._showPronunciation && hole.word.pronunciation) {
                    hole.pronunciationElement.textContent = hole.word.pronunciation;
                    hole.pronunciationElement.style.display = 'block';
                } else {
                    hole.pronunciationElement.style.display = 'none';
                }
            }
        });
    }

    _stopGame() {
        this._isRunning = false;
        this._stopTimers();
        this._hideAllMoles();

        this._container.querySelector('#start-btn').disabled = false;
        this._container.querySelector('#pause-btn').disabled = true;
    }

    _resetGame() {
        this._stopGame();

        this._score = 0;
        this._errors = 0;
        this._timeLeft = this._gameTime;
        this._targetWord = null;
        this._activeMoles = [];
        this._spawnsSinceTarget = 0;

        this._updateUI();
        this._container.querySelector('#target-word').textContent = '---';
        this._showFeedback('Select a mode and click Start!', 'info');

        // Clear all holes
        this._holes.forEach(hole => {
            if (hole.timer) {
                clearTimeout(hole.timer);
                hole.timer = null;
            }
            hole.isActive = false;
            hole.word = null;
            if (hole.wordElement) hole.wordElement.textContent = '';
            if (hole.pronunciationElement) {
                hole.pronunciationElement.textContent = '';
                hole.pronunciationElement.style.display = 'none';
            }
            if (hole.mole) hole.mole.classList.remove('active', 'hit');
        });
    }

    _startTimers() {
        // Main game timer
        this._gameTimer = setInterval(() => {
            this._timeLeft--;
            this._updateUI();

            if (this._timeLeft <= 0 && this._isRunning) {
                this._endGame();
            }
        }, 1000);

        // Mole spawn timer
        this._spawnTimer = setInterval(() => {
            if (this._isRunning) {
                this._spawnMole();
            }
        }, this._spawnRate);

        // First immediate mole wave
        setTimeout(() => this._spawnMole(), 500);
    }

    _stopTimers() {
        if (this._gameTimer) {
            clearInterval(this._gameTimer);
            this._gameTimer = null;
        }
        if (this._spawnTimer) {
            clearInterval(this._spawnTimer);
            this._spawnTimer = null;
        }
    }

    _spawnMole() {
        // Hard mode: Spawn multiple moles at once
        this._spawnMultipleMoles();
    }

    _spawnMultipleMoles() {
        // Find all free holes
        const availableHoles = this._holes.filter(hole => !hole.isActive);

        // Spawn up to molesPerWave moles
        const molesToSpawn = Math.min(this._molesPerWave, availableHoles.length);

        if (molesToSpawn === 0) return;

        // Shuffle available holes
        const shuffledHoles = this._shuffleArray(availableHoles);

        // Spawn the moles
        for (let i = 0; i < molesToSpawn; i++) {
            const hole = shuffledHoles[i];
            const holeIndex = this._holes.indexOf(hole);

            // Choose a word according to guarantee strategy
            const word = this._getWordWithTargetGuarantee();

            // Activate the mole with a small delay for visual effect
            setTimeout(() => {
                if (this._isRunning && !hole.isActive) {
                    this._activateMole(holeIndex, word);
                }
            }, i * 200); // 200ms delay between each mole
        }
    }

    _getWordWithTargetGuarantee() {
        // Increment spawn counter since last target word
        this._spawnsSinceTarget++;

        // If we've reached the limit, force the target word
        if (this._spawnsSinceTarget >= this._maxSpawnsWithoutTarget) {
            this._spawnsSinceTarget = 0;
            return this._targetWord;
        }

        // Otherwise, 10% chance for target word (1/10 instead of 1/2)
        if (Math.random() < 0.1) {
            this._spawnsSinceTarget = 0;
            return this._targetWord;
        } else {
            return this._getRandomWord();
        }
    }

    _activateMole(holeIndex, word) {
        const hole = this._holes[holeIndex];
        if (hole.isActive) return;

        hole.isActive = true;
        hole.word = word;
        hole.wordElement.textContent = word.original;

        // Show pronunciation if enabled and available
        if (this._showPronunciation && word.pronunciation) {
            hole.pronunciationElement.textContent = word.pronunciation;
            hole.pronunciationElement.style.display = 'block';
        } else {
            hole.pronunciationElement.style.display = 'none';
        }

        hole.mole.classList.add('active');
        this._activeMoles.push(holeIndex);

        // Timer to make the mole disappear
        hole.timer = setTimeout(() => {
            this._deactivateMole(holeIndex);
        }, this._moleAppearTime);
    }

    _deactivateMole(holeIndex) {
        const hole = this._holes[holeIndex];
        if (!hole.isActive) return;

        hole.isActive = false;
        hole.word = null;
        hole.wordElement.textContent = '';
        hole.pronunciationElement.textContent = '';
        hole.pronunciationElement.style.display = 'none';
        hole.mole.classList.remove('active');

        if (hole.timer) {
            clearTimeout(hole.timer);
            hole.timer = null;
        }

        // Remove from active moles list
        const activeIndex = this._activeMoles.indexOf(holeIndex);
        if (activeIndex > -1) {
            this._activeMoles.splice(activeIndex, 1);
        }
    }

    _hitMole(holeIndex) {
        if (!this._isRunning) return;

        const hole = this._holes[holeIndex];
        if (!hole.isActive || !hole.word) return;

        const isCorrect = hole.word.translation === this._targetWord.translation;

        if (isCorrect) {
            // Correct answer
            this._score += 10;

            // Speak the word (pronounce it)
            this._speakWord(hole.word.original);

            this._deactivateMole(holeIndex);
            this._setNewTarget();
            this._showScorePopup(holeIndex, '+10', true);
            this._showFeedback(`Well done! Now find: "${this._targetWord.translation}"`, 'success');

            // Success animation
            hole.mole.classList.add('hit');
            setTimeout(() => hole.mole.classList.remove('hit'), 500);

            this._eventBus.emit('whack-hard:correct-hit', {
                word: hole.word,
                score: this._score
            }, this.name);

        } else {
            // Wrong answer
            this._errors++;
            this._score = Math.max(0, this._score - 2);
            this._showScorePopup(holeIndex, '-2', false);
            this._showFeedback(`Oops! "${hole.word.translation}" ≠ "${this._targetWord.translation}"`, 'error');

            this._eventBus.emit('whack-hard:wrong-hit', {
                expected: this._targetWord,
                actual: hole.word,
                errors: this._errors
            }, this.name);
        }

        this._updateUI();

        // Check game end by errors
        if (this._errors >= this._maxErrors) {
            this._showFeedback('Too many errors! Game over.', 'error');
            setTimeout(() => {
                if (this._isRunning) {
                    this._endGame();
                }
            }, 1500);
        }
    }

    _setNewTarget() {
        // Choose a new target word
        const availableWords = this._vocabulary.filter(word =>
            !this._activeMoles.some(moleIndex =>
                this._holes[moleIndex].word &&
                this._holes[moleIndex].word.original === word.original
            )
        );

        if (availableWords.length > 0) {
            this._targetWord = availableWords[Math.floor(Math.random() * availableWords.length)];
        } else {
            this._targetWord = this._vocabulary[Math.floor(Math.random() * this._vocabulary.length)];
        }

        // Reset counter for new target word
        this._spawnsSinceTarget = 0;

        this._container.querySelector('#target-word').textContent = this._targetWord.translation;

        this._eventBus.emit('whack-hard:new-target', { target: this._targetWord }, this.name);
    }

    _getRandomWord() {
        return this._vocabulary[Math.floor(Math.random() * this._vocabulary.length)];
    }

    _hideAllMoles() {
        this._holes.forEach((hole, index) => {
            if (hole.isActive) {
                this._deactivateMole(index);
            }
        });
        this._activeMoles = [];
    }

    _showScorePopup(holeIndex, scoreText, isPositive) {
        const hole = this._holes[holeIndex];
        const popup = document.createElement('div');
        popup.className = `score-popup ${isPositive ? 'correct-answer' : 'wrong-answer'}`;
        popup.textContent = scoreText;

        const rect = hole.element.getBoundingClientRect();
        popup.style.left = rect.left + rect.width / 2 + 'px';
        popup.style.top = rect.top + 'px';

        document.body.appendChild(popup);

        setTimeout(() => {
            if (popup.parentNode) {
                popup.parentNode.removeChild(popup);
            }
        }, 1000);
    }

    _showFeedback(message, type = 'info') {
        this._feedbackArea.innerHTML = `<div class="instruction ${type}">${message}</div>`;
    }

    _updateUI() {
        this._container.querySelector('#time-left').textContent = this._timeLeft;
        this._container.querySelector('#errors-count').textContent = this._errors;
    }

    _endGame() {
        this._stopGame();

        // Calculate stats for victory popup
        const duration = this._gameTime - this._timeLeft;
        const accuracy = this._score > 0 ? Math.round(((this._score / 10) / (this._score / 10 + this._errors)) * 100) : 0;
        const hitRate = Math.round((this._score / 10) || 0); // since each hit = 10 points

        // Handle localStorage best score
        const currentScore = this._score;
        const bestScore = parseInt(localStorage.getItem('whack-hard-best-score') || '0');
        const isNewBest = currentScore > bestScore;

        if (isNewBest) {
            localStorage.setItem('whack-hard-best-score', currentScore.toString());
        }

        this._showVictoryPopup({
            gameTitle: 'Whack-A-Mole Hard',
            currentScore,
            bestScore: isNewBest ? currentScore : bestScore,
            isNewBest,
            stats: {
                'Accuracy': `${accuracy}%`,
                'Successful Hits': hitRate,
                'Errors': `${this._errors}/${this._maxErrors}`,
                'Duration': `${duration}s`
            }
        });
    }

    _showInitError() {
        this._container.innerHTML = `
            <div class="game-error">
                <h3>❌ Loading Error</h3>
                <p>This content does not contain vocabulary compatible with Whack-a-Mole Hard.</p>
                <p>The game requires words with their translations.</p>
                <button onclick="window.app?.getCore().router.navigate('/games')" class="back-btn">← Back to Games</button>
            </div>
        `;
    }

    _extractVocabulary(content) {
        let vocabulary = [];

        // Use content from dependency injection
        if (!content) {
            return this._getDemoVocabulary();
        }

        // Priority 1: Ultra-modular format (vocabulary object)
        if (content.vocabulary && typeof content.vocabulary === 'object' && !Array.isArray(content.vocabulary)) {
            vocabulary = Object.entries(content.vocabulary).map(([word, data]) => {
                if (typeof data === 'object' && data.user_language) {
                    return {
                        original: word,
                        translation: data.user_language.split('；')[0],
                        fullTranslation: data.user_language,
                        type: data.type || 'general',
                        audio: data.audio,
                        image: data.image,
                        examples: data.examples,
                        pronunciation: data.pronunciation,
                        category: data.type || 'general'
                    };
                } else if (typeof data === 'string') {
                    return {
                        original: word,
                        translation: data.split('；')[0],
                        fullTranslation: data,
                        type: 'general',
                        category: 'general'
                    };
                }
                return null;
            }).filter(Boolean);
        }

        // Priority 2: Legacy formats support
        if (vocabulary.length === 0 && content.sentences) {
            vocabulary = content.sentences.map(sentence => ({
                original: sentence.english || sentence.chinese || '',
                translation: sentence.chinese || sentence.english || '',
                pronunciation: sentence.prononciation || sentence.pronunciation
            })).filter(word => word.original && word.translation);
        }

        return this._finalizeVocabulary(vocabulary);
    }

    _finalizeVocabulary(vocabulary) {
        // Validation and cleanup
        vocabulary = vocabulary.filter(word =>
            word &&
            typeof word.original === 'string' &&
            typeof word.translation === 'string' &&
            word.original.trim() !== '' &&
            word.translation.trim() !== ''
        );

        if (vocabulary.length === 0) {
            vocabulary = this._getDemoVocabulary();
        }

        return this._shuffleArray(vocabulary);
    }

    _getDemoVocabulary() {
        return [
            { original: 'hello', translation: 'bonjour', category: 'greetings' },
            { original: 'goodbye', translation: 'au revoir', category: 'greetings' },
            { original: 'thank you', translation: 'merci', category: 'greetings' },
            { original: 'cat', translation: 'chat', category: 'animals' },
            { original: 'dog', translation: 'chien', category: 'animals' },
            { original: 'book', translation: 'livre', category: 'objects' },
            { original: 'water', translation: 'eau', category: 'nature' },
            { original: 'sun', translation: 'soleil', category: 'nature' }
        ];
    }

    async _speakWord(word) {
        const targetLanguage = this._content?.language || 'en-US';
        await ttsService.speak(word, targetLanguage, { rate: 0.9, volume: 1.0 });
    }

    _shuffleArray(array) {
        const shuffled = [...array];
        for (let i = shuffled.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
        }
        return shuffled;
    }

    _showVictoryPopup({ gameTitle, currentScore, bestScore, isNewBest, stats }) {
        const popup = document.createElement('div');
        popup.className = 'victory-popup';
        popup.innerHTML = `
            <div class="victory-content">
                <div class="victory-header">
                    <div class="victory-icon">🔨</div>
                    <h2 class="victory-title">${gameTitle} Complete!</h2>
                    ${isNewBest ? '<div class="new-best-badge">🎉 New Best Score!</div>' : ''}
                </div>

                <div class="victory-scores">
                    <div class="score-display">
                        <div class="score-label">Your Score</div>
                        <div class="score-value">${currentScore}</div>
                    </div>
                    <div class="score-display best-score">
                        <div class="score-label">Best Score</div>
                        <div class="score-value">${bestScore}</div>
                    </div>
                </div>

                <div class="victory-stats">
                    ${Object.entries(stats).map(([key, value]) => `
                        <div class="stat-row">
                            <span class="stat-name">${key}</span>
                            <span class="stat-value">${value}</span>
                        </div>
                    `).join('')}
                </div>

                <div class="victory-buttons">
                    <button class="victory-btn primary" onclick="this.closest('.victory-popup').remove(); window.location.reload();">🔄 Play Again</button>
                    <button class="victory-btn secondary" onclick="this.closest('.victory-popup').remove(); window.app.getCore().router.navigate('/games'); setTimeout(() => { const chapterId = window.currentChapterId || 'sbs'; window.app.getCore().eventBus.emit('navigation:games', { path: \`/games/\${chapterId}\`, data: { path: \`/games/\${chapterId}\` } }, 'Application'); }, 100);">🎮 Different Game</button>
                    <button class="victory-btn tertiary" onclick="this.closest('.victory-popup').remove(); window.app.getCore().router.navigate('/');">🏠 Main Menu</button>
                </div>
            </div>
        `;

        document.body.appendChild(popup);

        // Emit completion event after showing popup
        this._eventBus.emit('whack-hard:game-ended', {
            score: currentScore,
            errors: this._errors,
            timeLeft: this._timeLeft,
            mode: this._gameMode
        }, this.name);
    }

    // Event handlers
    _handleStart(event) {
        this._validateInitialized();
        this.startGame();
    }

    _handlePause(event) {
        this._validateInitialized();
        this.pauseGame();
    }

    _handleRestart(event) {
        this._validateInitialized();
        this.restartGame();
    }

    _handleTogglePronunciation(event) {
        this._validateInitialized();
        this._togglePronunciation();
    }

    // Static metadata methods
    static getMetadata() {
        return {
            name: 'WhackAMoleHard',
            version: '1.0.0',
            description: 'Advanced Whack-a-Mole game with multiple moles per wave and increased difficulty',
            author: 'Class Generator',
            difficulty: 'hard',
            category: 'action',
            tags: ['vocabulary', 'reaction', 'translation', 'hard', 'multiple-targets'],
            contentRequirements: ['vocabulary'],
            supportedModes: ['translation'],
            features: [
                'Multiple moles per wave',
                '15-hole grid (5x3)',
                'Target word guarantee system',
                'Pronunciation support',
                'Score tracking',
                'Time pressure',
                'Error limits'
            ]
        };
    }

    static getCompatibilityScore(content) {
        let score = 0;

        if (!content) return 0;

        // Check vocabulary availability (required)
        if (content.vocabulary && Object.keys(content.vocabulary).length > 0) {
            score += 40;

            // Bonus for rich vocabulary data
            const sampleEntry = Object.values(content.vocabulary)[0];
            if (typeof sampleEntry === 'object' && sampleEntry.user_language) {
                score += 20;
            }

            // Pronunciation bonus
            const haspronounciation = Object.values(content.vocabulary).some(entry =>
                (typeof entry === 'object' && entry.pronunciation) ||
                (typeof entry === 'object' && entry.prononciation)
            );
            if (haspronounciation) score += 15;

            // Volume bonus
            const vocabCount = Object.keys(content.vocabulary).length;
            if (vocabCount >= 20) score += 10;
            if (vocabCount >= 50) score += 10;

        } else if (content.sentences && content.sentences.length > 0) {
            // Fallback support for legacy format
            score += 25;
        }

        return Math.min(score, 100);
    }
}

export default WhackAMoleHard;