// === MODULE ADVENTURE READER (ZELDA-STYLE) ===

class AdventureReaderGame {
    constructor(options) {
        this.container = options.container;
        this.content = options.content;
        this.onScoreUpdate = options.onScoreUpdate || (() => {});
        this.onGameEnd = options.onGameEnd || (() => {});
        
        // Game state
        this.score = 0;
        this.currentSentenceIndex = 0;
        this.currentVocabIndex = 0;
        this.potsDestroyed = 0;
        this.enemiesDefeated = 0;
        this.isGamePaused = false;
        
        // Game objects
        this.pots = [];
        this.enemies = [];
        this.player = { x: 0, y: 0 }; // Will be set when map is created
        this.isPlayerMoving = false;
        this.isPlayerInvulnerable = false;
        this.invulnerabilityTimeout = null;

        // TTS settings
        this.autoPlayTTS = true;
        this.ttsEnabled = true;

        // Expose content globally for SettingsManager TTS language detection
        window.currentGameContent = this.content;
        
        // Content extraction
        this.vocabulary = this.extractVocabulary(this.content);
        this.sentences = this.extractSentences(this.content);
        this.stories = this.extractStories(this.content);
        this.dialogues = this.extractDialogues(this.content);
        
        this.init();
    }

    init() {
        const hasVocabulary = this.vocabulary && this.vocabulary.length > 0;
        const hasSentences = this.sentences && this.sentences.length > 0;
        const hasStories = this.stories && this.stories.length > 0;
        const hasDialogues = this.dialogues && this.dialogues.length > 0;

        if (!hasVocabulary && !hasSentences && !hasStories && !hasDialogues) {
            logSh('No compatible content found for Adventure Reader', 'ERROR');
            this.showInitError();
            return;
        }

        logSh(`Adventure Reader initialized with: ${this.vocabulary.length} vocab, ${this.sentences.length} sentences, ${this.stories.length} stories, ${this.dialogues.length} dialogues`, 'INFO');
        
        this.createGameInterface();
        this.initializePlayer();
        this.setupEventListeners();
        this.updateContentInfo();
        this.generateGameObjects();
        this.generateDecorations();
        this.startGameLoop();
    }
    
    showInitError() {
        this.container.innerHTML = `
            <div class="game-error">
                <h3>❌ No Adventure Content Found</h3>
                <p>This content module needs adventure-compatible content:</p>
                <ul style="text-align: left; margin: 1rem 0;">
                    <li><strong>📚 texts:</strong> Stories with original_language and user_language</li>
                    <li><strong>💬 dialogues:</strong> Character conversations with speakers</li>
                    <li><strong>📝 vocabulary:</strong> Words with translations for discovery</li>
                    <li><strong>📖 sentences:</strong> Individual phrases for reading practice</li>
                </ul>
                <p>Add adventure content to enable this game mode.</p>
                <button onclick="AppNavigation.navigateTo('games')" class="back-btn">← Back to Games</button>
            </div>
        `;
    }

    extractVocabulary(content) {
        let vocabulary = [];

        // Support pour Dragon's Pearl vocabulary structure
        if (content.vocabulary && typeof content.vocabulary === 'object') {
            vocabulary = Object.entries(content.vocabulary).map(([original_language, vocabData]) => {
                if (typeof vocabData === 'string') {
                    // Simple format: "word": "translation"
                    return {
                        original_language: original_language,
                        user_language: vocabData,
                        type: 'unknown'
                    };
                } else if (typeof vocabData === 'object') {
                    // Rich format: "word": { user_language: "translation", type: "noun", ... }
                    return {
                        original_language: original_language,
                        user_language: vocabData.user_language || vocabData.translation || 'No translation',
                        type: vocabData.type || 'unknown',
                        pronunciation: vocabData.pronunciation,
                        difficulty: vocabData.difficulty
                    };
                }
                return null;
            }).filter(item => item !== null);
        }
        // Ultra-modular format support
        else if (content.rawContent && content.rawContent.vocabulary) {
            if (typeof content.rawContent.vocabulary === 'object' && !Array.isArray(content.rawContent.vocabulary)) {
                vocabulary = Object.entries(content.rawContent.vocabulary).map(([original_language, vocabData]) => {
                    if (typeof vocabData === 'string') {
                        // Simple format: "word": "translation"
                        return {
                            original_language: original_language,
                            user_language: vocabData,
                            type: 'unknown'
                        };
                    } else if (typeof vocabData === 'object') {
                        // Rich format: "word": { user_language: "translation", type: "noun", ... }
                        return {
                            original_language: original_language,
                            user_language: vocabData.user_language || vocabData.translation || 'No translation',
                            type: vocabData.type || 'unknown',
                            pronunciation: vocabData.pronunciation,
                            difficulty: vocabData.difficulty
                        };
                    }
                    return null;
                }).filter(item => item !== null);
            }
        }

        return vocabulary.filter(item => item && item.original_language && item.user_language);
    }
    
