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

/**
 * AdventureReader - Zelda-style RPG adventure with vocabulary and sentence reading
 * Players move around a map, click pots for vocabulary and defeat enemies for reading content
 */
class AdventureReader extends Module {
    constructor(name, dependencies, config = {}) {
        super(name, ['eventBus']);

        // Validate dependencies
        if (!dependencies.eventBus || !dependencies.content) {
            throw new Error('AdventureReader requires eventBus and content dependencies');
        }

        this._eventBus = dependencies.eventBus;
        this._content = dependencies.content;
        this._config = {
            container: null,
            autoPlayTTS: true,
            ttsEnabled: true,
            maxPots: 8,
            maxEnemies: 8,
            ...config
        };

        // Game state
        this._score = 0;
        this._currentSentenceIndex = 0;
        this._currentVocabIndex = 0;
        this._potsDestroyed = 0;
        this._enemiesDefeated = 0;
        this._isGamePaused = false;
        this._gameStartTime = null;

        // Game objects
        this._pots = [];
        this._enemies = [];
        this._player = { x: 0, y: 0 };
        this._isPlayerMoving = false;
        this._isPlayerInvulnerable = false;
        this._invulnerabilityTimeout = null;

        // Content
        this._vocabulary = null;
        this._sentences = null;
        this._stories = null;
        this._dialogues = null;

        Object.seal(this);
    }

    /**
     * Get game metadata
     * @returns {Object} Game metadata
     */
    static getMetadata() {
        return {
            name: 'Adventure Reader',
            description: 'Zelda-style RPG adventure with vocabulary discovery and reading quests',
            difficulty: 'intermediate',
            category: 'adventure',
            estimatedTime: 12, // minutes
            skills: ['vocabulary', 'reading', 'exploration', 'comprehension']
        };
    }

    /**
     * Calculate compatibility score with content
     * @param {Object} content - Content to check compatibility with
     * @returns {Object} Compatibility score and details
     */
    static getCompatibilityScore(content) {
        const vocab = content?.vocabulary || {};
        const dialogues = content?.dialogues || [];
        const stories = content?.story?.chapters || content?.texts || [];

        const vocabCount = Object.keys(vocab).length;
        const dialogueCount = dialogues.length;
        const storyCount = stories.length;

        // Count sentences from ALL possible sources (matching _extractSentences logic)
        let sentenceCount = 0;

        // From story chapters
        if (content?.story?.chapters) {
            content.story.chapters.forEach(chapter => {
                if (chapter.sentences) {
                    sentenceCount += chapter.sentences.filter(s => s.original && s.translation).length;
                }
            });
        }

        // From direct sentences array
        if (content?.sentences) {
            sentenceCount += content.sentences.length;
        }

        // From phrases (array or object format)
        if (content?.phrases) {
            if (Array.isArray(content.phrases)) {
                sentenceCount += content.phrases.filter(p => p.chinese && p.english).length;
            } else if (typeof content.phrases === 'object') {
                sentenceCount += Object.keys(content.phrases).length;
            }
        }

        // From lessons
        if (content?.lessons) {
            content.lessons.forEach(lesson => {
                if (lesson.sentences) {
                    sentenceCount += lesson.sentences.filter(s => s.chinese && s.english).length;
                }
            });
        }

        const totalContent = vocabCount + sentenceCount + storyCount + dialogueCount;

        if (totalContent < 5) {
            return {
                score: 0,
                reason: `Insufficient adventure content (${totalContent}/5 required)`,
                requirements: ['vocabulary', 'sentences', 'stories', 'dialogues'],
                minContent: 5,
                details: 'Adventure Reader needs vocabulary, sentences, stories, or dialogues for exploration'
            };
        }

        // Calculate weighted score based on content diversity and quantity
        let score = 0;

        // Vocabulary: 0.3 points max (reach 100% at 8+ items)
        if (vocabCount > 0) score += Math.min(vocabCount / 8, 1) * 0.3;

        // Sentences: 0.4 points max (reach 100% at 8+ items) - most important for gameplay
        if (sentenceCount > 0) score += Math.min(sentenceCount / 8, 1) * 0.4;

        // Stories: 0.15 points max (reach 100% at 3+ items)
        if (storyCount > 0) score += Math.min(storyCount / 3, 1) * 0.15;

        // Dialogues: 0.15 points max (reach 100% at 3+ items)
        if (dialogueCount > 0) score += Math.min(dialogueCount / 3, 1) * 0.15;

        return {
            score: Math.min(score, 1),
            reason: `Adventure content: ${vocabCount} vocab, ${sentenceCount} sentences, ${storyCount} stories, ${dialogueCount} dialogues`,
            requirements: ['vocabulary', 'sentences', 'stories', 'dialogues'],
            optimalContent: { vocab: 8, sentences: 8, stories: 3, dialogues: 3 },
            details: `Rich adventure content with ${totalContent} total elements`
        };
    }