    extractSentences(content) {
        let sentences = [];

        logSh('🐉 Adventure Reader: Extracting sentences from content...', 'DEBUG');
        logSh(`🐉 Content structure: story=${!!content.story}, rawContent=${!!content.rawContent}`, 'DEBUG');

        // Support pour Dragon's Pearl structure: content.story.chapters[].sentences[]
        if (content.story && content.story.chapters && Array.isArray(content.story.chapters)) {
            logSh(`🐉 Dragon's Pearl structure detected, ${content.story.chapters.length} chapters`, 'DEBUG');

            content.story.chapters.forEach((chapter, chapterIndex) => {
                logSh(`🐉 Processing chapter ${chapterIndex}: ${chapter.title}`, 'DEBUG');

                if (chapter.sentences && Array.isArray(chapter.sentences)) {
                    logSh(`🐉 Chapter ${chapterIndex} has ${chapter.sentences.length} sentences`, 'DEBUG');

                    chapter.sentences.forEach((sentence, sentenceIndex) => {
                        if (sentence.original && sentence.translation) {
                            // Construire la prononciation depuis les mots si pas disponible directement
                            let pronunciation = sentence.pronunciation || '';

                            if (!pronunciation && sentence.words && Array.isArray(sentence.words)) {
                                pronunciation = sentence.words
                                    .map(wordObj => wordObj.pronunciation || '')
                                    .filter(p => p.trim().length > 0)
                                    .join(' ');
                            }

                            sentences.push({
                                original_language: sentence.original,
                                user_language: sentence.translation,
                                pronunciation: pronunciation,
                                chapter: chapter.title || '',
                                id: sentence.id || sentences.length
                            });
                        } else {
                            logSh(`🐉 WARNING: Skipping sentence ${sentenceIndex} in chapter ${chapterIndex} - missing original/translation`, 'WARN');
                        }
                    });
                } else {
                    logSh(`🐉 WARNING: Chapter ${chapterIndex} has no sentences array`, 'WARN');
                }
            });

            logSh(`🐉 Dragon's Pearl extraction complete: ${sentences.length} sentences extracted`, 'INFO');
        }
        // Support pour la structure ultra-modulaire existante
        else if (content.rawContent) {
            // Ultra-modular format: Extract from texts (stories/adventures)
            if (content.rawContent.texts && Array.isArray(content.rawContent.texts)) {
                content.rawContent.texts.forEach(text => {
                    if (text.original_language && text.user_language) {
                        // Split long texts into sentences for adventure reading
                        const originalSentences = text.original_language.split(/[.!?]+/).filter(s => s.trim().length > 10);
                        const userSentences = text.user_language.split(/[.!?]+/).filter(s => s.trim().length > 10);

                        // Match sentences by index
                        originalSentences.forEach((originalSentence, index) => {
                            const userSentence = userSentences[index] || originalSentence;
                            sentences.push({
                                original_language: originalSentence.trim() + '.',
                                user_language: userSentence.trim() + '.',
                                title: text.title || 'Adventure Text',
                                id: text.id || `text_${index}`
                            });
                        });
                    }
                });
            }

            // Ultra-modular format: Extract from dialogues
            if (content.rawContent.dialogues && Array.isArray(content.rawContent.dialogues)) {
                content.rawContent.dialogues.forEach(dialogue => {
                    if (dialogue.conversation && Array.isArray(dialogue.conversation)) {
                        dialogue.conversation.forEach(line => {
                            if (line.original_language && line.user_language) {
                                sentences.push({
                                    original_language: line.original_language,
                                    user_language: line.user_language,
                                    speaker: line.speaker || 'Character',
                                    title: dialogue.title || 'Dialogue',
                                    id: line.id || dialogue.id
                                });
                            }
                        });
                    }
                });
            }

            // Legacy format support for backward compatibility
            if (content.rawContent.sentences && Array.isArray(content.rawContent.sentences)) {
                content.rawContent.sentences.forEach(sentence => {
                    sentences.push({
                        original_language: sentence.english || sentence.original_language || '',
                        user_language: sentence.chinese || sentence.french || sentence.user_language || sentence.translation || '',
                        pronunciation: sentence.prononciation || sentence.pronunciation
                    });
                });
            }
        }

        return sentences.filter(item => item && item.original_language && item.user_language);
    }