    async init() {
        this._validateNotDestroyed();

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

            // Extract content
            this._extractContent();

            // Validate content
            if (!this._hasValidContent()) {
                throw new Error('No compatible adventure content found');
            }

            // Set up event listeners
            this._eventBus.on('game:pause', this._handlePause.bind(this), this.name);
            this._eventBus.on('game:resume', this._handleResume.bind(this), this.name);

            // Inject CSS
            this._injectCSS();

            // Initialize game interface
            this._createGameInterface();

            // Wait for DOM to render before initializing player
            requestAnimationFrame(() => {
                this._initializePlayer();
                this._setupEventListeners();
                this._updateContentInfo();
                this._generateGameObjects();
                this._generateDecorations();
                this._startGameLoop();
            });

            // Start the game
            this._gameStartTime = Date.now();

            // Emit game ready event
            this._eventBus.emit('game:ready', {
                gameId: 'adventure-reader',
                instanceId: this.name,
                vocabulary: this._vocabulary.length,
                sentences: this._sentences.length,
                stories: this._stories.length,
                dialogues: this._dialogues.length
            }, this.name);

            this._setInitialized();

        } catch (error) {
            this._showError(error.message);
            throw error;
        }
    }

    async destroy() {
        this._validateNotDestroyed();

        // Clear timeouts
        if (this._invulnerabilityTimeout) {
            clearTimeout(this._invulnerabilityTimeout);
            this._invulnerabilityTimeout = null;
        }

        // Cancel any ongoing TTS
        ttsService.cancel();

        // Remove CSS
        this._removeCSS();

        // Clean up event listeners
        if (this._config.container) {
            this._config.container.innerHTML = '';
        }

        // Emit game end event
        this._eventBus.emit('game:ended', {
            gameId: 'adventure-reader',
            instanceId: this.name,
            score: this._score,
            potsDestroyed: this._potsDestroyed,
            enemiesDefeated: this._enemiesDefeated,
            duration: this._gameStartTime ? Date.now() - this._gameStartTime : 0
        }, this.name);

        this._setDestroyed();
    }

    /**
     * Get current game state
     * @returns {Object} Current game state
     */
    getGameState() {
        this._validateInitialized();

        return {
            score: this._score,
            potsDestroyed: this._potsDestroyed,
            enemiesDefeated: this._enemiesDefeated,
            totalPots: this._pots.length,
            totalEnemies: this._enemies.length,
            isComplete: this._isGameComplete(),
            isPaused: this._isGamePaused,
            duration: this._gameStartTime ? Date.now() - this._gameStartTime : 0
        };
    }

    // Private methods
    _extractContent() {
        this._vocabulary = this._extractVocabulary();
        this._sentences = this._extractSentences();
        this._stories = this._extractStories();
        this._dialogues = this._extractDialogues();
    }

    _extractVocabulary() {
        const vocab = this._content?.vocabulary || {};
        const vocabulary = [];

        for (const [word, data] of Object.entries(vocab)) {
            if (data.user_language || (typeof data === 'string')) {
                vocabulary.push({
                    original_language: word,
                    user_language: data.user_language || data,
                    type: data.type || 'unknown',
                    pronunciation: data.pronunciation
                });
            }
        }

        return vocabulary;
    }

    _extractSentences() {
        let sentences = [];

        console.log('AdventureReader: Extracting sentences from content', this._content);

        // Support for Dragon's Pearl structure
        if (this._content.story?.chapters) {
            this._content.story.chapters.forEach(chapter => {
                if (chapter.sentences) {
                    chapter.sentences.forEach(sentence => {
                        if (sentence.original && sentence.translation) {
                            sentences.push({
                                original_language: sentence.original,
                                user_language: sentence.translation,
                                pronunciation: sentence.pronunciation,
                                chapter: chapter.title || ''
                            });
                        }
                    });
                }
            });
        }

        // Support for modular format
        if (this._content.sentences) {
            this._content.sentences.forEach(sentence => {
                sentences.push({
                    original_language: sentence.english || sentence.original_language || sentence.target_language,
                    user_language: sentence.chinese || sentence.french || sentence.user_language || sentence.translation,
                    pronunciation: sentence.pronunciation || sentence.prononciation
                });
            });
        }

        // Support for LEDU format with phrases/lessons
        if (this._content.phrases) {
            // Check if phrases is an array or object
            if (Array.isArray(this._content.phrases)) {
                this._content.phrases.forEach(phrase => {
                    if (phrase.chinese && phrase.english) {
                        sentences.push({
                            original_language: phrase.chinese,
                            user_language: phrase.english,
                            pronunciation: phrase.pinyin
                        });
                    }
                });
            } else if (typeof this._content.phrases === 'object') {
                // Handle object format (key-value pairs)
                Object.entries(this._content.phrases).forEach(([phraseText, phraseData]) => {
                    const translation = typeof phraseData === 'object' ? phraseData.user_language : phraseData;
                    const pronunciation = typeof phraseData === 'object' ? phraseData.pronunciation : undefined;

                    if (phraseText && translation) {
                        sentences.push({
                            original_language: phraseText,
                            user_language: translation,
                            pronunciation: pronunciation
                        });
                    }
                });
            }
        }

        // Support for lessons with sentences
        if (this._content.lessons) {
            this._content.lessons.forEach(lesson => {
                if (lesson.sentences) {
                    lesson.sentences.forEach(sentence => {
                        if (sentence.chinese && sentence.english) {
                            sentences.push({
                                original_language: sentence.chinese,
                                user_language: sentence.english,
                                pronunciation: sentence.pinyin
                            });
                        }
                    });
                }
            });
        }

        console.log('AdventureReader: Extracted sentences:', sentences.length);
        return sentences.filter(s => s.original_language && s.user_language);
    }

    _extractStories() {
        let stories = [];

        // Support for Dragon's Pearl structure
        if (this._content.story?.chapters) {
            stories.push({
                title: this._content.story.title || this._content.name || "Adventure Story",
                chapters: this._content.story.chapters
            });
        }

        // Support for modular texts
        if (this._content.texts) {
            stories = stories.concat(this._content.texts.filter(text =>
                text.original_language && text.user_language
            ));
        }

        return stories;
    }

    _extractDialogues() {
        let dialogues = [];

        if (this._content.dialogues) {
            dialogues = this._content.dialogues.filter(dialogue =>
                dialogue.conversation && dialogue.conversation.length > 0
            );
        }

        return dialogues;
    }

    _hasValidContent() {
        const hasVocab = this._vocabulary.length > 0;
        const hasSentences = this._sentences.length > 0;
        const hasStories = this._stories.length > 0;
        const hasDialogues = this._dialogues.length > 0;

        return hasVocab || hasSentences || hasStories || hasDialogues;
    }

    _injectCSS() {
        const cssId = `adventure-reader-styles-${this.name}`;
        if (document.getElementById(cssId)) return;

        const style = document.createElement('style');
        style.id = cssId;
        style.textContent = `
            .adventure-reader-wrapper {
                height: 75vh;
                display: flex;
                flex-direction: column;
                font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
                background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%);
                overflow: hidden;
            }

            .adventure-hud {
                display: flex;
                justify-content: space-between;
                align-items: center;
                padding: 15px 20px;
                background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
                color: white;
                border-bottom: 3px solid rgba(255, 255, 255, 0.1);
                z-index: 100;
            }

            .hud-section {
                display: flex;
                gap: 20px;
                align-items: center;
            }

            .stat-item {
                display: flex;
                align-items: center;
                gap: 8px;
                background: rgba(255, 255, 255, 0.1);
                padding: 8px 12px;
                border-radius: 20px;
                font-weight: 500;
            }

            .stat-icon {
                font-size: 0.72rem; /* 1.2 / 1.66 */
            }

            .progress-info {
                background: rgba(255, 255, 255, 0.1);
                padding: 8px 15px;
                border-radius: 15px;
                font-size: 0.54rem; /* 0.9 / 1.66 */
            }

            .game-map {
                flex: 1;
                position: relative;
                background: linear-gradient(135deg, #27ae60 0%, #2ecc71 100%);
                overflow: hidden;
                cursor: crosshair;
            }

            .player {
                position: absolute;
                font-size: 1.51rem; /* 2.5 / 1.66 */
                z-index: 50;
                transition: all 0.8s cubic-bezier(0.4, 0, 0.2, 1);
                filter: drop-shadow(2px 2px 4px rgba(0,0,0,0.3));
                user-select: none;
            }

            .pot, .enemy {
                position: absolute;
                font-size: 1.2rem; /* 2 / 1.66 */
                cursor: pointer;
                z-index: 30;
                transition: all 0.3s ease;
                filter: drop-shadow(1px 1px 2px rgba(0,0,0,0.3));
                user-select: none;
            }

            .pot:hover, .enemy:hover {
                transform: scale(1.1);
                filter: drop-shadow(2px 2px 6px rgba(0,0,0,0.5));
            }

            .pot.destroyed, .enemy.defeated {
                pointer-events: none;
                transition: all 0.5s ease;
            }

            .decoration {
                position: absolute;
                z-index: 10;
                pointer-events: none;
                user-select: none;
                opacity: 0.8;
            }

            .decoration.tree {
                filter: drop-shadow(1px 1px 2px rgba(0,0,0,0.2));
            }

            .decoration.grass {
                opacity: 0.6;
            }

            .decoration.rock {
                filter: drop-shadow(1px 1px 3px rgba(0,0,0,0.3));
            }

            .adventure-controls {
                padding: 15px 20px;
                background: rgba(0, 0, 0, 0.8);
                color: white;
                display: flex;
                justify-content: space-between;
                align-items: center;
                flex-wrap: wrap;
                gap: 15px;
            }

            .instructions {
                font-size: 0.54rem; /* 0.9 / 1.66 */
                opacity: 0.9;
            }

            .content-summary {
                font-size: 0.51rem; /* 0.85 / 1.66 */
                background: rgba(255, 255, 255, 0.1);
                padding: 8px 12px;
                border-radius: 8px;
            }

            .control-btn {
                padding: 8px 15px;
                border: none;
                border-radius: 6px;
                cursor: pointer;
                font-size: 0.54rem; /* 0.9 / 1.66 */
                font-weight: 500;
                transition: all 0.3s ease;
            }

            .control-btn.primary {
                background: #3b82f6;
                color: white;
            }

            .control-btn.primary:hover {
                background: #2563eb;
                transform: translateY(-2px);
            }

            .control-btn.secondary {
                background: #10b981;
                color: white;
            }

            .control-btn.secondary:hover {
                background: #059669;
                transform: translateY(-2px);
            }

            .reading-modal, .vocab-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: 1000;
                opacity: 0;
                visibility: hidden;
                transition: all 0.3s ease;
            }

            .reading-modal.show, .vocab-popup.show {
                opacity: 1;
                visibility: visible;
            }

            .modal-content {
                background: white;
                border-radius: 15px;
                max-width: 600px;
                width: 90%;
                max-height: 80vh;
                overflow-y: auto;
                box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
                transform: translateY(20px);
                transition: transform 0.3s ease;
            }

            .reading-modal.show .modal-content {
                transform: translateY(0);
            }

            .modal-header {
                padding: 20px 25px 15px;
                border-bottom: 2px solid #e5e7eb;
                background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                color: white;
                border-radius: 15px 15px 0 0;
            }

            .modal-header h3 {
                margin: 0;
                font-size: 0.78rem; /* 1.3 / 1.66 */
            }

            .modal-body {
                padding: 25px;
            }

            .sentence-content {
                text-align: center;
            }

            .sentence-content.dialogue-content {
                background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
                padding: 20px;
                border-radius: 12px;
                margin-bottom: 15px;
            }

            .speaker-info, .story-title, .emotion-info {
                font-weight: 600;
                margin-bottom: 10px;
                color: #374151;
            }

            .text-content {
                margin: 20px 0;
            }

            .original-text {
                font-size: 0.84rem; /* 1.4 / 1.66 */
                font-weight: 600;
                color: #1f2937;
                margin-bottom: 15px;
                line-height: 1.4;
            }

            .translation-text {
                font-size: 0.66rem; /* 1.1 / 1.66 */
                color: #6b7280;
                margin-bottom: 10px;
                line-height: 1.3;
            }

            .pronunciation-text {
                font-size: 0.60rem; /* 1.0 / 1.66 */
                color: #7c3aed;
                font-style: italic;
            }

            .modal-footer {
                padding: 15px 25px 25px;
                text-align: center;
            }

            .popup-content {
                background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                color: white;
                padding: 20px 25px;
                border-radius: 15px;
                text-align: center;
                box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
                transform: scale(0.9);
                transition: transform 0.3s ease;
            }

            .vocab-popup.show .popup-content {
                transform: scale(1);
            }

            .vocab-word {
                font-size: 1.2rem; /* 2.0 / 1.66 */
                font-weight: bold;
                margin-bottom: 10px;
            }

            .vocab-translation {
                font-size: 0.78rem; /* 1.3 / 1.66 */
                margin-bottom: 10px;
                opacity: 0.9;
            }

            .vocab-pronunciation {
                font-size: 0.60rem; /* 1.0 / 1.66 */
                opacity: 0.8;
                font-style: italic;
            }

            .game-error {
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
                height: 100vh;
                text-align: center;
                padding: 40px;
                background: linear-gradient(135deg, #f87171 0%, #ef4444 100%);
                color: white;
            }

            .game-error h3 {
                font-size: 2rem;
                margin-bottom: 20px;
            }

            .game-error ul {
                text-align: left;
                background: rgba(255, 255, 255, 0.1);
                padding: 20px;
                border-radius: 10px;
                margin: 20px 0;
            }

            .back-btn {
                padding: 12px 25px;
                background: white;
                color: #ef4444;
                border: none;
                border-radius: 8px;
                font-size: 1rem;
                font-weight: 600;
                cursor: pointer;
                transition: all 0.3s ease;
            }

            .back-btn:hover {
                transform: translateY(-2px);
                box-shadow: 0 4px 12px rgba(255, 255, 255, 0.3);
            }

            /* Animations */
            @keyframes protectionFloat {
                0% {
                    transform: translate(-50%, -50%) scale(0.8);
                    opacity: 0;
                }
                20% {
                    transform: translate(-50%, -50%) scale(1.2);
                    opacity: 1;
                }
                80% {
                    transform: translate(-50%, -50%) scale(1);
                    opacity: 1;
                }
                100% {
                    transform: translate(-50%, -50%) scale(0.8);
                    opacity: 0;
                }
            }

            @keyframes damageFloat {
                0% {
                    transform: translate(-50%, -50%) scale(1);
                    opacity: 1;
                }
                50% {
                    transform: translate(-50%, -80%) scale(1.2);
                    opacity: 1;
                }
                100% {
                    transform: translate(-50%, -120%) scale(0.8);
                    opacity: 0;
                }
            }

            @media (max-width: 768px) {
                .adventure-hud {
                    flex-direction: column;
                    gap: 15px;
                    padding: 12px 15px;
                }

                .hud-section {
                    gap: 15px;
                }

                .stat-item {
                    padding: 6px 10px;
                    font-size: 0.9rem;
                }

                .player {
                    font-size: 2rem;
                }

                .pot, .enemy {
                    font-size: 1.8rem;
                }

                .adventure-controls {
                    flex-direction: column;
                    gap: 10px;
                    padding: 12px 15px;
                }

                .modal-content {
                    width: 95%;
                }

                .modal-body {
                    padding: 20px 15px;
                }
            }

            /* 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(style);
    }

    _removeCSS() {
        const cssId = `adventure-reader-styles-${this.name}`;
        const existingStyle = document.getElementById(cssId);
        if (existingStyle) {
            existingStyle.remove();
        }
    }

    _createGameInterface() {
        this._config.container.innerHTML = `
            <div class="adventure-reader-wrapper">
                <!-- Game HUD -->
                <div class="adventure-hud">
                    <div class="hud-section">
                        <div class="stat-item">
                            <span class="stat-icon">🏆</span>
                            <span id="score-display">0</span>
                        </div>
                        <div class="stat-item">
                            <span class="stat-icon">🏺</span>
                            <span id="pots-counter">0</span>
                        </div>
                        <div class="stat-item">
                            <span class="stat-icon">⚔️</span>
                            <span id="enemies-counter">0</span>
                        </div>
                    </div>
                    <div class="hud-section">
                        <div class="progress-info">
                            <span id="progress-text">Start your adventure!</span>
                        </div>
                        <div style="display: flex; gap: 8px;">
                            <button class="btn btn-outline btn-sm" id="restart-btn">
                                <span class="btn-icon">🔄</span>
                                <span class="btn-text">Restart</span>
                            </button>
                            <button class="btn btn-outline btn-sm" id="exit-adventure">
                                <span class="btn-icon">←</span>
                                <span class="btn-text">Exit</span>
                            </button>
                        </div>
                    </div>
                </div>

                <!-- Game Map -->
                <div class="game-map" id="game-map">
                    <!-- Player -->
                    <div class="player" id="player">🧙‍♂️</div>

                    <!-- Game objects will be generated here -->
                </div>

                <!-- Game Controls -->
                <div class="adventure-controls">
                    <div class="instructions" id="game-instructions">
                        Click 🏺 pots for vocabulary • Click 👹 enemies for sentences
                    </div>
                    <div class="content-info" id="content-info">
                        <!-- Content type info will be populated here -->
                    </div>
                </div>

                <!-- Reading Modal -->
                <div class="reading-modal" id="reading-modal">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h3 id="modal-title">Enemy Defeated!</h3>
                        </div>
                        <div class="modal-body">
                            <div class="reading-content" id="reading-content">
                                <!-- Sentence content -->
                            </div>
                        </div>
                    </div>
                </div>

                <!-- Vocab Popup -->
                <div class="vocab-popup" id="vocab-popup">
                    <div class="popup-content">
                        <div class="vocab-word" id="vocab-word"></div>
                        <div class="vocab-translation" id="vocab-translation"></div>
                        <div class="vocab-pronunciation" id="vocab-pronunciation"></div>
                    </div>
                </div>
            </div>
        `;
    }

    _initializePlayer() {
        const gameMap = document.getElementById('game-map');
        if (!gameMap) {
            console.error('AdventureReader: game-map element not found for player initialization');
            return;
        }

        const mapRect = gameMap.getBoundingClientRect();
        this._player.x = mapRect.width / 2 - 20;
        this._player.y = mapRect.height / 2 - 20;

        const playerElement = document.getElementById('player');
        if (!playerElement) {
            console.error('AdventureReader: player element not found for positioning');
            return;
        }

        playerElement.style.left = this._player.x + 'px';
        playerElement.style.top = this._player.y + 'px';
    }

    _setupEventListeners() {
        // Control buttons
        document.getElementById('restart-btn').addEventListener('click', () => this._restart());

        // Exit button
        const exitButton = document.getElementById('exit-adventure');
        if (exitButton) {
            exitButton.addEventListener('click', () => {
                this._eventBus.emit('game:exit-request', { instanceId: this.name }, this.name);
            });
        }

        // Map click handler
        const gameMap = document.getElementById('game-map');
        gameMap.addEventListener('click', (e) => this._handleMapClick(e));

        // Window resize handler
        window.addEventListener('resize', () => {
            setTimeout(() => {
                if (!this._isDestroyed) {
                    this._initializePlayer();
                }
            }, 100);
        });
    }

    _updateContentInfo() {
        const contentInfoEl = document.getElementById('content-info');
        if (!contentInfoEl) return;

        const contentTypes = [];

        if (this._stories.length > 0) {
            contentTypes.push(`📚 ${this._stories.length} stories`);
        }
        if (this._dialogues.length > 0) {
            contentTypes.push(`💬 ${this._dialogues.length} dialogues`);
        }
        if (this._vocabulary.length > 0) {
            contentTypes.push(`📝 ${this._vocabulary.length} words`);
        }
        if (this._sentences.length > 0) {
            contentTypes.push(`📖 ${this._sentences.length} sentences`);
        }

        if (contentTypes.length > 0) {
            contentInfoEl.innerHTML = `
                <div class="content-summary">
                    <strong>Adventure Content:</strong> ${contentTypes.join(' • ')}
                </div>
            `;
        }
    }

    _generateGameObjects() {
        const gameMap = document.getElementById('game-map');

        // Clear existing objects
        gameMap.querySelectorAll('.pot, .enemy').forEach(el => el.remove());

        this._pots = [];
        this._enemies = [];

        // Generate pots (for vocabulary)
        const numPots = Math.min(this._config.maxPots, this._vocabulary.length);
        for (let i = 0; i < numPots; i++) {
            const pot = this._createPot();
            this._pots.push(pot);
            gameMap.appendChild(pot.element);
        }

        // Generate enemies (for sentences)
        const numEnemies = Math.min(this._config.maxEnemies, this._sentences.length);
        for (let i = 0; i < numEnemies; i++) {
            const enemy = this._createEnemy();
            this._enemies.push(enemy);
            gameMap.appendChild(enemy.element);
        }

        this._updateHUD();
    }

    _createPot() {
        const pot = document.createElement('div');
        pot.className = 'pot';
        pot.innerHTML = '🏺';

        const position = this._getRandomPosition();
        pot.style.left = position.x + 'px';
        pot.style.top = position.y + 'px';

        return {
            element: pot,
            x: position.x,
            y: position.y,
            destroyed: false
        };
    }

    _createEnemy() {
        const enemy = document.createElement('div');
        enemy.className = 'enemy';
        enemy.innerHTML = '👹';

        const position = this._getRandomPosition(true);
        enemy.style.left = position.x + 'px';
        enemy.style.top = position.y + 'px';

        const patterns = ['patrol', 'chase', 'wander', 'circle'];
        const pattern = patterns[Math.floor(Math.random() * patterns.length)];

        return {
            element: enemy,
            x: position.x,
            y: position.y,
            defeated: false,
            moveDirection: Math.random() * Math.PI * 2,
            speed: 1.2 + Math.random() * 1.2, // 2x faster (was 0.6 + 0.6)
            pattern: pattern,
            patrolStartX: position.x,
            patrolStartY: position.y,
            patrolDistance: 80 + Math.random() * 60,
            circleCenter: { x: position.x, y: position.y },
            circleRadius: 60 + Math.random() * 40,
            circleAngle: Math.random() * Math.PI * 2,
            changeDirectionTimer: 0,
            dashCooldown: 0,
            isDashing: false,
            dashDuration: 0
        };
    }

    _getRandomPosition(forceAwayFromPlayer = false) {
        const gameMap = document.getElementById('game-map');
        const mapRect = gameMap.getBoundingClientRect();
        const mapWidth = mapRect.width;
        const mapHeight = mapRect.height;
        const margin = 40;

        let x, y;
        let tooClose;
        const minDistance = forceAwayFromPlayer ? 150 : 80;

        do {
            x = margin + Math.random() * (mapWidth - margin * 2);
            y = margin + Math.random() * (mapHeight - margin * 2);

            const distFromPlayer = Math.sqrt(
                Math.pow(x - this._player.x, 2) + Math.pow(y - this._player.y, 2)
            );
            tooClose = distFromPlayer < minDistance;

        } while (tooClose);

        return { x, y };
    }

    _generateDecorations() {
        const gameMap = document.getElementById('game-map');
        const mapRect = gameMap.getBoundingClientRect();
        const mapWidth = mapRect.width;
        const mapHeight = mapRect.height;

        // Remove existing decorations
        gameMap.querySelectorAll('.decoration').forEach(el => el.remove());

        // Generate trees
        const numTrees = 4 + Math.floor(Math.random() * 4);
        for (let i = 0; i < numTrees; i++) {
            const tree = document.createElement('div');
            tree.className = 'decoration tree';
            tree.innerHTML = Math.random() < 0.5 ? '🌳' : '🌲';

            const position = this._getDecorationPosition(mapWidth, mapHeight, 60);
            tree.style.left = position.x + 'px';
            tree.style.top = position.y + 'px';
            tree.style.fontSize = ((25 + Math.random() * 15) / 1.66) + 'px'; // Reduced by 1.66

            gameMap.appendChild(tree);
        }

        // Generate grass patches
        const numGrass = 15 + Math.floor(Math.random() * 10);
        for (let i = 0; i < numGrass; i++) {
            const grass = document.createElement('div');
            grass.className = 'decoration grass';
            const grassTypes = ['🌿', '🌱', '🍀', '🌾'];
            grass.innerHTML = grassTypes[Math.floor(Math.random() * grassTypes.length)];

            const position = this._getDecorationPosition(mapWidth, mapHeight, 30);
            grass.style.left = position.x + 'px';
            grass.style.top = position.y + 'px';
            grass.style.fontSize = ((15 + Math.random() * 8) / 1.66) + 'px'; // Reduced by 1.66

            gameMap.appendChild(grass);
        }

        // Generate rocks
        const numRocks = 3 + Math.floor(Math.random() * 3);
        for (let i = 0; i < numRocks; i++) {
            const rock = document.createElement('div');
            rock.className = 'decoration rock';
            rock.innerHTML = Math.random() < 0.5 ? '🪨' : '⛰️';

            const position = this._getDecorationPosition(mapWidth, mapHeight, 40);
            rock.style.left = position.x + 'px';
            rock.style.top = position.y + 'px';
            rock.style.fontSize = ((20 + Math.random() * 10) / 1.66) + 'px'; // Reduced by 1.66

            gameMap.appendChild(rock);
        }
    }

    _getDecorationPosition(mapWidth, mapHeight, keepAwayDistance) {
        const margin = 20;
        let x, y;
        let attempts = 0;
        let validPosition = false;

        do {
            x = margin + Math.random() * (mapWidth - margin * 2);
            y = margin + Math.random() * (mapHeight - margin * 2);

            const distFromPlayer = Math.sqrt(
                Math.pow(x - this._player.x, 2) + Math.pow(y - this._player.y, 2)
            );

            let tooClose = distFromPlayer < keepAwayDistance;

            if (!tooClose) {
                this._pots.forEach(pot => {
                    const dist = Math.sqrt(Math.pow(x - pot.x, 2) + Math.pow(y - pot.y, 2));
                    if (dist < keepAwayDistance) tooClose = true;
                });
            }

            if (!tooClose) {
                this._enemies.forEach(enemy => {
                    const dist = Math.sqrt(Math.pow(x - enemy.x, 2) + Math.pow(y - enemy.y, 2));
                    if (dist < keepAwayDistance) tooClose = true;
                });
            }

            validPosition = !tooClose;
            attempts++;

        } while (!validPosition && attempts < 50);

        return { x, y };
    }

    _startGameLoop() {
        const animate = () => {
            if (this._isDestroyed) return; // Stop animation if game is destroyed

            if (!this._isGamePaused) {
                this._moveEnemies();
            }
            requestAnimationFrame(animate);
        };
        animate();
    }

    _moveEnemies() {
        const gameMap = document.getElementById('game-map');
        if (!gameMap) return; // Exit if game map doesn't exist

        const mapRect = gameMap.getBoundingClientRect();
        const mapWidth = mapRect.width;
        const mapHeight = mapRect.height;

        this._enemies.forEach(enemy => {
            if (enemy.defeated) return;

            this._applyMovementPattern(enemy, mapWidth, mapHeight);

            // Bounce off walls
            if (enemy.x < 10 || enemy.x > mapWidth - 50) {
                enemy.moveDirection = Math.PI - enemy.moveDirection;
                enemy.x = Math.max(10, Math.min(mapWidth - 50, enemy.x));
            }
            if (enemy.y < 10 || enemy.y > mapHeight - 50) {
                enemy.moveDirection = -enemy.moveDirection;
                enemy.y = Math.max(10, Math.min(mapHeight - 50, enemy.y));
            }

            enemy.element.style.left = enemy.x + 'px';
            enemy.element.style.top = enemy.y + 'px';

            // Add red shadow effect during dash
            if (enemy.isDashing) {
                enemy.element.style.filter = 'drop-shadow(0 0 10px rgba(255, 0, 0, 0.8)) drop-shadow(0 0 20px rgba(255, 0, 0, 0.5))';
                enemy.element.style.transform = 'scale(1.1)'; // Slightly larger during dash
            } else {
                enemy.element.style.filter = '';
                enemy.element.style.transform = '';
            }

            this._checkPlayerEnemyCollision(enemy);
        });
    }

    _applyMovementPattern(enemy, mapWidth, mapHeight) {
        enemy.changeDirectionTimer++;

        switch (enemy.pattern) {
            case 'patrol':
                const distanceFromStart = Math.sqrt(
                    Math.pow(enemy.x - enemy.patrolStartX, 2) + Math.pow(enemy.y - enemy.patrolStartY, 2)
                );

                if (distanceFromStart > enemy.patrolDistance) {
                    const angleToStart = Math.atan2(
                        enemy.patrolStartY - enemy.y,
                        enemy.patrolStartX - enemy.x
                    );
                    enemy.moveDirection = angleToStart;
                }

                if (enemy.changeDirectionTimer > 120) {
                    enemy.moveDirection += (Math.random() - 0.5) * Math.PI * 0.5;
                    enemy.changeDirectionTimer = 0;
                }

                enemy.x += Math.cos(enemy.moveDirection) * enemy.speed;
                enemy.y += Math.sin(enemy.moveDirection) * enemy.speed;
                break;

            case 'chase':
                const angleToPlayer = Math.atan2(
                    this._player.y - enemy.y,
                    this._player.x - enemy.x
                );
                const distanceToPlayer = Math.sqrt(
                    Math.pow(this._player.x - enemy.x, 2) + Math.pow(this._player.y - enemy.y, 2)
                );

                // Decrease dash cooldown
                if (enemy.dashCooldown > 0) {
                    enemy.dashCooldown--;
                }

                // Trigger dash if close enough and cooldown is ready
                if (!enemy.isDashing && enemy.dashCooldown <= 0 && distanceToPlayer < 300 && distanceToPlayer > 80) {
                    enemy.isDashing = true;
                    enemy.dashDuration = 30; // 30 frames of dash
                    enemy.dashCooldown = 120; // 120 frames cooldown (~2 seconds)

                    // Choose perpendicular direction (90° or -90° randomly)
                    const perpendicularOffset = Math.random() < 0.5 ? Math.PI / 2 : -Math.PI / 2;
                    enemy.dashAngle = angleToPlayer + perpendicularOffset;
                }

                // Handle dashing (perpendicular to player direction - evasive maneuver)
                if (enemy.isDashing) {
                    // Use stored dash angle (perpendicular to player at dash start)
                    enemy.moveDirection = enemy.dashAngle;
                    enemy.x += Math.cos(enemy.dashAngle) * (enemy.speed * 3.5); // 3.5x speed during dash
                    enemy.y += Math.sin(enemy.dashAngle) * (enemy.speed * 3.5);

                    enemy.dashDuration--;
                    if (enemy.dashDuration <= 0) {
                        enemy.isDashing = false;
                    }
                } else {
                    // Normal chase movement
                    enemy.moveDirection = angleToPlayer + (Math.random() - 0.5) * 0.3;
                    enemy.x += Math.cos(enemy.moveDirection) * (enemy.speed * 0.8);
                    enemy.y += Math.sin(enemy.moveDirection) * (enemy.speed * 0.8);
                }
                break;

            case 'wander':
                if (enemy.changeDirectionTimer > 60 + Math.random() * 60) {
                    enemy.moveDirection += (Math.random() - 0.5) * Math.PI;
                    enemy.changeDirectionTimer = 0;
                }

                enemy.x += Math.cos(enemy.moveDirection) * enemy.speed;
                enemy.y += Math.sin(enemy.moveDirection) * enemy.speed;
                break;

            case 'circle':
                enemy.circleAngle += 0.03 + (enemy.speed * 0.01);

                enemy.x = enemy.circleCenter.x + Math.cos(enemy.circleAngle) * enemy.circleRadius;
                enemy.y = enemy.circleCenter.y + Math.sin(enemy.circleAngle) * enemy.circleRadius;
                break;
        }
    }

    _handleMapClick(e) {
        if (this._isGamePaused || this._isPlayerMoving) return;

        const rect = e.currentTarget.getBoundingClientRect();
        const clickX = e.clientX - rect.left;
        const clickY = e.clientY - rect.top;

        // Check pot clicks
        let targetFound = false;
        this._pots.forEach(pot => {
            if (!pot.destroyed && this._isNearPosition(clickX, clickY, pot)) {
                this._movePlayerToTarget(pot, 'pot');
                targetFound = true;
            }
        });

        // Check enemy clicks
        if (!targetFound) {
            this._enemies.forEach(enemy => {
                if (!enemy.defeated && this._isNearPosition(clickX, clickY, enemy)) {
                    this._movePlayerToTarget(enemy, 'enemy');
                    targetFound = true;
                }
            });
        }

        // Move to empty area
        if (!targetFound) {
            this._movePlayerToPosition(clickX, clickY);
        }
    }

    _isNearPosition(clickX, clickY, object) {
        const distance = Math.sqrt(
            Math.pow(clickX - (object.x + 20), 2) + Math.pow(clickY - (object.y + 20), 2)
        );
        return distance < 60;
    }

    _movePlayerToTarget(target, type) {
        this._isPlayerMoving = true;
        const playerElement = document.getElementById('player');

        if (type === 'enemy') {
            this._grantAttackInvulnerability();
        }

        const targetX = target.x;
        const targetY = target.y;

        this._player.x = targetX;
        this._player.y = targetY;

        playerElement.style.left = targetX + 'px';
        playerElement.style.top = targetY + 'px';
        playerElement.style.transform = 'scale(1.1)';

        setTimeout(() => {
            playerElement.style.transform = 'scale(1)';
            this._isPlayerMoving = false;

            if (type === 'pot') {
                this._destroyPot(target);
            } else if (type === 'enemy') {
                this._defeatEnemy(target);
            }
        }, 800);
    }

    _movePlayerToPosition(targetX, targetY) {
        this._isPlayerMoving = true;
        const playerElement = document.getElementById('player');

        this._player.x = targetX - 20;
        this._player.y = targetY - 20;

        const gameMap = document.getElementById('game-map');
        const mapRect = gameMap.getBoundingClientRect();
        const margin = 20;

        this._player.x = Math.max(margin, Math.min(mapRect.width - 60, this._player.x));
        this._player.y = Math.max(margin, Math.min(mapRect.height - 60, this._player.y));

        playerElement.style.left = this._player.x + 'px';
        playerElement.style.top = this._player.y + 'px';
        playerElement.style.transform = 'scale(1.1)';

        setTimeout(() => {
            playerElement.style.transform = 'scale(1)';
            this._isPlayerMoving = false;
        }, 800);
    }

    _destroyPot(pot) {
        pot.destroyed = true;
        pot.element.classList.add('destroyed');

        pot.element.innerHTML = '💥';
        setTimeout(() => {
            pot.element.style.opacity = '0.3';
            pot.element.innerHTML = '💨';
        }, 200);

        this._potsDestroyed++;
        this._score += 10;

        if (this._currentVocabIndex < this._vocabulary.length) {
            this._showVocabPopup(this._vocabulary[this._currentVocabIndex]);
            this._currentVocabIndex++;
        }

        this._updateHUD();
        this._checkGameComplete();
    }

    _defeatEnemy(enemy) {
        // CRITICAL: Mark enemy as defeated FIRST to prevent any further damage
        enemy.defeated = true;
        enemy.element.classList.add('defeated');

        enemy.element.innerHTML = '☠️';
        setTimeout(() => {
            enemy.element.style.opacity = '0.3';
        }, 300);

        this._enemiesDefeated++;
        this._score += 25;

        // Clear any existing invulnerability timeout to prevent conflicts
        // The reading modal will provide protection via pause,
        // and post-reading invulnerability will be granted after modal closes
        if (this._invulnerabilityTimeout) {
            clearTimeout(this._invulnerabilityTimeout);
            this._invulnerabilityTimeout = null;
        }

        // Keep player invulnerable until modal shows
        this._isPlayerInvulnerable = true;

        if (this._currentSentenceIndex < this._sentences.length) {
            this._showReadingModal(this._sentences[this._currentSentenceIndex]);
            this._currentSentenceIndex++;
        }

        this._updateHUD();
    }

    _showVocabPopup(vocab) {
        const popup = document.getElementById('vocab-popup');
        const wordEl = document.getElementById('vocab-word');
        const translationEl = document.getElementById('vocab-translation');
        const pronunciationEl = document.getElementById('vocab-pronunciation');

        wordEl.textContent = vocab.original_language;
        translationEl.textContent = vocab.user_language;

        if (vocab.pronunciation) {
            pronunciationEl.textContent = `🗣️ ${vocab.pronunciation}`;
            pronunciationEl.style.display = 'block';
        } else {
            pronunciationEl.style.display = 'none';
        }

        popup.style.display = 'flex';
        popup.classList.add('show');

        if (this._config.autoPlayTTS && this._config.ttsEnabled) {
            setTimeout(() => {
                this._speakText(vocab.original_language, { rate: 0.8 });
            }, 400);
        }

        setTimeout(() => {
            popup.classList.remove('show');
            setTimeout(() => {
                popup.style.display = 'none';
            }, 300);
        }, 2000);
    }

    _showReadingModal(sentence) {
        this._isGamePaused = true;
        const modal = document.getElementById('reading-modal');
        const content = document.getElementById('reading-content');
        const modalTitle = document.getElementById('modal-title');

        let modalTitleText = 'Adventure Text';
        if (sentence.speaker) {
            modalTitleText = `💬 ${sentence.speaker} says...`;
        } else if (sentence.title) {
            modalTitleText = `📚 ${sentence.title}`;
        }

        modalTitle.textContent = modalTitleText;

        const speakerInfo = sentence.speaker ? `<div class="speaker-info">🎭 ${sentence.speaker}</div>` : '';
        const titleInfo = sentence.title && !sentence.speaker ? `<div class="story-title">📖 ${sentence.title}</div>` : '';

        content.innerHTML = `
            <div class="sentence-content ${sentence.speaker ? 'dialogue-content' : 'story-content'}">
                ${titleInfo}
                ${speakerInfo}
                <div class="text-content">
                    <p class="original-text">${sentence.original_language}</p>
                    <p class="translation-text">${sentence.user_language}</p>
                    ${sentence.pronunciation ? `<p class="pronunciation-text">🗣️ ${sentence.pronunciation}</p>` : ''}
                </div>
            </div>
        `;

        modal.style.display = 'flex';
        modal.classList.add('show');

        // Calculate reading time based on text length and TTS
        const textLength = sentence.original_language.length;
        // Average reading speed: ~5 chars/second at 0.8 rate
        // Add base delay of 800ms (600ms initial + 200ms buffer)
        const ttsDelay = 600; // Initial delay before TTS starts
        const readingTime = (textLength / 5) * 1000; // Characters to milliseconds
        const bufferTime = 500; // Extra buffer after TTS ends
        const totalTime = ttsDelay + readingTime + bufferTime;

        if (this._config.autoPlayTTS && this._config.ttsEnabled) {
            setTimeout(() => {
                this._speakText(sentence.original_language, { rate: 0.8 });
            }, ttsDelay);
        }

        // Auto-close modal after TTS completes
        setTimeout(() => {
            this._closeModal();
        }, totalTime);
    }

    _closeModal() {
        const modal = document.getElementById('reading-modal');
        modal.classList.remove('show');
        setTimeout(() => {
            modal.style.display = 'none';
            this._isGamePaused = false;

            // Grant 1 second invulnerability after closing reading modal
            this._grantPostReadingInvulnerability();
        }, 300);

        this._checkGameComplete();
    }

    _checkGameComplete() {
        const allPotsDestroyed = this._pots.every(pot => pot.destroyed);
        const allEnemiesDefeated = this._enemies.every(enemy => enemy.defeated);

        if (allPotsDestroyed && allEnemiesDefeated) {
            setTimeout(() => {
                this._gameComplete();
            }, 1000);
        }
    }

    _gameComplete() {
        this._score += 100;
        this._updateHUD();

        document.getElementById('progress-text').textContent = '🏆 Adventure Complete!';

        // Calculate duration
        const duration = Math.round((Date.now() - this._gameStartTime) / 1000);

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

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

        setTimeout(() => {
            this._showVictoryPopup({
                gameTitle: 'Adventure Reader',
                currentScore,
                bestScore: isNewBest ? currentScore : bestScore,
                isNewBest,
                stats: {
                    'Pots Destroyed': this._potsDestroyed,
                    'Enemies Defeated': this._enemiesDefeated,
                    'Duration': `${duration}s`,
                    'Bonus Score': '100'
                }
            });
        }, 2000);
    }

    _updateHUD() {
        document.getElementById('score-display').textContent = this._score;
        document.getElementById('pots-counter').textContent = this._potsDestroyed;
        document.getElementById('enemies-counter').textContent = this._enemiesDefeated;

        const totalObjects = this._pots.length + this._enemies.length;
        const destroyedObjects = this._potsDestroyed + this._enemiesDefeated;

        document.getElementById('progress-text').textContent =
            `Progress: ${destroyedObjects}/${totalObjects} objects`;
    }

    _checkPlayerEnemyCollision(enemy) {
        // CRITICAL SAFETY CHECKS - Skip collision in ANY of these conditions:
        // 1. Game is paused (reading modal open)
        // 2. Player is invulnerable
        // 3. Enemy is defeated
        // 4. Player is currently moving (attacking)
        if (this._isGamePaused || this._isPlayerInvulnerable || enemy.defeated || this._isPlayerMoving) {
            return;
        }

        const distance = Math.sqrt(
            Math.pow(this._player.x - enemy.x, 2) + Math.pow(this._player.y - enemy.y, 2)
        );

        if (distance < 35) {
            this._takeDamage();
        }
    }

    _takeDamage() {
        if (this._isPlayerInvulnerable) return;

        this._score = Math.max(0, this._score - 20);
        this._updateHUD();

        if (this._invulnerabilityTimeout) {
            clearTimeout(this._invulnerabilityTimeout);
        }

        this._isPlayerInvulnerable = true;
        const playerElement = document.getElementById('player');

        // Blinking animation (visual only)
        let blinkCount = 0;
        const blinkInterval = setInterval(() => {
            playerElement.style.opacity = playerElement.style.opacity === '0.3' ? '1' : '0.3';
            blinkCount++;

            if (blinkCount >= 8) {
                clearInterval(blinkInterval);
                playerElement.style.opacity = '1';
                playerElement.style.filter = 'drop-shadow(2px 2px 4px rgba(0,0,0,0.3))';
            }
        }, 250);

        // Actual invulnerability duration (independent of blink animation)
        this._invulnerabilityTimeout = setTimeout(() => {
            this._isPlayerInvulnerable = false;
        }, 2000); // 2 seconds of actual invulnerability

        this._showDamagePopup();
    }

    _grantAttackInvulnerability() {
        this._isPlayerInvulnerable = true;
        const playerElement = document.getElementById('player');

        if (this._invulnerabilityTimeout) {
            clearTimeout(this._invulnerabilityTimeout);
        }

        playerElement.style.filter = 'drop-shadow(0 0 15px gold) brightness(1.4)';

        this._invulnerabilityTimeout = setTimeout(() => {
            playerElement.style.filter = 'drop-shadow(2px 2px 4px rgba(0,0,0,0.3))';
            this._isPlayerInvulnerable = false;
        }, 2000);

        this._showInvulnerabilityPopup();
    }

    _grantPostReadingInvulnerability() {
        this._isPlayerInvulnerable = true;
        const playerElement = document.getElementById('player');

        if (this._invulnerabilityTimeout) {
            clearTimeout(this._invulnerabilityTimeout);
        }

        // Brief blue glow to indicate post-reading protection
        playerElement.style.filter = 'drop-shadow(0 0 10px rgba(100, 150, 255, 0.8)) brightness(1.2)';

        this._invulnerabilityTimeout = setTimeout(() => {
            playerElement.style.filter = 'drop-shadow(2px 2px 4px rgba(0,0,0,0.3))';
            this._isPlayerInvulnerable = false;
        }, 1000); // 1 second protection
    }

    _refreshAttackInvulnerability() {
        if (this._invulnerabilityTimeout) {
            clearTimeout(this._invulnerabilityTimeout);
        }

        const playerElement = document.getElementById('player');
        this._isPlayerInvulnerable = true;

        this._invulnerabilityTimeout = setTimeout(() => {
            playerElement.style.filter = 'drop-shadow(2px 2px 4px rgba(0,0,0,0.3))';
            this._isPlayerInvulnerable = false;
        }, 2000);
    }

    _showInvulnerabilityPopup() {
        const popup = document.createElement('div');
        popup.className = 'invulnerability-popup';
        popup.innerHTML = 'Protected!';
        popup.style.cssText = `
            position: fixed;
            left: 50%;
            top: 25%;
            transform: translate(-50%, -50%);
            color: #FFD700;
            font-size: 1.5rem;
            font-weight: bold;
            z-index: 999;
            pointer-events: none;
            animation: protectionFloat 2s ease-out forwards;
        `;

        document.body.appendChild(popup);

        setTimeout(() => {
            popup.remove();
        }, 2000);
    }

    _showDamagePopup() {
        const damagePopup = document.createElement('div');
        damagePopup.className = 'damage-popup';
        damagePopup.innerHTML = '-20';
        damagePopup.style.cssText = `
            position: fixed;
            left: 50%;
            top: 30%;
            transform: translate(-50%, -50%);
            color: #EF4444;
            font-size: 2rem;
            font-weight: bold;
            z-index: 999;
            pointer-events: none;
            animation: damageFloat 1.5s ease-out forwards;
        `;

        document.body.appendChild(damagePopup);

        setTimeout(() => {
            damagePopup.remove();
        }, 1500);
    }

    _restart() {
        this._score = 0;
        this._currentSentenceIndex = 0;
        this._currentVocabIndex = 0;
        this._potsDestroyed = 0;
        this._enemiesDefeated = 0;
        this._isGamePaused = false;
        this._isPlayerMoving = false;
        this._isPlayerInvulnerable = false;

        if (this._invulnerabilityTimeout) {
            clearTimeout(this._invulnerabilityTimeout);
            this._invulnerabilityTimeout = null;
        }

        this._generateGameObjects();
        this._initializePlayer();
        this._generateDecorations();

        document.getElementById('progress-text').textContent = 'Click objects to begin your adventure!';
    }

    _isGameComplete() {
        const allPotsDestroyed = this._pots.every(pot => pot.destroyed);
        const allEnemiesDefeated = this._enemies.every(enemy => enemy.defeated);
        return allPotsDestroyed && allEnemiesDefeated;
    }

    _speakText(text, options = {}) {
        if (!text || !this._config.ttsEnabled) return;

        const language = this._getContentLanguage();
        const rate = options.rate || 0.8;

        ttsService.speak(text, language, { rate, volume: 1.0 });
    }

    _getContentLanguage() {
        if (this._content.language) {
            const langMap = {
                'chinese': 'zh-CN',
                'english': 'en-US',
                'french': 'fr-FR',
                'spanish': 'es-ES'
            };
            return langMap[this._content.language] || this._content.language;
        }
        return 'en-US';
    }

    _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');">🎮 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('game:completed', {
            gameId: 'adventure-reader',
            instanceId: this.name,
            score: currentScore,
            potsDestroyed: stats['Pots Destroyed'],
            enemiesDefeated: stats['Enemies Defeated'],
            duration: parseInt(stats['Duration'].replace('s', '')) * 1000
        }, this.name);
    }

    _showError(message) {
        if (this._config.container) {
            this._config.container.innerHTML = `
                <div class="game-error">
                    <h3>❌ Adventure Reader Error</h3>
                    <p>${message}</p>
                    <p>This content module needs adventure-compatible content:</p>
                    <ul style="text-align: left; margin: 1rem 0;">
                        <li><strong>📚 stories:</strong> Adventure texts with original and translated content</li>
                        <li><strong>💬 dialogues:</strong> Character conversations</li>
                        <li><strong>📝 vocabulary:</strong> Words with translations for discovery</li>
                        <li><strong>📖 sentences:</strong> Individual phrases for reading practice</li>
                    </ul>
                    <button class="back-btn" onclick="history.back()">← Go Back</button>
                </div>
            `;
        }
    }

    _handlePause() {
        this._isGamePaused = true;
        this._eventBus.emit('game:paused', { instanceId: this.name }, this.name);
    }

    _handleResume() {
        this._isGamePaused = false;
        this._eventBus.emit('game:resumed', { instanceId: this.name }, this.name);
    }
}

export default AdventureReader;