    extractStories(content) {
        let stories = [];

        // Support pour Dragon's Pearl structure
        if (content.story && content.story.chapters && Array.isArray(content.story.chapters)) {
            // Créer une histoire depuis les chapitres de Dragon's Pearl
            stories.push({
                title: content.story.title || content.name || "Dragon's Pearl",
                original_language: content.story.chapters.map(ch =>
                    ch.sentences.map(s => s.original).join(' ')
                ).join('\n\n'),
                user_language: content.story.chapters.map(ch =>
                    ch.sentences.map(s => s.translation).join(' ')
                ).join('\n\n'),
                chapters: content.story.chapters.map(chapter => ({
                    title: chapter.title,
                    sentences: chapter.sentences
                }))
            });
        }
        // Support pour la structure ultra-modulaire existante
        else if (content.rawContent && content.rawContent.texts && Array.isArray(content.rawContent.texts)) {
            stories = content.rawContent.texts.filter(text =>
                text.original_language && text.user_language && text.title
            ).map(text => ({
                id: text.id || `story_${Date.now()}_${Math.random()}`,
                title: text.title,
                original_language: text.original_language,
                user_language: text.user_language,
                description: text.description || '',
                difficulty: text.difficulty || 'medium'
            }));
        }

        return stories;
    }

    extractDialogues(content) {
        let dialogues = [];

        if (content.rawContent && content.rawContent.dialogues && Array.isArray(content.rawContent.dialogues)) {
            dialogues = content.rawContent.dialogues.filter(dialogue =>
                dialogue.conversation && Array.isArray(dialogue.conversation) && dialogue.conversation.length > 0
            ).map(dialogue => ({
                id: dialogue.id || `dialogue_${Date.now()}_${Math.random()}`,
                title: dialogue.title || 'Character Dialogue',
                conversation: dialogue.conversation.filter(line =>
                    line.original_language && line.user_language
                ).map(line => ({
                    id: line.id || `line_${Date.now()}_${Math.random()}`,
                    speaker: line.speaker || 'Character',
                    original_language: line.original_language,
                    user_language: line.user_language,
                    emotion: line.emotion || 'neutral'
                }))
            }));
        }

        return dialogues.filter(dialogue => dialogue.conversation.length > 0);
    }

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

        const contentTypes = [];

        if (this.stories && this.stories.length > 0) {
            contentTypes.push(`📚 ${this.stories.length} stories`);
        }

        if (this.dialogues && this.dialogues.length > 0) {
            contentTypes.push(`💬 ${this.dialogues.length} dialogues`);
        }

        if (this.vocabulary && this.vocabulary.length > 0) {
            contentTypes.push(`📝 ${this.vocabulary.length} words`);
        }

        if (this.sentences && 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>
            `;
        }
    }

    createGameInterface() {
        this.container.innerHTML = `
            <div class="adventure-reader-wrapper">
                <!-- Game HUD -->
                <div class="game-hud">
                    <div class="hud-left">
                        <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-right">
                        <div class="progress-info">
                            <span id="progress-text">Start your adventure!</span>
                        </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="game-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>
                    <button class="control-btn secondary" id="restart-btn">🔄 Restart Adventure</button>
                </div>

                <!-- Reading Modal -->
                <div class="reading-modal" id="reading-modal" style="display: none;">
                    <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 class="modal-footer">
                            <button class="control-btn primary" id="continue-btn">Continue Adventure →</button>
                        </div>
                    </div>
                </div>

                <!-- Vocab Popup -->
                <div class="vocab-popup" id="vocab-popup" style="display: none;">
                    <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() {
        // Set player initial position to center of map
        const gameMap = document.getElementById('game-map');
        const mapRect = gameMap.getBoundingClientRect();
        this.player.x = mapRect.width / 2 - 20; // -20 for half player width
        this.player.y = mapRect.height / 2 - 20; // -20 for half player height
        
        const playerElement = document.getElementById('player');
        playerElement.style.left = this.player.x + 'px';
        playerElement.style.top = this.player.y + 'px';
    }

    setupEventListeners() {
        document.getElementById('restart-btn').addEventListener('click', () => this.restart());
        document.getElementById('continue-btn').addEventListener('click', () => this.closeModal());
        
        // Map click handler
        const gameMap = document.getElementById('game-map');
        gameMap.addEventListener('click', (e) => this.handleMapClick(e));
        
        // Window resize handler
        window.addEventListener('resize', () => {
            setTimeout(() => this.initializePlayer(), 100);
        });
    }

    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(8, 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) - spawn across entire viewport
        const numEnemies = Math.min(8, 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); // Force away from player
        enemy.style.left = position.x + 'px';
        enemy.style.top = position.y + 'px';
        
        // Random movement pattern for each enemy
        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: 0.6 + Math.random() * 0.6, // Reduced speed
            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
        };
    }

    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);
            
            // Check distance from player
            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 };
    }

    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 (only if no pot was clicked)
        if (!targetFound) {
            this.enemies.forEach(enemy => {
                if (!enemy.defeated && this.isNearPosition(clickX, clickY, enemy)) {
                    this.movePlayerToTarget(enemy, 'enemy');
                    targetFound = true;
                }
            });
        }
        
        // If no target found, 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; // Larger clickable area
    }

    movePlayerToTarget(target, type) {
        this.isPlayerMoving = true;
        const playerElement = document.getElementById('player');
        
        // Grant invulnerability IMMEDIATELY when attacking an enemy
        if (type === 'enemy') {
            this.grantAttackInvulnerability();
        }
        
        // Calculate target position (near the object)
        const targetX = target.x;
        const targetY = target.y;
        
        // Update player position
        this.player.x = targetX;
        this.player.y = targetY;
        
        // Animate player movement
        playerElement.style.left = targetX + 'px';
        playerElement.style.top = targetY + 'px';
        
        // Add walking animation
        playerElement.style.transform = 'scale(1.1)';
        
        // Wait for movement animation to complete, then interact
        setTimeout(() => {
            playerElement.style.transform = 'scale(1)';
            this.isPlayerMoving = false;
            
            if (type === 'pot') {
                this.destroyPot(target);
            } else if (type === 'enemy') {
                this.defeatEnemy(target);
            }
        }, 800); // Match CSS transition duration
    }

    movePlayerToPosition(targetX, targetY) {
        this.isPlayerMoving = true;
        const playerElement = document.getElementById('player');
        
        // Update player position
        this.player.x = targetX - 20; // Center the player on click point
        this.player.y = targetY - 20;
        
        // Keep player within bounds
        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));
        
        // Animate player movement
        playerElement.style.left = this.player.x + 'px';
        playerElement.style.top = this.player.y + 'px';
        
        // Add walking animation
        playerElement.style.transform = 'scale(1.1)';
        
        // Reset animation after movement
        setTimeout(() => {
            playerElement.style.transform = 'scale(1)';
            this.isPlayerMoving = false;
        }, 800);
    }

    destroyPot(pot) {
        pot.destroyed = true;
        pot.element.classList.add('destroyed');
        
        // Animation
        pot.element.innerHTML = '💥';
        setTimeout(() => {
            pot.element.style.opacity = '0.3';
            pot.element.innerHTML = '💨';
        }, 200);
        
        this.potsDestroyed++;
        this.score += 10;
        
        // Show vocabulary
        if (this.currentVocabIndex < this.vocabulary.length) {
            this.showVocabPopup(this.vocabulary[this.currentVocabIndex]);
            this.currentVocabIndex++;
        }
        
        this.updateHUD();
        this.checkGameComplete();
    }

    defeatEnemy(enemy) {
        enemy.defeated = true;
        enemy.element.classList.add('defeated');
        
        // Animation
        enemy.element.innerHTML = '☠️';
        setTimeout(() => {
            enemy.element.style.opacity = '0.3';
        }, 300);
        
        this.enemiesDefeated++;
        this.score += 25;
        
        // Invulnerability is already granted at start of movement
        // Just refresh the timer to ensure full 2 seconds from now
        this.refreshAttackInvulnerability();
        
        // Show sentence (pause game)
        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;

        // Afficher la prononciation si disponible
        if (vocab.pronunciation) {
            pronunciationEl.textContent = `🗣️ ${vocab.pronunciation}`;
            pronunciationEl.style.display = 'block';
        } else {
            pronunciationEl.style.display = 'none';
        }
        
        popup.style.display = 'block';
        popup.classList.add('show');

        // Auto-play TTS for vocabulary
        if (this.autoPlayTTS && this.ttsEnabled) {
            setTimeout(() => {
                this.speakText(vocab.original_language, { rate: 0.8 });
            }, 400); // Small delay to let popup appear
        }

        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');

        // Determine content type and set appropriate modal title
        let modalTitleText = 'Adventure Text';
        if (sentence.speaker) {
            modalTitleText = `💬 ${sentence.speaker} says...`;
        } else if (sentence.title) {
            modalTitleText = `📚 ${sentence.title}`;
        }

        modalTitle.textContent = modalTitleText;

        // Create content with appropriate styling based on type
        const speakerInfo = sentence.speaker ? `<div class="speaker-info">🎭 ${sentence.speaker}</div>` : '';
        const titleInfo = sentence.title && !sentence.speaker ? `<div class="story-title">📖 ${sentence.title}</div>` : '';
        const emotionInfo = sentence.emotion && sentence.emotion !== 'neutral' ? `<div class="emotion-info">😊 ${sentence.emotion}</div>` : '';

        content.innerHTML = `
            <div class="sentence-content ${sentence.speaker ? 'dialogue-content' : 'story-content'}">
                ${titleInfo}
                ${speakerInfo}
                ${emotionInfo}
                <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');

        // Auto-play TTS for sentence
        if (this.autoPlayTTS && this.ttsEnabled) {
            setTimeout(() => {
                this.speakText(sentence.original_language, { rate: 0.8 });
            }, 600); // Longer delay for modal animation
        }
    }

    closeModal() {
        const modal = document.getElementById('reading-modal');
        modal.classList.remove('show');
        setTimeout(() => {
            modal.style.display = 'none';
            this.isGamePaused = false;
        }, 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() {
        // Bonus for completion
        this.score += 100;
        this.updateHUD();
        
        document.getElementById('progress-text').textContent = '🏆 Adventure Complete!';
        
        setTimeout(() => {
            this.onGameEnd(this.score);
        }, 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`;
        
        this.onScoreUpdate(this.score);
    }

    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 (fewer, larger)
        const numTrees = 4 + Math.floor(Math.random() * 4); // 4-7 trees
        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); // Keep away from objects
            tree.style.left = position.x + 'px';
            tree.style.top = position.y + 'px';
            tree.style.fontSize = (25 + Math.random() * 15) + 'px'; // Random size
            
            gameMap.appendChild(tree);
        }
        
        // Generate grass patches (many, small)
        const numGrass = 15 + Math.floor(Math.random() * 10); // 15-24 grass
        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); // Smaller keepaway
            grass.style.left = position.x + 'px';
            grass.style.top = position.y + 'px';
            grass.style.fontSize = (15 + Math.random() * 8) + 'px'; // Smaller size
            
            gameMap.appendChild(grass);
        }
        
        // Generate rocks (medium amount)
        const numRocks = 3 + Math.floor(Math.random() * 3); // 3-5 rocks
        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) + 'px';
            
            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);
            
            // Check distance from player
            const distFromPlayer = Math.sqrt(
                Math.pow(x - this.player.x, 2) + Math.pow(y - this.player.y, 2)
            );
            
            // Check distance from pots and enemies
            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.isGamePaused) {
                this.moveEnemies();
            }
            requestAnimationFrame(animate);
        };
        animate();
    }

    moveEnemies() {
        const gameMap = document.getElementById('game-map');
        const mapRect = gameMap.getBoundingClientRect();
        const mapWidth = mapRect.width;
        const mapHeight = mapRect.height;
        
        this.enemies.forEach(enemy => {
            if (enemy.defeated) return;
            
            // Apply movement pattern
            this.applyMovementPattern(enemy, mapWidth, mapHeight);
            
            // Bounce off walls (using dynamic map size)
            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';
            
            // Check collision with player
            this.checkPlayerEnemyCollision(enemy);
        });
    }

    applyMovementPattern(enemy, mapWidth, mapHeight) {
        enemy.changeDirectionTimer++;
        
        switch (enemy.pattern) {
            case 'patrol':
                // Patrol back and forth
                const distanceFromStart = Math.sqrt(
                    Math.pow(enemy.x - enemy.patrolStartX, 2) + Math.pow(enemy.y - enemy.patrolStartY, 2)
                );
                
                if (distanceFromStart > enemy.patrolDistance) {
                    // Turn around and head back to start
                    const angleToStart = Math.atan2(
                        enemy.patrolStartY - enemy.y,
                        enemy.patrolStartX - enemy.x
                    );
                    enemy.moveDirection = angleToStart;
                }
                
                if (enemy.changeDirectionTimer > 120) { // Change direction every ~2 seconds
                    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':
                enemy.dashCooldown--;
                
                if (enemy.isDashing) {
                    // Continue dash movement with very high speed
                    enemy.x += Math.cos(enemy.moveDirection) * (enemy.speed * 6);
                    enemy.y += Math.sin(enemy.moveDirection) * (enemy.speed * 6);
                    enemy.dashCooldown--;
                    
                    if (enemy.dashCooldown <= 0) {
                        enemy.isDashing = false;
                        enemy.dashCooldown = 120 + Math.random() * 60; // Reset cooldown
                    }
                } else {
                    // Normal chase behavior
                    const angleToPlayer = Math.atan2(
                        this.player.y - enemy.y,
                        this.player.x - enemy.x
                    );
                    
                    // Sometimes do a perpendicular dash
                    if (enemy.dashCooldown <= 0 && Math.random() < 0.3) {
                        enemy.isDashing = true;
                        enemy.dashCooldown = 50; // Much longer dash duration
                        
                        // Perpendicular angle (90 degrees from player direction)
                        const perpAngle = angleToPlayer + (Math.random() < 0.5 ? Math.PI/2 : -Math.PI/2);
                        enemy.moveDirection = perpAngle;
                        
                        // Start dash with visual effect
                        enemy.element.style.filter = 'drop-shadow(0 0 8px red)';
                        setTimeout(() => {
                            enemy.element.style.filter = 'drop-shadow(1px 1px 2px rgba(0,0,0,0.3))';
                        }, 300);
                    } else {
                        // Mix chasing with some randomness
                        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':
                // Random wandering
                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':
                // Move in circular pattern
                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;
                
                // Occasionally change circle center
                if (enemy.changeDirectionTimer > 180) {
                    enemy.circleCenter.x += (Math.random() - 0.5) * 100;
                    enemy.circleCenter.y += (Math.random() - 0.5) * 100;
                    
                    // Keep circle center within bounds
                    enemy.circleCenter.x = Math.max(enemy.circleRadius + 20, 
                        Math.min(mapWidth - enemy.circleRadius - 20, enemy.circleCenter.x));
                    enemy.circleCenter.y = Math.max(enemy.circleRadius + 20, 
                        Math.min(mapHeight - enemy.circleRadius - 20, enemy.circleCenter.y));
                    
                    enemy.changeDirectionTimer = 0;
                }
                break;
        }
    }

    checkPlayerEnemyCollision(enemy) {
        if (this.isPlayerInvulnerable || enemy.defeated) return;
        
        const distance = Math.sqrt(
            Math.pow(this.player.x - enemy.x, 2) + Math.pow(this.player.y - enemy.y, 2)
        );
        
        // Collision detected
        if (distance < 35) {
            this.takeDamage();
        }
    }

    takeDamage() {
        if (this.isPlayerInvulnerable) return;
        
        // Apply damage
        this.score = Math.max(0, this.score - 20);
        this.updateHUD();
        
        // Clear any existing invulnerability timeout
        if (this.invulnerabilityTimeout) {
            clearTimeout(this.invulnerabilityTimeout);
        }
        
        // Start damage invulnerability
        this.isPlayerInvulnerable = true;
        const playerElement = document.getElementById('player');
        
        // Visual feedback - blinking effect
        let blinkCount = 0;
        const blinkInterval = setInterval(() => {
            playerElement.style.opacity = playerElement.style.opacity === '0.3' ? '1' : '0.3';
            blinkCount++;
            
            if (blinkCount >= 8) { // 4 blinks in 2 seconds
                clearInterval(blinkInterval);
                playerElement.style.opacity = '1';
                playerElement.style.filter = 'drop-shadow(2px 2px 4px rgba(0,0,0,0.3))';
                playerElement.style.transform = 'scale(1)';
                this.isPlayerInvulnerable = false;
            }
        }, 250);
        
        // Show damage feedback
        this.showDamagePopup();
    }

    grantAttackInvulnerability() {
        // Always grant invulnerability after attack, even if already invulnerable
        this.isPlayerInvulnerable = true;
        const playerElement = document.getElementById('player');
        
        // Clear any existing timeout
        if (this.invulnerabilityTimeout) {
            clearTimeout(this.invulnerabilityTimeout);
        }
        
        // Different visual effect for attack invulnerability (golden glow)
        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);
        
        // Show invulnerability feedback
        this.showInvulnerabilityPopup();
    }

    refreshAttackInvulnerability() {
        // Refresh the invulnerability timer without changing visual state
        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.position = 'fixed';
        popup.style.left = '50%';
        popup.style.top = '25%';
        popup.style.transform = 'translate(-50%, -50%)';
        popup.style.color = '#FFD700';
        popup.style.fontSize = '1.5rem';
        popup.style.fontWeight = 'bold';
        popup.style.zIndex = '999';
        popup.style.pointerEvents = 'none';
        popup.style.animation = 'protectionFloat 2s ease-out forwards';
        
        document.body.appendChild(popup);
        
        setTimeout(() => {
            popup.remove();
        }, 2000);
    }

    showDamagePopup() {
        // Create damage popup
        const damagePopup = document.createElement('div');
        damagePopup.className = 'damage-popup';
        damagePopup.innerHTML = '-20';
        damagePopup.style.position = 'fixed';
        damagePopup.style.left = '50%';
        damagePopup.style.top = '30%';
        damagePopup.style.transform = 'translate(-50%, -50%)';
        damagePopup.style.color = '#EF4444';
        damagePopup.style.fontSize = '2rem';
        damagePopup.style.fontWeight = 'bold';
        damagePopup.style.zIndex = '999';
        damagePopup.style.pointerEvents = 'none';
        damagePopup.style.animation = 'damageFloat 1.5s ease-out forwards';
        
        document.body.appendChild(damagePopup);
        
        setTimeout(() => {
            damagePopup.remove();
        }, 1500);
    }

    start() {
        logSh('⚔️ Adventure Reader: Starting', 'INFO');
        document.getElementById('progress-text').textContent = 'Click objects to begin your adventure!';
    }

    restart() {
        logSh('🔄 Adventure Reader: Restarting', 'INFO');
        this.reset();
        this.start();
    }

    reset() {
        this.score = 0;
        this.currentSentenceIndex = 0;
        this.currentVocabIndex = 0;
        this.potsDestroyed = 0;
        this.enemiesDefeated = 0;
        this.isGamePaused = false;
        this.isPlayerMoving = false;
        this.isPlayerInvulnerable = false;
        
        // Clear any existing timeout
        if (this.invulnerabilityTimeout) {
            clearTimeout(this.invulnerabilityTimeout);
            this.invulnerabilityTimeout = null;
        }
        
        this.generateGameObjects();
        this.initializePlayer();
        this.generateDecorations();
    }

    // TTS Methods
    speakText(text, options = {}) {
        if (!text || !this.ttsEnabled) return;

        // Use SettingsManager if available for better language support
        if (window.SettingsManager && window.SettingsManager.speak) {
            const ttsOptions = {
                lang: this.getContentLanguage(),
                rate: options.rate || 0.8,
                ...options
            };

            window.SettingsManager.speak(text, ttsOptions)
                .catch(error => {
                    console.warn('🔊 SettingsManager TTS failed:', error);
                    this.fallbackTTS(text, ttsOptions);
                });
        } else {
            this.fallbackTTS(text, options);
        }
    }

    fallbackTTS(text, options = {}) {
        if ('speechSynthesis' in window && text) {
            // Cancel any ongoing speech
            speechSynthesis.cancel();

            const utterance = new SpeechSynthesisUtterance(text);
            utterance.lang = this.getContentLanguage();
            utterance.rate = options.rate || 0.8;
            utterance.volume = 1.0;

            speechSynthesis.speak(utterance);
        }
    }

    getContentLanguage() {
        // Get language from content or use sensible defaults
        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'; // Default fallback
    }

    destroy() {
        // Cancel any ongoing TTS
        if ('speechSynthesis' in window) {
            speechSynthesis.cancel();
        }
        this.container.innerHTML = '';
    }
}

// Module registration
window.GameModules = window.GameModules || {};
window.GameModules.AdventureReader = AdventureReaderGame;