import Module from '../core/Module.js';

/**
 * MarioEducational - 2D Mario-style educational game with question blocks
 * Classic side-scrolling platformer that integrates vocabulary learning through interactive question blocks
 */
class MarioEducational extends Module {
    constructor(name, dependencies, config = {}) {
        super(name, ['eventBus']);

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

        this._eventBus = dependencies.eventBus;
        this._content = dependencies.content;
        this._config = {
            container: null,
            canvasWidth: 1200,
            canvasHeight: 690, // +15% viewport height (600 * 1.15 = 690)
            gravity: 0.8,
            jumpForce: -16,
            moveSpeed: 5,
            maxLevels: 7,
            ...config
        };

        // Game state
        this._canvas = null;
        this._ctx = null;
        this._gameLoop = null;
        this._keys = {};
        this._isGameOver = false;
        this._isPaused = false;
        this._score = 0;
        this._questionsAnswered = 0;
        this._currentLevel = 1;
        this._gameStartTime = null;

        // Mario character
        this._mario = {
            x: 100,
            y: 400,
            width: 32,
            height: 32,
            velocityX: 0,
            velocityY: 0,
            onGround: false,
            facing: 'right',
            color: '#FF6B6B' // Red Mario
        };

        // Game world
        this._camera = { x: 0, y: 0 };
        this._platforms = [];
        this._questionBlocks = [];
        this._enemies = [];
        this._collectibles = [];
        this._particles = [];
        this._walls = [];
        this._castleStructure = null;

        // Advanced level elements
        this._piranhaPlants = [];
        this._projectiles = [];

        // Level 4+ catapult system
        this._catapults = [];
        this._boulders = [];
        this._stones = []; // Small stones from onager

        // Level 5+ flying eyes system
        this._flyingEyes = [];

        // Level 6 boss system
        this._boss = null;
        this._bossTurrets = [];
        this._bossMinions = [];
        this._powerUps = [];
        this._isBoostMode = false;
        this._boostTimer = 0;
        this._bossCollisionCooldown = 0; // Prevent bounce loop

        // Level generation
        this._levelData = [];
        this._currentLevelIndex = 0;
        this._levelWidth = 3000;
        this._sentences = [];
        this._usedSentences = [];

        // Question system
        this._questionDialog = null;
        this._isQuestionActive = false;

        // Celebration mode - blocks enemies but allows particles
        this._isCelebrating = false;

        // Level completion flag to prevent multiple triggers
        this._levelCompleted = false;

        // Input handlers (need to be declared before seal)
        this._handleKeyDown = null;
        this._handleKeyUp = null;

        // UI elements (need to be declared before seal)
        this._uiOverlay = null;

        // Sound system
        this._audioContext = null;
        this._sounds = {};

        Object.seal(this);
    }

    /**
     * Get game metadata
     * @returns {Object} Game metadata
     */
    static getMetadata() {
        return {
            name: 'Mario Educational Adventure',
            description: '2D Mario-style platformer with educational question blocks and vocabulary challenges',
            difficulty: 'intermediate',
            category: 'platformer',
            estimatedTime: 15, // minutes
            skills: ['reading', 'vocabulary', 'comprehension', 'reflexes', 'problem-solving']
        };
    }

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

        const vocabCount = Object.keys(vocab).length;
        const sentenceCount = sentences.length;

        // Count sentences from texts and story
        let extraSentenceCount = 0;

        if (story && typeof story === 'string') {
            extraSentenceCount += story.split(/[.!?]+/).filter(s => s.trim().length > 0).length;
        }

        if (Array.isArray(texts)) {
            texts.forEach(text => {
                if (typeof text === 'string') {
                    extraSentenceCount += text.split(/[.!?]+/).filter(s => s.trim().length > 0).length;
                } else if (text.content) {
                    extraSentenceCount += text.content.split(/[.!?]+/).filter(s => s.trim().length > 0).length;
                }
            });
        }

        const totalSentences = sentenceCount + extraSentenceCount;

        if (totalSentences < 3 && vocabCount < 10) {
            return {
                score: 0,
                reason: `Insufficient content (${totalSentences} sentences, ${vocabCount} vocabulary words)`,
                requirements: ['sentences', 'vocabulary', 'texts', 'story'],
                minSentences: 3,
                minVocabulary: 10,
                details: 'Mario Educational needs at least 3 sentences OR 10+ vocabulary words'
            };
        }

        if (vocabCount < 5) {
            return {
                score: 0.3,
                reason: `Limited vocabulary (${vocabCount}/5 minimum)`,
                requirements: ['sentences', 'vocabulary'],
                minWords: 5,
                details: 'Game can work with sentences but vocabulary enhances learning'
            };
        }

        // Perfect score at 30+ sentences, good score for 10+
        const score = Math.min((totalSentences + vocabCount) / 50, 1);

        return {
            score,
            reason: `${totalSentences} sentences and ${vocabCount} vocabulary words available`,
            requirements: ['sentences', 'vocabulary', 'texts', 'story'],
            minSentences: 3,
            optimalSentences: 30,
            details: `Can create ${Math.min(totalSentences + vocabCount, 50)} question blocks from all content sources`
        };
    }

    async init() {
        this._validateNotDestroyed();

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

            // Extract sentences from content
            this._extractSentences();
            if (this._sentences.length < 5) {
                throw new Error('Insufficient content for Mario Educational game');
            }

            // Setup canvas
            this._setupCanvas();

            // Setup input handlers
            this._setupInputHandlers();

            // Initialize sound system
            this._initializeSoundSystem();

            // Generate all levels
            this._generateAllLevels();

            // Start first level
            this._startLevel(5); // Start at level 6 (index 5) to continue boss work

            // Setup game UI
            this._setupGameUI();

            // Start game loop
            this._startGameLoop();

            this._gameStartTime = Date.now();
            console.log('🎮 Mario Educational game initialized successfully');

            this._setInitialized();

        } catch (error) {
            console.error('❌ Error initializing Mario Educational game:', error);
            throw error;
        }
    }

    async destroy() {
        this._validateNotDestroyed();

        // Stop game loop
        if (this._gameLoop) {
            cancelAnimationFrame(this._gameLoop);
            this._gameLoop = null;
        }

        // Remove event listeners
        document.removeEventListener('keydown', this._handleKeyDown);
        document.removeEventListener('keyup', this._handleKeyUp);

        // Clear canvas
        if (this._canvas && this._canvas.parentNode) {
            this._canvas.parentNode.removeChild(this._canvas);
        }

        // Clear game state
        this._platforms = [];
        this._questionBlocks = [];
        this._enemies = [];
        this._collectibles = [];
        this._particles = [];

        console.log('🎮 Mario Educational game destroyed');
        this._setDestroyed();
    }

    // Private methods
    _extractSentences() {
        const sentences = this._content.sentences || [];
        const vocab = this._content.vocabulary || {};
        const texts = this._content.texts || [];
        const story = this._content.story || '';

        // Combine sentences and vocabulary for questions
        this._sentences = [];

        // Add actual sentences - handle both formats
        sentences.forEach(sentence => {
            // Format 1: Modern format with english/user_language
            if (sentence.english && sentence.user_language) {
                this._sentences.push({
                    type: 'sentence',
                    english: sentence.english,
                    translation: sentence.user_language,
                    context: sentence.context || ''
                });
            }
            // Format 2: Current format with text field
            else if (sentence.text) {
                this._sentences.push({
                    type: 'sentence',
                    english: sentence.text,
                    translation: sentence.translation || 'Read this sentence carefully',
                    context: `Difficulty: ${sentence.difficulty || 'intermediate'}`
                });
            }
        });

        // Extract sentences from story text
        if (story && typeof story === 'string') {
            const storySentences = this._splitTextIntoSentences(story);
            storySentences.forEach(sentence => {
                this._sentences.push({
                    type: 'story',
                    english: sentence,
                    translation: 'Story sentence - read carefully',
                    context: 'Story'
                });
            });
        }

        // Extract sentences from texts array
        if (Array.isArray(texts)) {
            texts.forEach((text, index) => {
                if (typeof text === 'string') {
                    const textSentences = this._splitTextIntoSentences(text);
                    textSentences.forEach(sentence => {
                        this._sentences.push({
                            type: 'text',
                            english: sentence,
                            translation: `Text passage ${index + 1} - practice reading`,
                            context: `Text ${index + 1}`
                        });
                    });
                } else if (text.content) {
                    const textSentences = this._splitTextIntoSentences(text.content);
                    textSentences.forEach(sentence => {
                        this._sentences.push({
                            type: 'text',
                            english: sentence,
                            translation: text.translation || `Read this text sentence`,
                            context: text.title || `Text ${index + 1}`
                        });
                    });
                }
            });
        }

        // Add vocabulary as contextual sentences
        Object.entries(vocab).forEach(([word, data]) => {
            if (data.user_language) {
                const generatedSentence = this._generateSentenceFromWord(word, data);
                this._sentences.push({
                    type: 'vocabulary',
                    english: generatedSentence.english,
                    translation: generatedSentence.translation,
                    context: data.type || 'vocabulary'
                });
            }
        });

        // Shuffle sentences for variety
        this._sentences = this._shuffleArray(this._sentences);

        console.log(`📝 Extracted ${this._sentences.length} sentences/vocabulary for questions`);
    }

    /**
     * Generate contextual sentences from vocabulary words
     * @param {string} word - The vocabulary word
     * @param {Object} data - Word data including type and translation
     * @returns {Object} Generated sentence with English and translation
     */
    /**
     * Split long text into individual sentences
     * @param {string} text - Long text to split
     * @returns {Array} Array of sentences
     */
    _splitTextIntoSentences(text) {
        if (!text || typeof text !== 'string') return [];

        // Clean the text
        const cleanText = text.trim();

        // Split by sentence-ending punctuation
        const sentences = cleanText
            .split(/[.!?]+/)
            .map(s => s.trim())
            .filter(s => s.length > 0)
            .map(s => {
                // Add period if sentence doesn't end with punctuation
                if (!s.match(/[.!?]$/)) {
                    s += '.';
                }
                // Capitalize first letter
                return s.charAt(0).toUpperCase() + s.slice(1);
            });

        // Filter out very short sentences (less than 3 words)
        return sentences.filter(sentence => sentence.split(' ').length >= 3);
    }

    _generateSentenceFromWord(word, data) {
        const type = data.type || 'noun';
        const translation = data.user_language.split('；')[0]; // Use first translation

        // Simple sentence templates based on word type
        const templates = {
            'noun': [
                `This is a ${word}.`,
                `I see a ${word}.`,
                `The ${word} is here.`,
                `Where is the ${word}?`,
                `I need a ${word}.`
            ],
            'adjective': [
                `The house is ${word}.`,
                `This looks ${word}.`,
                `It seems ${word}.`,
                `How ${word} it is!`,
                `The weather is ${word}.`
            ],
            'verb': [
                `I ${word} every day.`,
                `Please ${word} this.`,
                `Don't ${word} too fast.`,
                `Can you ${word}?`,
                `Let's ${word} together.`
            ],
            'adverb': [
                `He walks ${word}.`,
                `She speaks ${word}.`,
                `They work ${word}.`,
                `Do it ${word}.`,
                `Move ${word}.`
            ],
            'preposition': [
                `The book is ${word} the table.`,
                `Walk ${word} the street.`,
                `It's ${word} the house.`,
                `Look ${word} the window.`,
                `Go ${word} the door.`
            ]
        };

        // Get templates for this word type, fallback to noun if type unknown
        const typeTemplates = templates[type] || templates['noun'];
        const randomTemplate = typeTemplates[Math.floor(Math.random() * typeTemplates.length)];

        return {
            english: randomTemplate,
            translation: `${translation} - ${randomTemplate.replace(word, `**${word}**`)}`
        };
    }

    _setupCanvas() {
        this._canvas = document.createElement('canvas');
        this._canvas.width = this._config.canvasWidth;
        this._canvas.height = this._config.canvasHeight;
        this._canvas.style.border = '2px solid #333';
        this._canvas.style.borderRadius = '8px';
        this._canvas.style.background = 'linear-gradient(to bottom, #87CEEB, #98FB98)';

        this._ctx = this._canvas.getContext('2d');
        this._ctx.imageSmoothingEnabled = false; // Pixel art style

        this._config.container.appendChild(this._canvas);
    }

    _setupInputHandlers() {
        this._handleKeyDown = (e) => {
            this._keys[e.code] = true;

            // Prevent default for game controls
            if (['ArrowLeft', 'ArrowRight', 'ArrowUp', 'Space'].includes(e.code)) {
                e.preventDefault();
            }
        };

        this._handleKeyUp = (e) => {
            this._keys[e.code] = false;
        };

        document.addEventListener('keydown', this._handleKeyDown);
        document.addEventListener('keyup', this._handleKeyUp);
    }

    _initializeSoundSystem() {
        try {
            // Initialize Web Audio Context
            this._audioContext = new (window.AudioContext || window.webkitAudioContext)();
            console.log('🔊 Sound system initialized');

            // Create sound library
            this._createSoundLibrary();
        } catch (error) {
            console.warn('⚠️ Sound system not available:', error);
            this._audioContext = null;
        }
    }

    _createSoundLibrary() {
        // Sound definitions with parameters for programmatic generation
        this._sounds = {
            jump: { type: 'sweep', frequency: 330, endFrequency: 600, duration: 0.1 },
            coin: { type: 'bell', frequency: 800, duration: 0.3 },
            powerup: { type: 'arpeggio', frequencies: [264, 330, 396, 528], duration: 0.6 },
            enemy_defeat: { type: 'noise_sweep', frequency: 200, endFrequency: 50, duration: 0.2 },
            question_block: { type: 'sparkle', frequency: 600, endFrequency: 1200, duration: 0.4 },
            level_complete: { type: 'victory', frequencies: [523, 659, 784, 1047], duration: 1.0 },
            death: { type: 'descend', frequency: 300, endFrequency: 100, duration: 0.8 },
            finish_stars: { type: 'magical', frequencies: [880, 1100, 1320, 1760], duration: 2.0 }
        };

        console.log('🎵 Sound library created with', Object.keys(this._sounds).length, 'sounds');
    }

    _playSound(soundName, volume = 0.3) {
        if (!this._audioContext || !this._sounds[soundName]) {
            return;
        }

        try {
            const sound = this._sounds[soundName];
            const oscillator = this._audioContext.createOscillator();
            const gainNode = this._audioContext.createGain();

            oscillator.connect(gainNode);
            gainNode.connect(this._audioContext.destination);

            const currentTime = this._audioContext.currentTime;
            const duration = sound.duration;

            // Set volume
            gainNode.gain.setValueAtTime(0, currentTime);
            gainNode.gain.linearRampToValueAtTime(volume, currentTime + 0.01);
            gainNode.gain.exponentialRampToValueAtTime(0.01, currentTime + duration);

            // Configure sound based on type
            switch (sound.type) {
                case 'sweep':
                    oscillator.type = 'square';
                    oscillator.frequency.setValueAtTime(sound.frequency, currentTime);
                    oscillator.frequency.linearRampToValueAtTime(sound.endFrequency, currentTime + duration);
                    break;

                case 'bell':
                    oscillator.type = 'sine';
                    oscillator.frequency.setValueAtTime(sound.frequency, currentTime);
                    oscillator.frequency.exponentialRampToValueAtTime(sound.frequency * 0.5, currentTime + duration);
                    break;

                case 'noise_sweep':
                    oscillator.type = 'sawtooth';
                    oscillator.frequency.setValueAtTime(sound.frequency, currentTime);
                    oscillator.frequency.linearRampToValueAtTime(sound.endFrequency, currentTime + duration);
                    break;

                case 'sparkle':
                    oscillator.type = 'triangle';
                    oscillator.frequency.setValueAtTime(sound.frequency, currentTime);
                    oscillator.frequency.linearRampToValueAtTime(sound.endFrequency, currentTime + duration * 0.7);
                    oscillator.frequency.linearRampToValueAtTime(sound.frequency, currentTime + duration);
                    break;

                case 'descend':
                    oscillator.type = 'square';
                    oscillator.frequency.setValueAtTime(sound.frequency, currentTime);
                    oscillator.frequency.exponentialRampToValueAtTime(sound.endFrequency, currentTime + duration);
                    break;

                case 'arpeggio':
                case 'victory':
                case 'magical':
                    // For complex sounds, play the first frequency and schedule others
                    oscillator.type = sound.type === 'magical' ? 'triangle' : 'square';
                    oscillator.frequency.setValueAtTime(sound.frequencies[0], currentTime);

                    // Schedule frequency changes for arpeggio effect
                    const noteLength = duration / sound.frequencies.length;
                    sound.frequencies.forEach((freq, index) => {
                        if (index > 0) {
                            oscillator.frequency.setValueAtTime(freq, currentTime + noteLength * index);
                        }
                    });
                    break;

                default:
                    oscillator.type = 'square';
                    oscillator.frequency.setValueAtTime(sound.frequency || 440, currentTime);
            }

            oscillator.start(currentTime);
            oscillator.stop(currentTime + duration);

            console.log(`🎵 Playing sound: ${soundName}`);

        } catch (error) {
            console.warn('⚠️ Failed to play sound:', soundName, error);
        }
    }

    _generateAllLevels() {
        this._levelData = [];

        for (let i = 0; i < this._config.maxLevels; i++) {
            const isLastLevel = i === this._config.maxLevels - 1;
            const level = this._generateLevel(i, isLastLevel);
            this._levelData.push(level);
        }

        console.log(`🏗️ Generated ${this._levelData.length} levels`);
    }

    _generateLevel(levelIndex, isCastleLevel = false) {
        const level = {
            index: levelIndex,
            isCastleLevel,
            platforms: [],
            questionBlocks: [],
            enemies: [],
            collectibles: [],
            walls: [],
            startX: 100,
            startY: 400,
            endX: this._levelWidth - 200,
            width: this._levelWidth
        };

        if (isCastleLevel) {
            return this._generateCastleLevel(level);
        } else {
            return this._generateRegularLevel(level);
        }
    }

    _generateRegularLevel(level) {
        const { index } = level;
        const difficulty = Math.min(index + 1, 5); // Difficulty scales 1-5

        // Generate ground platforms
        for (let x = 0; x < this._levelWidth; x += 200) {
            level.platforms.push({
                x: x,
                y: this._config.canvasHeight - 50,
                width: 200,
                height: 50,
                type: 'ground',
                color: '#8B4513'
            });
        }

        // Generate floating platforms with intelligent placement
        this._generateIntelligentPlatforms(level, difficulty);

        // Generate question blocks on reachable platforms
        const questionCount = 3 + difficulty;
        const availablePlatforms = level.platforms.filter(p => p.y < this._config.canvasHeight - 100);

        for (let i = 0; i < questionCount; i++) {
            const maxAttempts = 5;
            let attemptCount = 0;
            let blockPlaced = false;

            while (attemptCount < maxAttempts && !blockPlaced) {
                attemptCount++;

                const platform = availablePlatforms[Math.floor(Math.random() * availablePlatforms.length)];
                const sentence = this._getRandomSentence();

                if (sentence && platform) {
                    const blockX = platform.x + platform.width / 2 - 16;
                    const blockY = platform.y - 32;
                    const blockWidth = 32;
                    const blockHeight = 32;

                    // Check minimum distance from other question blocks
                    const hasMinDistance = this._checkQuestionBlockDistance(
                        level.questionBlocks, blockX, blockY, blockWidth, blockHeight, 60
                    );

                    if (hasMinDistance) {
                        level.questionBlocks.push({
                            x: blockX,
                            y: blockY,
                            width: blockWidth,
                            height: blockHeight,
                            sentence: sentence,
                            hit: false,
                            color: '#FFD700',
                            symbol: '?'
                        });

                        console.log(`💰 Question block ${i}: x=${blockX.toFixed(0)}, y=${blockY.toFixed(0)}, attempts=${attemptCount}`);
                        blockPlaced = true;
                    } else {
                        console.log(`❌ Question block ${i} attempt ${attemptCount} failed: too close to other blocks`);
                    }
                }
            }

            if (!blockPlaced) {
                console.log(`⚠️ Failed to place question block ${i} after ${maxAttempts} attempts`);
            }
        }

        // Generate simple enemies (avoid walls)
        let helmetEnemyPlaced = false;

        for (let i = 0; i < difficulty; i++) {
            let enemyPlaced = false;
            let attempts = 0;
            const maxAttempts = 20;

            while (!enemyPlaced && attempts < maxAttempts) {
                const platform = level.platforms[Math.floor(Math.random() * level.platforms.length)];
                const enemyX = platform.x + Math.random() * (platform.width - 20);
                const enemyY = platform.y - 20;

                // Check if enemy would spawn inside a wall
                const wouldOverlapWall = level.walls.some(wall => {
                    return enemyX < wall.x + wall.width &&
                           enemyX + 20 > wall.x &&
                           enemyY < wall.y + wall.height &&
                           enemyY + 20 > wall.y;
                });

                // Check if enemy would spawn over a hole (more thorough check)
                const wouldOverlapHole = level.holes && level.holes.some(hole => {
                    return enemyX + 10 >= hole.x && enemyX + 10 <= hole.x + hole.width; // Check center of enemy
                });

                // Check if enemy has solid ground/platform/stair support below
                const hasSolidSupport = this._hasSolidSupportBelow(enemyX, enemyY + 20, level); // Check below enemy position

                if (!wouldOverlapWall && !wouldOverlapHole && hasSolidSupport) {
                    // Level 2+ gets exactly ONE helmet enemy per level
                    const isHelmetEnemy = index >= 1 && !helmetEnemyPlaced && i === 0; // Only first enemy can be helmet

                    if (isHelmetEnemy) {
                        helmetEnemyPlaced = true;
                    }

                    level.enemies.push({
                        x: enemyX,
                        y: enemyY,
                        width: 20,
                        height: 20,
                        velocityX: (Math.random() > 0.5 ? 1 : -1) * (1 + Math.random()),
                        color: isHelmetEnemy ? '#4169E1' : '#8B0000', // Blue for helmet, red for normal
                        type: isHelmetEnemy ? 'koopa' : 'goomba',
                        hasHelmet: isHelmetEnemy
                    });
                    enemyPlaced = true;
                } else {
                    console.log(`🚫 Enemy ${i} attempt ${attempts} would overlap wall/hole/unsupported ground, retrying...`);
                }
                attempts++;
            }

            if (!enemyPlaced) {
                console.log(`⚠️ Failed to place enemy ${i} after ${maxAttempts} attempts`);
            }
        }

        // Level 3+ gets advanced features (except level 6 boss level)
        if (index >= 2 && index <= 4) {
            this._generateHoles(level, difficulty);
            this._generateStairs(level, difficulty);
            this._generatePiranhaPlants(level, difficulty);
        }

        // Level 6 boss level: only stairs (no holes, limited piranha plants)
        if (index === 5) {
            this._generateBossStairs(level, difficulty);
            // Reduced piranha plants for boss level
            if (difficulty > 3) {
                this._generatePiranhaPlants(level, Math.min(difficulty - 2, 2));
            }
        }

        // Level 4-5 gets catapults (NOT level 6 - boss level)
        if (index >= 3 && index <= 4) {
            this._generateCatapults(level, difficulty);
        }

        // Level 5+ gets flying eyes
        if (index >= 4) {
            this._generateFlyingEyes(level, difficulty);
        }

        // Level 6 gets colossal boss
        if (index === 5) {
            this._generateColossalBoss(level, difficulty);
        }

        return level;
    }

    _generateIntelligentPlatforms(level, difficulty) {
        // Calculate Mario's jump capabilities
        const jumpForce = Math.abs(this._config.jumpForce);
        const gravity = this._config.gravity;
        const moveSpeed = this._config.moveSpeed;

        // Physics calculations for jump distances
        const maxJumpHeight = (jumpForce * jumpForce) / (2 * gravity); // Peak height
        const totalAirTime = (2 * jumpForce) / gravity; // Time in air
        const maxHorizontalDistance = moveSpeed * totalAirTime; // Max horizontal distance

        // Safe margins for reachable platforms
        const safeJumpHeight = maxJumpHeight * 0.85;
        const safeHorizontalDistance = maxHorizontalDistance * 0.8;

        console.log(`🔧 Jump physics: height=${safeJumpHeight.toFixed(1)}, distance=${safeHorizontalDistance.toFixed(1)}`);

        const platformCount = 8 + difficulty * 2;
        const groundHeight = this._config.canvasHeight - 50;

        // Define height zones for better vertical distribution
        const heightZones = {
            low: groundHeight - safeJumpHeight * 0.3,      // Just above ground level
            mid: groundHeight - safeJumpHeight * 0.6,      // Medium height
            high: groundHeight - safeJumpHeight * 0.9,     // High platforms
            veryHigh: groundHeight - safeJumpHeight        // Max reachable height
        };

        // Force vertical progression - alternate between height zones
        for (let i = 0; i < platformCount; i++) {
            const maxAttempts = 5;
            let attemptCount = 0;
            let platformPlaced = false;

            while (attemptCount < maxAttempts && !platformPlaced) {
                attemptCount++;

                // Find a suitable previous platform to connect from
                const availablePlatforms = level.platforms.filter(p =>
                    p.x > 100 && p.x < this._levelWidth - 400
                );

                if (availablePlatforms.length === 0) break;

                const fromPlatform = availablePlatforms[Math.floor(Math.random() * availablePlatforms.length)];

                // Force better height distribution
                let targetY;
                const progressRatio = i / platformCount;

                // Bias towards higher platforms as we progress
                if (progressRatio < 0.3) {
                    // Early platforms: mix of low and mid
                    targetY = Math.random() < 0.7 ? heightZones.low : heightZones.mid;
                } else if (progressRatio < 0.7) {
                    // Middle platforms: mix of mid and high
                    targetY = Math.random() < 0.6 ? heightZones.mid : heightZones.high;
                } else {
                    // Later platforms: mix of high and very high
                    targetY = Math.random() < 0.5 ? heightZones.high : heightZones.veryHigh;
                }

                // Add some randomness around target height
                targetY += (Math.random() - 0.5) * safeJumpHeight * 0.2;

                // Calculate horizontal position within jump range
                const distanceRange = {
                    min: safeHorizontalDistance * 0.4,
                    max: safeHorizontalDistance * 0.9
                };

                const direction = Math.random() > 0.5 ? 1 : -1;
                const distance = distanceRange.min + Math.random() * (distanceRange.max - distanceRange.min);
                const newX = fromPlatform.x + (direction * distance);
                const width = 120 + Math.random() * 80;
                const height = 20;
                const finalY = Math.max(50, Math.min(this._config.canvasHeight - 100, targetY));

                // Validate all conditions
                const heightDifference = Math.abs(finalY - fromPlatform.y);
                const horizontalDistance = Math.abs(newX - fromPlatform.x);

                const isReachable = this._validateJumpPossible(
                    horizontalDistance, heightDifference,
                    safeHorizontalDistance, safeJumpHeight,
                    finalY < fromPlatform.y // jumping up or down
                );

                const minDistance = 100; // Increased minimum distance
                const hasMinDistance = this._checkMinimumDistance(
                    level.platforms, newX, finalY, width, height, minDistance
                );

                const isInBounds = newX > 150 && newX + width < this._levelWidth - 300;

                if (isReachable && hasMinDistance && isInBounds) {
                    level.platforms.push({
                        x: newX,
                        y: finalY,
                        width: width,
                        height: height,
                        type: 'floating',
                        color: this._getPlatformColor(finalY, heightZones)
                    });

                    console.log(`📍 Platform ${i}: x=${newX.toFixed(0)}, y=${finalY.toFixed(0)}, attempts=${attemptCount}`);
                    platformPlaced = true;
                } else {
                    console.log(`❌ Platform ${i} attempt ${attemptCount} failed: reachable=${isReachable}, minDist=${hasMinDistance}, bounds=${isInBounds}`);
                }
            }

            if (!platformPlaced) {
                console.log(`⚠️ Failed to place platform ${i} after ${maxAttempts} attempts`);
            }
        }

        // Add some challenge platforms at max difficulty
        if (difficulty >= 3) {
            this._addChallengePlatforms(level, safeHorizontalDistance, safeJumpHeight);
        }

        // Generate walls as obstacles
        this._generateWalls(level, difficulty, safeJumpHeight);
    }

    _validateJumpPossible(horizontalDist, heightDiff, maxHorizontalDist, maxJumpHeight, isJumpingUp) {
        // Check horizontal distance
        if (horizontalDist > maxHorizontalDist) return false;

        // Check vertical distance
        if (isJumpingUp && heightDiff > maxJumpHeight) return false;

        // For downward jumps, allow more flexibility (gravity helps)
        if (!isJumpingUp && heightDiff > maxJumpHeight * 1.5) return false;

        return true;
    }

    _checkMinimumDistance(existingPlatforms, newX, newY, newWidth, newHeight, minDistance) {
        for (const platform of existingPlatforms) {
            // Skip ground platforms for distance check, but increase minimum distance from ground
            if (platform.type === 'ground') {
                // Check minimum distance from ground level (increased)
                if (Math.abs(newY - platform.y) < 120) { // Increased from 80 to 120
                    return false;
                }
                continue;
            }

            // Check for overlap and minimum distance
            const newRight = newX + newWidth;
            const newBottom = newY + newHeight;
            const platformRight = platform.x + platform.width;
            const platformBottom = platform.y + platform.height;

            // Calculate distances between edges
            const horizontalDistance = Math.max(0,
                Math.max(platform.x - newRight, newX - platformRight)
            );
            const verticalDistance = Math.max(0,
                Math.max(platform.y - newBottom, newY - platformBottom)
            );

            // Check if platforms overlap or are too close
            if (horizontalDistance === 0 && verticalDistance === 0) {
                // Overlapping
                return false;
            }

            // Check minimum distance
            const totalDistance = Math.sqrt(horizontalDistance * horizontalDistance + verticalDistance * verticalDistance);
            if (totalDistance < minDistance) {
                return false;
            }
        }
        return true;
    }

    _checkQuestionBlockDistance(existingBlocks, newX, newY, newWidth, newHeight, minDistance) {
        for (const block of existingBlocks) {
            // Calculate distances between edges
            const newRight = newX + newWidth;
            const newBottom = newY + newHeight;
            const blockRight = block.x + block.width;
            const blockBottom = block.y + block.height;

            const horizontalDistance = Math.max(0,
                Math.max(block.x - newRight, newX - blockRight)
            );
            const verticalDistance = Math.max(0,
                Math.max(block.y - newBottom, newY - blockBottom)
            );

            // Check if blocks overlap or are too close
            if (horizontalDistance === 0 && verticalDistance === 0) {
                // Overlapping
                return false;
            }

            // Check minimum distance
            const totalDistance = Math.sqrt(horizontalDistance * horizontalDistance + verticalDistance * verticalDistance);
            if (totalDistance < minDistance) {
                return false;
            }
        }
        return true;
    }

    _getPlatformColor(y, heightZones) {
        if (y >= heightZones.low) return '#90EE90';      // Light green (low)
        if (y >= heightZones.mid) return '#32CD32';      // Green (mid)
        if (y >= heightZones.high) return '#228B22';     // Forest green (high)
        return '#006400';                                // Dark green (very high)
    }

    _generateWalls(level, difficulty, maxJumpHeight) {
        const wallCount = Math.floor(difficulty * 1.5); // More walls as difficulty increases
        const groundHeight = this._config.canvasHeight - 50;

        console.log(`🧱 Generating ${wallCount} walls for difficulty ${difficulty}`);

        for (let i = 0; i < wallCount; i++) {
            // Find suitable positions that don't block critical paths
            const attempts = 20;
            let placed = false;

            for (let attempt = 0; attempt < attempts && !placed; attempt++) {
                // Random position in the middle section of the level
                const x = 400 + Math.random() * (this._levelWidth - 800);

                // Wall heights based on difficulty
                let wallHeight;
                if (difficulty <= 2) {
                    // Low walls - can be jumped over
                    wallHeight = maxJumpHeight * (0.3 + Math.random() * 0.4);
                } else if (difficulty <= 4) {
                    // Medium walls - some jumpable, some need platform
                    wallHeight = Math.random() < 0.5
                        ? maxJumpHeight * (0.3 + Math.random() * 0.4)  // Jumpable
                        : maxJumpHeight * (0.8 + Math.random() * 0.3); // Need platform
                } else {
                    // High walls - mostly need platforms or alternate routes
                    wallHeight = maxJumpHeight * (0.7 + Math.random() * 0.4);
                }

                const wallY = groundHeight - wallHeight;
                const wallWidth = 20 + Math.random() * 30; // Variable width

                // Check if wall placement is valid (not too close to other obstacles)
                const isValidPosition = this._isValidWallPosition(
                    level, x, wallY, wallWidth, wallHeight
                );

                if (isValidPosition) {
                    level.walls.push({
                        x: x,
                        y: wallY,
                        width: wallWidth,
                        height: wallHeight,
                        color: '#8B4513', // Brown color
                        type: wallHeight > maxJumpHeight * 0.6 ? 'tall' : 'short',
                        health: 3, // Wall can be damaged 3 times before being destroyed
                        maxHealth: 3
                    });

                    console.log(`🧱 Wall placed: x=${x.toFixed(0)}, height=${wallHeight.toFixed(0)} (${wallHeight > maxJumpHeight * 0.6 ? 'tall' : 'short'})`);
                    placed = true;
                }
            }
        }
    }

    _isValidWallPosition(level, wallX, wallY, wallWidth, wallHeight) {
        const wallRight = wallX + wallWidth;
        const wallBottom = wallY + wallHeight;
        const minDistance = 120; // Minimum distance from other obstacles

        // Check distance from platforms
        for (const platform of level.platforms) {
            if (platform.type === 'ground') continue; // Skip ground check

            const platformRight = platform.x + platform.width;

            // Check overlap or too close
            if (!(wallRight < platform.x - minDistance ||
                  wallX > platformRight + minDistance ||
                  wallBottom < platform.y - minDistance ||
                  wallY > platform.y + platform.height + minDistance)) {
                return false;
            }
        }

        // Check distance from other walls
        for (const wall of level.walls) {
            const wallRight2 = wall.x + wall.width;

            if (!(wallRight < wall.x - minDistance ||
                  wallX > wallRight2 + minDistance)) {
                return false;
            }
        }

        // Don't place walls too close to start/end
        if (wallX < 300 || wallRight > this._levelWidth - 300) {
            return false;
        }

        return true;
    }

    _addChallengePlatforms(level, maxDistance, maxHeight) {
        // Add 2-3 challenging but reachable platforms
        const challengeCount = 2 + Math.floor(Math.random() * 2);

        for (let i = 0; i < challengeCount; i++) {
            const availablePlatforms = level.platforms.filter(p =>
                p.type === 'floating' && p.x > 300 && p.x < this._levelWidth - 500
            );

            if (availablePlatforms.length === 0) continue;

            const fromPlatform = availablePlatforms[Math.floor(Math.random() * availablePlatforms.length)];

            // Use 90-95% of max capabilities for challenge
            const challengeDistance = maxDistance * (0.9 + Math.random() * 0.05);
            const challengeHeight = maxHeight * (0.8 + Math.random() * 0.15);

            const direction = Math.random() > 0.5 ? 1 : -1;
            const newX = fromPlatform.x + (direction * challengeDistance);
            const newY = Math.max(50, fromPlatform.y - challengeHeight);

            if (newX > 150 && newX < this._levelWidth - 300) {
                level.platforms.push({
                    x: newX,
                    y: newY,
                    width: 100, // Smaller platforms for challenge
                    height: 20,
                    type: 'floating',
                    color: '#FF6B35' // Orange for challenge platforms
                });
            }
        }
    }

    _generateCastleLevel(level) {
        // Ground platforms for entire level
        for (let x = 0; x < this._levelWidth; x += 200) {
            level.platforms.push({
                x: x,
                y: this._config.canvasHeight - 50,
                width: 200,
                height: 50,
                type: 'ground',
                color: '#8B4513'
            });
        }

        // Create single ascending staircase to castle
        const jumpDistance = 180; // Comfortable jump distance
        const castleX = this._levelWidth - 200; // Castle position
        const numberOfPlatforms = Math.floor((castleX - 400) / jumpDistance) + 1;

        // Progressive platforms leading directly to castle
        for (let i = 0; i < numberOfPlatforms; i++) {
            const x = 400 + i * jumpDistance;
            const y = this._config.canvasHeight - 100 - (i * 30); // Steeper but manageable ascent
            const isNearCastle = x > castleX - 300;

            level.platforms.push({
                x: x,
                y: Math.max(200, y), // Higher ceiling for castle approach
                width: isNearCastle ? 160 : 140, // Wider near castle
                height: 20,
                type: 'ascending',
                color: isNearCastle ? '#FFD700' : '#32CD32' // Gold near castle
            });
        }

        // Final platform right at castle level
        level.platforms.push({
            x: this._levelWidth - 360, // Aligned with shifted castle
            y: this._config.canvasHeight - 160, // Lower since castle is on ground
            width: 160,
            height: 20,
            type: 'castle_entrance',
            color: '#FFD700'
        });

        // Castle emoji (visual only - no collision!)
        const groundLevel = this._config.canvasHeight - 50;
        level.castleStructure = {
            x: this._levelWidth - 280, // Shifted left
            y: groundLevel - 140, // Slightly in ground (360/2 = 180, but -140 puts it 40px in ground)
            emoji: '🏰',
            size: 360,
            princess: {
                x: this._levelWidth - 280, // Same X as castle
                y: groundLevel - 200, // Above castle, adjusted for lower castle
                emoji: '👸',
                size: 50 // Slightly bigger princess
            }
        };

        // Question blocks on accessible platforms
        const accessiblePlatforms = level.platforms.filter(p => p.type === 'ascending' || p.type === 'floating');

        for (let i = 0; i < Math.min(5, accessiblePlatforms.length); i++) {
            const platform = accessiblePlatforms[i];
            const sentence = this._getRandomSentence();

            if (sentence) {
                level.questionBlocks.push({
                    x: platform.x + platform.width / 2 - 16,
                    y: platform.y - 32,
                    width: 32,
                    height: 32,
                    sentence: sentence,
                    hit: false,
                    color: '#FFD700',
                    symbol: '?'
                });
            }
        }

        console.log(`🏰 Castle level generated with ${level.platforms.length} platforms and castle structure`);
        return level;
    }

    _generateHoles(level, difficulty) {
        const holeCount = Math.min(difficulty - 1, 3); // 1-3 holes based on difficulty
        level.holes = []; // Store hole positions to avoid spawning over them

        for (let i = 0; i < holeCount; i++) {
            let holeX, holeWidth = 1; // TEST: 1 pixel wide to see the holes clearly
            let validPosition = false;
            let attempts = 0;
            const maxAttempts = 20;

            while (!validPosition && attempts < maxAttempts) {
                holeX = 300 + (i * 800) + Math.random() * 400; // Spread holes out

                // Check minimum distance from other holes (at least 2 tiles = 400px apart)
                const tooCloseToOtherHole = level.holes.some(existingHole => {
                    return Math.abs(holeX - existingHole.x) < 400;
                });

                if (!tooCloseToOtherHole) {
                    validPosition = true;
                }
                attempts++;
            }

            if (validPosition) {
                // Store hole position for collision avoidance
                level.holes.push({
                    x: holeX,
                    width: holeWidth
                });

                // Simply remove ground platforms that overlap with hole area
                level.platforms = level.platforms.filter(platform => {
                    if (platform.type === 'ground') {
                        return !(platform.x < holeX + holeWidth && platform.x + platform.width > holeX);
                    }
                    return true;
                });

                console.log(`🕳️ Hole ${i} created by removing ground at x=${holeX.toFixed(0)}, width=${holeWidth}px`);
            } else {
                console.log(`⚠️ Failed to place hole ${i} after ${maxAttempts} attempts - too close to other holes`);
            }
        }
    }

    _generateStairs(level, difficulty) {
        const groundLevel = this._config.canvasHeight - 50;
        const stairCount = Math.min(difficulty, 2); // 1-2 stair sets

        for (let i = 0; i < stairCount; i++) {
            let stairPlaced = false;
            let attempts = 0;
            const maxAttempts = 20;

            while (!stairPlaced && attempts < maxAttempts) {
                const stairX = 500 + (i * 1000) + Math.random() * 300;
                const stepWidth = 80;
                const stepHeight = 40;
                const steps = 3 + Math.floor(Math.random() * 3); // 3-5 steps

                // Check if stairs would collide with existing platforms or holes
                let wouldCollide = false;

                // Check collision with holes first
                const overHole = level.holes && level.holes.some(hole => {
                    return stairX < hole.x + hole.width && stairX + (steps * stepWidth) > hole.x;
                });

                if (overHole) {
                    wouldCollide = true;
                } else {
                    // Check collision with existing platforms
                    for (let step = 0; step < steps; step++) {
                        const stepX = stairX + (step * stepWidth);
                        const stepY = groundLevel - ((step + 1) * stepHeight);

                        const hasCollision = level.platforms.some(platform => {
                            return stepX < platform.x + platform.width &&
                                   stepX + stepWidth > platform.x &&
                                   stepY < platform.y + platform.height &&
                                   stepY + stepHeight > platform.y;
                        });

                        if (hasCollision) {
                            wouldCollide = true;
                            break;
                        }
                    }
                }

                if (!wouldCollide) {
                    // Generate ascending stairs
                    for (let step = 0; step < steps; step++) {
                        level.platforms.push({
                            x: stairX + (step * stepWidth),
                            y: groundLevel - ((step + 1) * stepHeight),
                            width: stepWidth,
                            height: stepHeight,
                            color: '#8B4513', // Brown like walls
                            type: 'stair'
                        });
                    }
                    stairPlaced = true;
                    console.log(`🪜 Stairs created at x=${stairX.toFixed(0)}, ${steps} steps`);
                } else {
                    console.log(`🚫 Stair attempt ${attempts} at x=${stairX.toFixed(0)} would collide, retrying...`);
                }
                attempts++;
            }

            if (!stairPlaced) {
                console.log(`⚠️ Failed to place stairs ${i} after ${maxAttempts} attempts`);
            }
        }
    }

    _generatePiranhaPlants(level, difficulty) {
        const plantCount = Math.min(difficulty - 2, 2); // 0-2 plants for level 3+

        for (let i = 0; i < plantCount; i++) {
            // Find a suitable ground platform for the plant
            const groundPlatforms = level.platforms.filter(p => p.type === 'ground');
            if (groundPlatforms.length === 0) continue;

            const platform = groundPlatforms[Math.floor(Math.random() * groundPlatforms.length)];
            const plantX = platform.x + Math.random() * (platform.width - 30);

            level.piranhaPlants = level.piranhaPlants || [];
            level.piranhaPlants.push({
                x: plantX,
                y: platform.y - 40, // Plant height
                width: 30,
                height: 40,
                color: '#228B22', // Forest green
                lastShot: 0,
                shootCooldown: 2000 + Math.random() * 1000, // 2-3 second intervals
                type: 'piranha'
            });

            console.log(`🌸 Piranha plant placed at x=${plantX.toFixed(0)}`);
        }
    }

    _generateCatapults(level, difficulty) {
        const { index } = level;

        let catapultCount = 1; // Always 1 catapult for level 4+
        let onagerCount = 0;

        // Level 5+ gets onagers
        if (index >= 4) {
            onagerCount = 1; // 1 onager for level 5+
        }

        const totalCount = catapultCount + onagerCount;
        console.log(`🏹 Generating ${catapultCount} catapult(s) and ${onagerCount} onager(s) for level ${index + 1}`);

        for (let i = 0; i < totalCount; i++) {
            const isOnager = i >= catapultCount; // Onagers come after catapults
            // Place catapults near END of level to help finish it
            const nearEndX = this._levelWidth * 0.7; // 70% through level
            const catapultX = nearEndX + (i * 300) + Math.random() * 200;
            let catapultY = this._config.canvasHeight - 100; // Default: on background ground

            // Check if there's a platform, wall, or stair above this position
            const platformAbove = this._findPlatformAbove(catapultX, catapultY, level.platforms || []);
            const wallAbove = this._findWallAbove(catapultX, catapultY, level.walls || []);
            const stairAbove = this._findStairAbove(catapultX, catapultY, level.stairs || []);

            // Choose the lowest obstacle (closest to ground = highest Y value)
            let obstacleAbove = null;
            const obstacles = [platformAbove, wallAbove, stairAbove].filter(obs => obs !== null);

            if (obstacles.length > 0) {
                // Find the obstacle with the highest Y value (closest to ground)
                obstacleAbove = obstacles.reduce((lowest, current) =>
                    current.y > lowest.y ? current : lowest
                );
            }

            if (obstacleAbove) {
                // Place catapult ON TOP of the obstacle
                catapultY = obstacleAbove.y - 80; // 80 is catapult height
                console.log(`🏹 Catapult moved to obstacle at y=${catapultY.toFixed(0)}`);
            }

            level.catapults = level.catapults || [];
            level.catapults.push({
                x: catapultX,
                y: catapultY,
                width: 60,
                height: 80,
                color: isOnager ? '#654321' : '#8B4513', // Onager: darker brown, Catapult: normal brown
                lastShot: 0,
                shootCooldown: isOnager ? 6000 + Math.random() * 2000 : 4000 + Math.random() * 2000, // Onager shoots much less often (6-8s vs 4-6s)
                type: isOnager ? 'onager' : 'catapult',
                isOnager: isOnager
            });

            console.log(`${isOnager ? '🏛️' : '🏹'} ${isOnager ? 'Onager' : 'Catapult'} placed at x=${catapultX.toFixed(0)}, y=${catapultY.toFixed(0)}`);
        }
    }

    _findPlatformAbove(x, groundY, platforms) {
        // Find the lowest platform that's above the ground position and overlaps horizontally
        let bestPlatform = null;
        let lowestY = 0; // We want the platform closest to ground (highest Y value)

        platforms.forEach(platform => {
            // Check horizontal overlap (catapult width is 60)
            const catapultLeft = x;
            const catapultRight = x + 60;
            const platformLeft = platform.x;
            const platformRight = platform.x + platform.width;

            const hasHorizontalOverlap = catapultLeft < platformRight && catapultRight > platformLeft;

            // Check if platform is above ground and has horizontal overlap
            if (hasHorizontalOverlap && platform.y < groundY && platform.y > lowestY) {
                bestPlatform = platform;
                lowestY = platform.y;
            }
        });

        return bestPlatform;
    }

    _findWallAbove(x, groundY, walls) {
        // Find the lowest wall that's above the ground position and overlaps horizontally
        let bestWall = null;
        let lowestY = 0; // We want the wall closest to ground (highest Y value)

        walls.forEach(wall => {
            // Check horizontal overlap (catapult width is 60)
            const catapultLeft = x;
            const catapultRight = x + 60;
            const wallLeft = wall.x;
            const wallRight = wall.x + wall.width;

            const hasHorizontalOverlap = catapultLeft < wallRight && catapultRight > wallLeft;

            // Check if wall is above ground and has horizontal overlap
            if (hasHorizontalOverlap && wall.y < groundY && wall.y > lowestY) {
                bestWall = wall;
                lowestY = wall.y;
            }
        });

        return bestWall;
    }

    _findStairAbove(x, groundY, stairs) {
        // Find the lowest stair that's above the ground position and overlaps horizontally
        let bestStair = null;
        let lowestY = 0; // We want the stair closest to ground (highest Y value)

        stairs.forEach(stair => {
            // Check horizontal overlap (catapult width is 60)
            const catapultLeft = x;
            const catapultRight = x + 60;
            const stairLeft = stair.x;
            const stairRight = stair.x + stair.width;

            const hasHorizontalOverlap = catapultLeft < stairRight && catapultRight > stairLeft;

            // Check if stair is above ground and has horizontal overlap
            if (hasHorizontalOverlap && stair.y < groundY && stair.y > lowestY) {
                bestStair = stair;
                lowestY = stair.y;
            }
        });

        return bestStair;
    }

    _generateColossalBoss(level, difficulty) {
        console.log(`👹 Generating Colossal Boss for level 6!`);

        // Boss positioned in center-right of level to block the path
        const bossX = this._levelWidth * 0.6; // 60% through the level
        const bossY = this._config.canvasHeight - 250; // Standing on ground
        const bossWidth = 150;
        const bossHeight = 200;

        level.boss = {
            x: bossX,
            y: bossY,
            width: bossWidth,
            height: bossHeight,
            health: 5, // Takes 5 hits (1/5 each)
            maxHealth: 5,
            color: '#2F4F4F', // Dark slate gray
            type: 'colossus',
            // Collision boxes (knees for damage)
            leftKnee: {
                x: bossX + 20,
                y: bossY + bossHeight - 60,
                width: 40,
                height: 40
            },
            rightKnee: {
                x: bossX + bossWidth - 60,
                y: bossY + bossHeight - 60,
                width: 40,
                height: 40
            },
            // Boss behavior
            lastTurretShot: Date.now(),
            turretCooldown: 2000, // Turrets fire every 2 seconds
            lastMinionLaunch: Date.now(),
            minionCooldown: 4000, // Launch minions every 4 seconds
            // Visual
            eyeColor: '#FF0000', // Red glowing eyes
            isDamaged: false,
            damageFlashTimer: 0
        };

        // Generate turrets on the boss (2 turrets)
        level.bossTurrets = [
            {
                x: bossX + 30,
                y: bossY + 50,
                width: 25,
                height: 25,
                color: '#8B4513',
                type: 'turret',
                lastShot: Date.now(),
                shootCooldown: 2500 // Individual cooldown
            },
            {
                x: bossX + bossWidth - 55,
                y: bossY + 50,
                width: 25,
                height: 25,
                color: '#8B4513',
                type: 'turret',
                lastShot: Date.now(),
                shootCooldown: 3000 // Slightly different timing
            }
        ];

        console.log(`👹 Colossal Boss spawned at x=${bossX.toFixed(0)}, health=${level.boss.health}`);
        console.log(`🔫 ${level.bossTurrets.length} turrets mounted on boss`);
    }

    _generateBossStairs(level, difficulty) {
        const groundLevel = this._config.canvasHeight - 50;
        const stairCount = Math.min(3, 2); // Maximum 3 stair sets for boss level

        for (let i = 0; i < stairCount; i++) {
            let stairPlaced = false;
            let attempts = 0;
            const maxAttempts = 20;

            while (!stairPlaced && attempts < maxAttempts) {
                const stairX = 400 + (i * 800) + Math.random() * 300;
                const stepWidth = 80;
                const stepHeight = 30;
                const maxSteps = 2; // BOSS LEVEL: Maximum 2 steps only

                // Check if stair area is clear of holes and other obstacles
                const stairAreaClear = true; // No holes in boss level

                if (stairAreaClear) {
                    level.stairs = level.stairs || [];

                    // Generate stair steps (max 2 steps)
                    for (let step = 0; step < maxSteps; step++) {
                        level.stairs.push({
                            x: stairX + (step * stepWidth),
                            y: groundLevel - ((step + 1) * stepHeight),
                            width: stepWidth,
                            height: stepHeight * (step + 1), // Height increases with each step
                            color: '#D2691E', // Orange brown for boss level stairs
                            type: 'stair'
                        });
                    }

                    stairPlaced = true;
                    console.log(`🏰 Boss stair ${i + 1} placed at x=${stairX.toFixed(0)} (${maxSteps} steps max)`);
                }

                attempts++;
            }

            if (!stairPlaced) {
                console.log(`⚠️ Failed to place boss stair ${i} after ${maxAttempts} attempts`);
            }
        }
    }

    _generateFlyingEyes(level, difficulty) {
        const eyeCount = Math.min(4, Math.max(3, difficulty - 2)); // 3-4 flying eyes (more guaranteed)
        console.log(`👁️ Generating ${eyeCount} flying eyes for level 5+`);

        for (let i = 0; i < eyeCount; i++) {
            // Eyes spawn in the middle-upper area of the level
            const eyeX = 300 + (i * 400) + Math.random() * 200; // Spread across level
            const eyeY = 100 + Math.random() * 150; // Upper area of screen

            level.flyingEyes = level.flyingEyes || [];
            level.flyingEyes.push({
                x: eyeX,
                y: eyeY,
                width: 30,
                height: 30,
                velocityX: (Math.random() - 0.5) * 2, // Random horizontal drift -1 to +1
                velocityY: (Math.random() - 0.5) * 2, // Random vertical drift -1 to +1
                color: '#DC143C', // Crimson red
                pupilColor: '#000000', // Black pupil
                type: 'flying_eye',
                health: 1,
                // AI behavior properties
                chaseDistance: 200, // Start chasing Mario within 200px
                chaseSpeed: 3.5, // Faster chase speed
                idleSpeed: 1.2, // Faster idle movement
                lastDirectionChange: Date.now(),
                directionChangeInterval: 2000 + Math.random() * 3000, // Change direction every 2-5 seconds
                isChasing: false,
                // Dash behavior
                dashCooldown: 0,
                dashDuration: 0,
                isDashing: false,
                dashSpeed: 8, // Very fast dash
                lastDashTime: Date.now(),
                dashInterval: 3000 + Math.random() * 2000, // Dash every 3-5 seconds
                // Visual properties
                blinkTimer: 0,
                isBlinking: false
            });

            console.log(`👁️ Flying eye ${i + 1} placed at x=${eyeX.toFixed(0)}, y=${eyeY.toFixed(0)}`);
        }
    }

    _hasSolidSupportBelow(x, y, level) {
        // Check if there's solid support (ground platforms, floating platforms, stairs) directly below this position
        const enemyWidth = 20;
        const enemyCenterX = x + 10; // Center of enemy
        const checkY = y + 5; // Just below the enemy

        // Check if there's a ground platform below (that wasn't removed by holes)
        const hasGroundPlatform = level.platforms.some(platform => {
            const isGroundLevel = platform.type === 'ground' && platform.y >= this._config.canvasHeight - 60;
            const isUnderEnemy = platform.x <= enemyCenterX && platform.x + platform.width >= enemyCenterX;
            const isBelow = platform.y >= checkY;
            return isGroundLevel && isUnderEnemy && isBelow;
        });

        // Check if there's any other platform below
        const hasFloatingPlatform = level.platforms.some(platform => {
            const isFloating = platform.type !== 'ground';
            const isUnderEnemy = platform.x <= enemyCenterX && platform.x + platform.width >= enemyCenterX;
            const isBelow = platform.y >= checkY && platform.y <= checkY + 50; // Within reasonable distance below
            return isFloating && isUnderEnemy && isBelow;
        });

        // Check if there's a stair below
        const hasStairSupport = level.stairs && level.stairs.some(stair => {
            const isUnderEnemy = stair.x <= enemyCenterX && stair.x + stair.width >= enemyCenterX;
            const isBelow = stair.y >= checkY && stair.y <= checkY + 50;
            return isUnderEnemy && isBelow;
        });

        return hasGroundPlatform || hasFloatingPlatform || hasStairSupport;
    }

    _hasLineOfSight(catapult, targetX, targetY) {
        // Check only the BEGINNING of the trajectory (immediate launch area)
        const startX = catapult.x + 30; // Center of catapult
        const startY = catapult.y - 10; // Top of catapult

        // Check just the first 3 points of trajectory (immediate launch area only)
        const steps = 3;
        for (let i = 1; i <= steps; i++) {
            const progress = i / 10; // Only check first 30% of trajectory
            const checkX = startX + (targetX - startX) * progress;
            const checkY = startY + (targetY - startY) * progress * 0.5; // Slight arc

            // Check if any platform blocks this immediate launch area
            const blocked = this._platforms.some(platform =>
                checkX >= platform.x &&
                checkX <= platform.x + platform.width &&
                checkY >= platform.y &&
                checkY <= platform.y + platform.height
            );

            if (blocked) {
                return false; // Launch area blocked
            }
        }

        return true; // Clear launch area
    }

    _startLevel(levelIndex) {
        if (levelIndex >= this._levelData.length) {
            this._completeGame();
            return;
        }

        this._currentLevelIndex = levelIndex;
        this._currentLevel = levelIndex + 1;

        // Reset completion flag for new level
        this._levelCompleted = false;
        this._isCelebrating = false;

        const level = this._levelData[levelIndex];
        this._platforms = [...level.platforms];
        this._questionBlocks = [...level.questionBlocks];
        this._enemies = [...level.enemies];
        this._collectibles = [...level.collectibles];
        this._walls = [...(level.walls || [])];
        this._castleStructure = level.castleStructure || null;

        // Advanced level elements
        this._piranhaPlants = [...(level.piranhaPlants || [])];
        this._projectiles = []; // Reset projectiles each level

        // Level 4+ catapult system
        this._catapults = [...(level.catapults || [])];
        this._boulders = []; // Reset boulders each level
        this._stones = []; // Reset stones each level

        // Level 5+ flying eyes system
        this._flyingEyes = [...(level.flyingEyes || [])];

        // Level 6 boss system
        this._boss = level.boss || null;
        this._bossTurrets = [...(level.bossTurrets || [])];
        this._bossMinions = []; // Reset minions each level
        this._powerUps = []; // Reset power-ups each level

        // Reset Mario position
        this._mario.x = level.startX;
        this._mario.y = level.startY;
        this._mario.velocityX = 0;
        this._mario.velocityY = 0;
        this._mario.onGround = false;

        // Reset camera
        this._camera.x = 0;
        this._camera.y = 0;

        console.log(`🎮 Started level ${this._currentLevel}${level.isCastleLevel ? ' (Castle)' : ''}`);
    }

    _setupGameUI() {
        // Create UI overlay
        const uiOverlay = document.createElement('div');
        uiOverlay.style.position = 'absolute';
        uiOverlay.style.top = '10px';
        uiOverlay.style.left = '10px';
        uiOverlay.style.color = 'white';
        uiOverlay.style.fontFamily = 'Arial, sans-serif';
        uiOverlay.style.fontSize = '18px';
        uiOverlay.style.fontWeight = 'bold';
        uiOverlay.style.textShadow = '2px 2px 4px rgba(0,0,0,0.8)';
        uiOverlay.style.pointerEvents = 'none';
        uiOverlay.style.zIndex = '10';

        this._uiOverlay = uiOverlay;
        this._config.container.style.position = 'relative';
        this._config.container.appendChild(uiOverlay);
    }

    _startGameLoop() {
        const gameLoop = () => {
            if (!this._isGameOver && !this._isPaused && !this._isQuestionActive) {
                this._update();
            }
            this._render();
            this._gameLoop = requestAnimationFrame(gameLoop);
        };

        gameLoop();
    }

    _update() {
        // Handle input
        this._updateMarioMovement();

        // Update Mario physics
        this._updateMarioPhysics();

        // Update enemies
        this._updateEnemies();

        // Check collisions
        this._checkCollisions();

        // Update camera
        this._updateCamera();

        // Update advanced elements
        this._updatePiranhaPlants();
        this._updateProjectiles();

        // Update level 4+ elements
        this._updateCatapults();
        this._updateBoulders();
        this._updateStones();

        // Update level 5+ elements
        this._updateFlyingEyes();

        // Update level 6 boss elements
        this._updateBoss();

        // Update particles
        this._updateParticles();

        // Check level completion
        this._checkLevelCompletion();
    }

    _updateMarioMovement() {
        // Don't update movement during celebration
        if (this._isCelebrating) return;

        // Horizontal movement
        if (this._keys['ArrowLeft'] || this._keys['KeyA']) {
            this._mario.velocityX = -this._config.moveSpeed;
            this._mario.facing = 'left';
        } else if (this._keys['ArrowRight'] || this._keys['KeyD']) {
            this._mario.velocityX = this._config.moveSpeed;
            this._mario.facing = 'right';
        } else {
            this._mario.velocityX *= 0.8; // Friction
        }

        // Jumping
        if ((this._keys['ArrowUp'] || this._keys['KeyW'] || this._keys['Space']) && this._mario.onGround) {
            this._mario.velocityY = this._config.jumpForce;
            this._mario.onGround = false;
            this._playSound('jump');
        }
    }

    _updateMarioPhysics() {
        // Apply gravity
        this._mario.velocityY += this._config.gravity;

        // Update position
        this._mario.x += this._mario.velocityX;
        this._mario.y += this._mario.velocityY;

        // Prevent going off left edge
        if (this._mario.x < 0) {
            this._mario.x = 0;
        }

        // Stop Mario at finish line during celebration
        const level = this._levelData[this._currentLevelIndex];
        if (this._mario.x > level.endX && this._levelCompleted) {
            this._mario.x = level.endX;
            this._mario.velocityX = 0;
        }

        // Check if Mario fell off the world
        if (this._mario.y > this._config.canvasHeight + 100) {
            this._restartLevel();
        }
    }

    _updateEnemies() {
        // Don't update enemies during celebration
        if (this._isCelebrating) return;

        this._enemies.forEach(enemy => {
            // Store old position for collision detection
            const oldX = enemy.x;
            enemy.x += enemy.velocityX;

            // Check wall collisions
            const hitWall = this._walls.some(wall => {
                return enemy.x < wall.x + wall.width &&
                       enemy.x + enemy.width > wall.x &&
                       enemy.y < wall.y + wall.height &&
                       enemy.y + enemy.height > wall.y;
            });

            if (hitWall) {
                // Reverse position and direction
                enemy.x = oldX;
                enemy.velocityX *= -1;
                console.log(`🧱 Enemy hit wall, reversing direction`);
            }

            // Simple AI: reverse direction at platform edges
            const platform = this._platforms.find(p =>
                enemy.x >= p.x - 10 && enemy.x <= p.x + p.width + 10 &&
                enemy.y >= p.y - enemy.height - 5 && enemy.y <= p.y + 5
            );

            if (!platform || enemy.x <= 0 || enemy.x >= this._levelWidth) {
                enemy.velocityX *= -1;
            }
        });
    }

    _checkCollisions() {
        // Platform collisions
        this._mario.onGround = false;

        this._platforms.forEach(platform => {
            if (this._isColliding(this._mario, platform)) {
                // Calculate overlap amounts to determine collision direction
                const overlapLeft = (this._mario.x + this._mario.width) - platform.x;
                const overlapRight = (platform.x + platform.width) - this._mario.x;
                const overlapTop = (this._mario.y + this._mario.height) - platform.y;
                const overlapBottom = (platform.y + platform.height) - this._mario.y;

                // Find the smallest overlap to determine collision side
                const minOverlap = Math.min(overlapLeft, overlapRight, overlapTop, overlapBottom);

                if (minOverlap === overlapTop && this._mario.velocityY > 0) {
                    // Landing on top of platform
                    this._mario.y = platform.y - this._mario.height;
                    this._mario.velocityY = 0;
                    this._mario.onGround = true;
                }
                else if (minOverlap === overlapBottom && this._mario.velocityY < 0) {
                    // Hitting platform from below
                    this._mario.y = platform.y + platform.height;
                    this._mario.velocityY = 0;
                }
                else if (minOverlap === overlapLeft && this._mario.velocityX > 0) {
                    // Hitting platform from left
                    this._mario.x = platform.x - this._mario.width;
                    this._mario.velocityX = 0;
                }
                else if (minOverlap === overlapRight && this._mario.velocityX < 0) {
                    // Hitting platform from right
                    this._mario.x = platform.x + platform.width;
                    this._mario.velocityX = 0;
                }
            }
        });

        // Boulder platform collisions (landed boulders act as platforms)
        this._boulders.forEach(boulder => {
            if (boulder.hasLanded && this._isColliding(this._mario, boulder)) {
                // Same collision logic as platforms
                const overlapLeft = (this._mario.x + this._mario.width) - boulder.x;
                const overlapRight = (boulder.x + boulder.width) - this._mario.x;
                const overlapTop = (this._mario.y + this._mario.height) - boulder.y;
                const overlapBottom = (boulder.y + boulder.height) - this._mario.y;
                const minOverlap = Math.min(overlapLeft, overlapRight, overlapTop, overlapBottom);

                if (minOverlap === overlapTop && this._mario.velocityY > 0) {
                    // Landing on top of boulder
                    this._mario.y = boulder.y - this._mario.height;
                    this._mario.velocityY = 0;
                    this._mario.onGround = true;
                }
                else if (minOverlap === overlapBottom && this._mario.velocityY < 0) {
                    // Hitting boulder from below
                    this._mario.y = boulder.y + boulder.height;
                    this._mario.velocityY = 0;
                }
                else if (minOverlap === overlapLeft && this._mario.velocityX > 0) {
                    // Hitting boulder from left
                    this._mario.x = boulder.x - this._mario.width;
                    this._mario.velocityX = 0;
                }
                else if (minOverlap === overlapRight && this._mario.velocityX < 0) {
                    // Hitting boulder from right
                    this._mario.x = boulder.x + boulder.width;
                    this._mario.velocityX = 0;
                }
            }
        });

        // Question block collisions
        this._questionBlocks.forEach(block => {
            if (!block.hit && this._isColliding(this._mario, block)) {
                // Hit from below (jumping into block)
                if (this._mario.velocityY < 0 &&
                    this._mario.y > block.y + block.height / 2) {
                    this._hitQuestionBlock(block);
                }
                // Touch from side or top
                else {
                    this._hitQuestionBlock(block);
                }
            }
        });

        // Wall collisions
        this._walls.forEach(wall => {
            if (this._isColliding(this._mario, wall)) {
                // Calculate overlap amounts to determine collision direction
                const overlapLeft = (this._mario.x + this._mario.width) - wall.x;
                const overlapRight = (wall.x + wall.width) - this._mario.x;
                const overlapTop = (this._mario.y + this._mario.height) - wall.y;
                const overlapBottom = (wall.y + wall.height) - this._mario.y;

                // Find the smallest overlap to determine collision side
                const minOverlap = Math.min(overlapLeft, overlapRight, overlapTop, overlapBottom);

                if (minOverlap === overlapTop && this._mario.velocityY > 0) {
                    // Landing on top of wall
                    this._mario.y = wall.y - this._mario.height;
                    this._mario.velocityY = 0;
                    this._mario.onGround = true;
                }
                else if (minOverlap === overlapBottom && this._mario.velocityY < 0) {
                    // Hitting wall from below
                    this._mario.y = wall.y + wall.height;
                    this._mario.velocityY = 0;
                }
                else if (minOverlap === overlapLeft && this._mario.velocityX > 0) {
                    // Hitting wall from left
                    this._mario.x = wall.x - this._mario.width;
                    this._mario.velocityX = 0;
                }
                else if (minOverlap === overlapRight && this._mario.velocityX < 0) {
                    // Hitting wall from right
                    this._mario.x = wall.x + wall.width;
                    this._mario.velocityX = 0;
                }
            }
        });

        // Catapult collisions (Mario destroys catapults!)
        this._catapults.forEach((catapult, index) => {
            if (this._isColliding(this._mario, catapult)) {
                console.log(`💥 Mario destroyed catapult! Explosion!`);

                // Create massive explosion effect at catapult center
                const explosionX = catapult.x + catapult.width / 2;
                const explosionY = catapult.y + catapult.height / 2;

                // Generate lots of particles flying in all directions
                for (let i = 0; i < 25; i++) {
                    const angle = (Math.PI * 2 * i) / 25; // Spread particles in circle
                    const speed = 3 + Math.random() * 4; // Random speed 3-7
                    const particleColor = ['#8B4513', '#654321', '#D2691E', '#FF4500', '#FFD700'][Math.floor(Math.random() * 5)];

                    this._particles.push({
                        x: explosionX,
                        y: explosionY,
                        velocityX: Math.cos(angle) * speed,
                        velocityY: Math.sin(angle) * speed,
                        color: particleColor,
                        life: 60 + Math.random() * 30, // Live 60-90 frames
                        maxLife: 60 + Math.random() * 30,
                        size: 3 + Math.random() * 4 // Size 3-7
                    });
                }

                // Remove the destroyed catapult
                this._catapults.splice(index, 1);

                // Play destruction sound and bounce Mario up slightly
                this._playSound('enemy_defeat');
                this._mario.velocityY = this._config.jumpForce * 0.5; // Small bounce from impact

                console.log(`🏹 Catapult destroyed! ${this._catapults.length} catapults remaining.`);
            }
        });

        // Enemy collisions
        this._enemies.forEach((enemy, index) => {
            if (this._isColliding(this._mario, enemy)) {
                // Calculate overlap to determine if Mario is stomping enemy
                const overlapTop = (this._mario.y + this._mario.height) - enemy.y;
                const overlapBottom = (enemy.y + enemy.height) - this._mario.y;

                // Stomp enemy if Mario is coming from above
                if (this._mario.velocityY > 0 && overlapTop < overlapBottom) {
                    if (enemy.hasHelmet) {
                        // Can't stomp helmet enemies! Mario bounces off
                        this._mario.velocityY = this._config.jumpForce * 0.7; // Big bounce back
                        this._addParticles(enemy.x, enemy.y, '#C0C0C0'); // Silver particles
                        this._playSound('jump'); // Bounce sound
                        console.log(`🛡️ Mario bounced off helmet enemy!`);
                    } else {
                        // Normal enemy - can be stomped
                        this._enemies.splice(index, 1);
                        this._mario.velocityY = this._config.jumpForce / 2; // Small bounce
                        // NO SCORE for killing enemies anymore!
                        this._addParticles(enemy.x, enemy.y, '#FFD700');
                        this._playSound('enemy_defeat');
                        console.log(`🦶 Mario stomped normal enemy! (No score)`);
                    }
                } else {
                    // Mario gets hurt by side/bottom collision
                    console.log(`💥 Mario hit by enemy - restarting level`);
                    this._restartLevel();
                }
            }
        });

        // Check piranha plant collisions (skip flattened plants)
        this._piranhaPlants.forEach((plant, index) => {
            if (!plant.flattened && this._isColliding(this._mario, plant)) {
                // Calculate overlap to determine if Mario is stomping plant
                const overlapTop = (this._mario.y + this._mario.height) - plant.y;
                const overlapBottom = (plant.y + plant.height) - this._mario.y;

                // Stomp plant if Mario is coming from above
                if (this._mario.velocityY > 0 && overlapTop < overlapBottom) {
                    // Flatten the plant instead of removing it
                    plant.flattened = true;
                    plant.height = 5; // Very flat
                    plant.y += 35; // Move to ground level (original height was 40, new is 5)
                    plant.shootCooldown = Infinity; // Stop shooting
                    this._mario.velocityY = this._config.jumpForce / 2; // Small bounce
                    this._addParticles(plant.x, plant.y, '#228B22'); // Green particles
                    this._playSound('enemy_defeat');
                    console.log(`🌸 Mario flattened piranha plant!`);
                } else {
                    // Mario gets hurt by side collision
                    console.log(`💥 Mario hit by piranha plant - restarting level`);
                    this._restartLevel();
                }
            }
        });

        // Check walking on flattened plants (for particles)
        this._piranhaPlants.forEach((plant, index) => {
            if (plant.flattened && this._isColliding(this._mario, plant)) {
                // Mario is standing on a flattened plant - add particles occasionally
                if (Math.random() < 0.1) { // 10% chance per frame for particles
                    this._addSmallParticles(plant.x + Math.random() * plant.width, plant.y, '#8B4513'); // Brown dust particles
                }
            }
        });
    }

    _isColliding(rect1, rect2) {
        return rect1.x < rect2.x + rect2.width &&
               rect1.x + rect1.width > rect2.x &&
               rect1.y < rect2.y + rect2.height &&
               rect1.y + rect1.height > rect2.y;
    }

    _hitQuestionBlock(block) {
        if (block.hit) return;

        block.hit = true;
        block.color = '#8B4513'; // Brown when hit
        block.symbol = '!';

        this._score += 100; // Increased points for question blocks
        this._addParticles(block.x, block.y, '#FFD700');
        this._playSound('question_block');

        // Show question dialog
        this._showQuestionDialog(block.sentence);
    }

    _showQuestionDialog(sentence) {
        this._isPaused = true;
        this._isQuestionActive = true;

        // Create dialog overlay
        const overlay = document.createElement('div');
        overlay.style.position = 'fixed';
        overlay.style.top = '0';
        overlay.style.left = '0';
        overlay.style.width = '100%';
        overlay.style.height = '100%';
        overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
        overlay.style.display = 'flex';
        overlay.style.justifyContent = 'center';
        overlay.style.alignItems = 'center';
        overlay.style.zIndex = '1000';

        const dialog = document.createElement('div');
        dialog.style.backgroundColor = 'white';
        dialog.style.padding = '30px';
        dialog.style.borderRadius = '15px';
        dialog.style.maxWidth = '500px';
        dialog.style.textAlign = 'center';
        dialog.style.boxShadow = '0 10px 30px rgba(0,0,0,0.3)';
        dialog.style.fontFamily = 'Arial, sans-serif';

        const title = document.createElement('h2');
        title.textContent = '🎧 Listen & Learn!';
        title.style.color = '#FF6B6B';
        title.style.marginBottom = '20px';

        const questionText = document.createElement('div');
        questionText.innerHTML = `
            <p style="font-size: 18px; margin-bottom: 10px;"><strong>English:</strong> ${sentence.english}</p>
            <p style="font-size: 18px; margin-bottom: 20px; color: #4ECDC4;"><strong>Translation:</strong> ${sentence.translation}</p>
            <p style="font-size: 14px; color: #666;">${sentence.context ? `Context: ${sentence.context}` : ''}</p>
        `;

        // Add progress indicator
        const progressBar = document.createElement('div');
        progressBar.style.width = '100%';
        progressBar.style.height = '4px';
        progressBar.style.backgroundColor = '#E0E0E0';
        progressBar.style.borderRadius = '2px';
        progressBar.style.marginTop = '20px';
        progressBar.style.overflow = 'hidden';

        const progressFill = document.createElement('div');
        progressFill.style.width = '0%';
        progressFill.style.height = '100%';
        progressFill.style.backgroundColor = '#4ECDC4';
        progressFill.style.transition = 'width linear';
        progressBar.appendChild(progressFill);

        dialog.appendChild(title);
        dialog.appendChild(questionText);
        dialog.appendChild(progressBar);
        overlay.appendChild(dialog);
        document.body.appendChild(overlay);

        // Start TTS and auto-close
        this._playTTSAndAutoClose(sentence.english, overlay, progressFill);
    }

    _playTTSAndAutoClose(text, overlay, progressBar) {
        // Calculate duration based on text length (words per minute estimation)
        const words = text.split(' ').length;
        const wordsPerMinute = 150; // Average speaking speed
        const baseDuration = Math.max(2000, (words / wordsPerMinute) * 60000); // Minimum 2 seconds
        const duration = Math.min(baseDuration, 8000); // Maximum 8 seconds

        console.log(`🔊 Playing TTS for: "${text}" (${words} words, ${duration}ms)`);

        // Use Web Speech API for TTS
        if ('speechSynthesis' in window) {
            const utterance = new SpeechSynthesisUtterance(text);
            utterance.rate = 0.8; // Slightly slower for clarity
            utterance.pitch = 1.0;
            utterance.volume = 0.8;

            // Try to use a nice English voice
            const voices = speechSynthesis.getVoices();
            const englishVoice = voices.find(voice =>
                voice.lang.startsWith('en') && (voice.name.includes('Female') || voice.name.includes('Google'))
            ) || voices.find(voice => voice.lang.startsWith('en'));

            if (englishVoice) {
                utterance.voice = englishVoice;
                console.log(`🎤 Using voice: ${englishVoice.name}`);
            }

            speechSynthesis.speak(utterance);
        }

        // Animate progress bar
        progressBar.style.transitionDuration = `${duration}ms`;
        progressBar.style.width = '100%';

        // Auto close after duration
        setTimeout(() => {
            if (overlay && overlay.parentNode) {
                document.body.removeChild(overlay);
                this._isPaused = false;
                this._isQuestionActive = false;
                this._questionsAnswered++;
                this._score += 300; // Increased bonus for listening
                console.log(`✅ Question dialog auto-closed. Questions answered: ${this._questionsAnswered}`);
            }
        }, duration);
    }

    _updatePiranhaPlants() {
        const currentTime = Date.now();

        this._piranhaPlants.forEach(plant => {
            // Check if it's time to shoot
            if (currentTime - plant.lastShot > plant.shootCooldown) {
                // Check if Mario is in range (within 400 pixels)
                const distanceToMario = Math.abs(plant.x - this._mario.x);

                if (distanceToMario < 400) {
                    // Shoot projectile towards Mario
                    const direction = this._mario.x > plant.x ? 1 : -1;

                    this._projectiles.push({
                        x: plant.x + plant.width / 2,
                        y: plant.y + plant.height / 2,
                        velocityX: direction * 3, // Projectile speed
                        velocityY: 0,
                        width: 8,
                        height: 8,
                        color: '#FF4500', // Orange fireball
                        type: 'fireball',
                        life: 200 // 200 frames lifetime
                    });

                    plant.lastShot = currentTime;
                    this._playSound('enemy_defeat'); // Shooting sound
                    console.log(`🔥 Piranha plant shot fireball towards Mario!`);
                }
            }
        });
    }

    _updateProjectiles() {
        // Update projectile positions
        this._projectiles.forEach((projectile, index) => {
            projectile.x += projectile.velocityX;
            projectile.y += projectile.velocityY;
            projectile.life--;

            // Remove projectiles that are off-screen or expired
            if (projectile.life <= 0 || projectile.x < -50 || projectile.x > this._levelWidth + 50) {
                this._projectiles.splice(index, 1);
                return;
            }

            // Check collision with Mario
            if (this._isColliding(this._mario, projectile)) {
                console.log(`🔥 Mario hit by projectile - restarting level`);
                this._restartLevel();
                return;
            }

            // Check collision with walls/platforms
            const hitObstacle = this._platforms.some(platform => this._isColliding(projectile, platform)) ||
                               this._walls.some(wall => this._isColliding(projectile, wall));

            if (hitObstacle) {
                this._projectiles.splice(index, 1);
                this._addParticles(projectile.x, projectile.y, '#FF4500');
                console.log(`💥 Projectile hit obstacle`);
            }
        });
    }

    _updateCatapults() {
        const currentTime = Date.now();

        this._catapults.forEach(catapult => {
            // Check if it's time to shoot
            if (currentTime - catapult.lastShot > catapult.shootCooldown) {
                // Target Mario's position with imperfect aim (randomness)
                const aimOffset = 100 + Math.random() * 150; // 100-250 pixel spread
                const aimDirection = Math.random() < 0.5 ? -1 : 1;
                const targetX = this._mario.x + (aimOffset * aimDirection);
                const targetY = this._config.canvasHeight - 50; // Ground level

                // ONAGER ONLY: Check minimum range - don't fire if Mario is too close
                if (catapult.isOnager) {
                    const distanceToMario = Math.abs(catapult.x - this._mario.x);
                    const minimumRange = 300; // Onager won't fire if Mario is within 300px

                    if (distanceToMario < minimumRange) {
                        console.log(`🏛️ Onager held fire - Mario too close! Distance: ${distanceToMario.toFixed(0)}px (min: ${minimumRange}px)`);
                        return; // Skip this shot, Mario is too close
                    }
                }

                // Check if there's a clear line of sight (no platform blocking)
                if (!this._hasLineOfSight(catapult, targetX, targetY)) {
                    console.log(`🚫 ${catapult.type} blocked by obstacle, skipping shot`);
                    return; // Skip this shot, try again next time
                }

                if (catapult.isOnager) {
                    // ONAGER: Fire 8 small stones in spread pattern
                    console.log(`🏛️ Onager firing stone rain!`);

                    for (let stone = 0; stone < 8; stone++) {
                        // Much more random targeting for fear factor
                        const randomSpreadX = (Math.random() - 0.5) * 400; // ±200px spread
                        const randomSpreadY = (Math.random() - 0.5) * 100; // ±50px spread
                        const stoneTargetX = targetX + randomSpreadX;
                        const stoneTargetY = targetY + randomSpreadY;

                        // Calculate trajectory for small stone
                        const deltaX = stoneTargetX - catapult.x;
                        const deltaY = stoneTargetY - catapult.y;
                        const time = 5 + Math.random() * 2; // 5-7 seconds flight time (varied)
                        const velocityX = deltaX / (time * 60);
                        const velocityY = (deltaY - 0.5 * 0.015 * time * time * 60 * 60) / (time * 60); // Slightly more gravity

                        this._stones.push({
                            x: catapult.x + 30 + (Math.random() - 0.5) * 20, // Spread launch point
                            y: catapult.y - 10 + (Math.random() - 0.5) * 10,
                            width: 8, // Much smaller than boulders
                            height: 8,
                            velocityX: velocityX,
                            velocityY: velocityY,
                            color: '#A0522D', // Brown stone color
                            type: 'stone',
                            sourceCatapultX: catapult.x,
                            sourceCatapultY: catapult.y
                        });
                    }

                    catapult.lastShot = currentTime;
                    this._playSound('enemy_defeat'); // Different sound for stone rain
                    console.log(`🏛️ Onager fired 8 stones in spread pattern!`);
                } else {
                    // CATAPULT: Fire single boulder (original behavior)
                    const deltaX = targetX - catapult.x;
                    const deltaY = targetY - catapult.y;
                    const time = 7.5; // 7.5 seconds flight time
                    const velocityX = deltaX / (time * 60);
                    const velocityY = (deltaY - 0.5 * 0.01 * time * time * 60 * 60) / (time * 60);

                    this._boulders.push({
                        x: catapult.x + 30,
                        y: catapult.y - 10,
                        width: 25,
                        height: 25,
                        velocityX: velocityX,
                        velocityY: velocityY,
                        color: '#696969', // Dark gray
                        type: 'boulder',
                        hasLanded: false,
                        sourceCatapultX: catapult.x,
                        sourceCatapultY: catapult.y,
                        health: 2,
                        maxHealth: 2
                    });

                    catapult.lastShot = currentTime;
                    this._playSound('jump'); // Boulder launch sound
                    console.log(`🏹 Catapult fired boulder towards x=${targetX.toFixed(0)}`);
                }
            }
        });
    }

    _updateBoulders() {
        this._boulders.forEach((boulder, index) => {
            if (boulder.hasLanded) return; // Don't update landed boulders

            // Apply gravity and movement (MUCH slower with very light gravity)
            boulder.velocityY += 0.01; // Ultra-light gravity so boulders can actually fly properly
            boulder.x += boulder.velocityX;
            boulder.y += boulder.velocityY;

            // Check ground collision
            const groundLevel = this._config.canvasHeight - 50;
            if (boulder.y + boulder.height >= groundLevel) {
                this._handleBoulderImpact(boulder, index, boulder.x, groundLevel - boulder.height);
                return;
            }

            // Check collision with platforms, walls, stairs
            let hasHit = false;

            // Check platforms
            this._platforms.forEach((platform, platformIndex) => {
                if (!hasHit && this._isColliding(boulder, platform)) {
                    this._handleBoulderImpact(boulder, index, boulder.x, platform.y - boulder.height, platform, platformIndex);
                    hasHit = true;
                }
            });

            // Check walls (boulder damages walls)
            if (!hasHit) {
                this._walls.forEach((wall, wallIndex) => {
                    if (!hasHit && this._isColliding(boulder, wall)) {
                        console.log(`🪨 Boulder hit wall! Wall damage system activated.`);

                        // Boulder is DESTROYED when hitting wall
                        this._addParticles(boulder.x + boulder.width/2, boulder.y + boulder.height/2, '#696969');
                        this._boulders.splice(index, 1);
                        this._playSound('enemy_defeat');
                        console.log(`💥 Boulder destroyed on wall impact`);

                        // Wall takes damage
                        wall.health--;
                        console.log(`🧱 Wall health: ${wall.health}/${wall.maxHealth}`);

                        if (wall.health <= 0) {
                            // Wall is destroyed
                            this._addParticles(wall.x + wall.width/2, wall.y + wall.height/2, '#8B4513');
                            this._walls.splice(wallIndex, 1);
                            console.log(`💥 Wall destroyed!`);
                        } else {
                            // Visual damage - change color to show damage
                            if (wall.health === 2) {
                                wall.color = '#A0522D'; // Slightly damaged - darker brown
                            } else if (wall.health === 1) {
                                wall.color = '#654321'; // Heavily damaged - dark brown
                            }
                            console.log(`🩹 Wall damaged but still standing`);
                        }

                        hasHit = true;
                    }
                });
            }

            // Check collision with catapults (but NOT the source catapult)
            if (!hasHit) {
                this._catapults.forEach((catapult, catapultIndex) => {
                    // Don't collide with the catapult that fired this boulder
                    const isSameCatapult = Math.abs(boulder.sourceCatapultX - catapult.x) < 10 &&
                                          Math.abs(boulder.sourceCatapultY - catapult.y) < 10;

                    if (!hasHit && !isSameCatapult && this._isColliding(boulder, catapult)) {
                        // Boulder hits a different catapult - land on top
                        this._handleBoulderImpact(boulder, index, boulder.x, catapult.y - boulder.height, catapult, catapultIndex, 'catapult');
                        hasHit = true;
                        console.log(`🪨 Boulder hit different catapult!`);
                    }
                });
            }

            // Check collision with Mario (boulder resets level like enemies!)
            if (!hasHit && this._isColliding(boulder, this._mario)) {
                console.log(`💀 Boulder hit Mario! Respawning at level start.`);
                this._addParticles(this._mario.x, this._mario.y, '#FF0000'); // Red death particles
                this._playSound('enemy_defeat');

                // Reset Mario to start position like other enemy deaths
                const level = this._levelData[this._currentLevelIndex];
                this._mario.x = level.startX;
                this._mario.y = level.startY;
                this._mario.velocityX = 0;
                this._mario.velocityY = 0;

                // Boulder lands after hitting Mario
                this._handleBoulderImpact(boulder, index, boulder.x, this._config.canvasHeight - 75);
                hasHit = true;
                return;
            }

            // Check collision with OTHER boulders (boulder-to-boulder damage system)
            if (!hasHit) {
                this._boulders.forEach((otherBoulder, otherIndex) => {
                    if (!hasHit && otherIndex !== index && otherBoulder.hasLanded && this._isColliding(boulder, otherBoulder)) {
                        console.log(`🪨 Flying boulder hit landed boulder! Damage system activated.`);

                        // Flying boulder is DESTROYED (removed completely)
                        this._addParticles(boulder.x + boulder.width/2, boulder.y + boulder.height/2, '#696969');
                        this._boulders.splice(index, 1);
                        this._playSound('enemy_defeat');
                        console.log(`💥 Flying boulder destroyed on impact`);

                        // Landed boulder takes damage
                        otherBoulder.health--;
                        console.log(`🩹 Landed boulder health: ${otherBoulder.health}/${otherBoulder.maxHealth}`);

                        if (otherBoulder.health <= 0) {
                            // Landed boulder is destroyed
                            this._addParticles(otherBoulder.x + otherBoulder.width/2, otherBoulder.y + otherBoulder.height/2, '#8B4513');
                            this._boulders.splice(otherIndex, 1);
                            console.log(`💥 Landed boulder destroyed!`);
                        } else {
                            // Visual damage - change color to show damage
                            otherBoulder.color = otherBoulder.health === 1 ? '#A0522D' : '#696969'; // Darker when damaged
                        }

                        hasHit = true;
                    }
                });
            }

            // Remove boulders that go off-screen
            if (boulder.x < -100 || boulder.x > this._levelWidth + 100 || boulder.y > this._config.canvasHeight + 100) {
                this._boulders.splice(index, 1);
            }
        });
    }

    _handleBoulderImpact(boulder, boulderIndex, impactX, impactY, hitObject = null, hitObjectIndex = -1, hitType = 'platform') {
        // Set boulder as landed at impact point
        boulder.x = impactX;
        boulder.y = impactY;
        boulder.velocityX = 0;
        boulder.velocityY = 0;
        boulder.hasLanded = true;
        boulder.color = '#8B4513'; // Brown when landed (becomes platform)

        // Explosion effect
        this._addParticles(boulder.x + boulder.width/2, boulder.y + boulder.height/2, '#FF4500');
        this._playSound('enemy_defeat');

        // Kill enemies in explosion radius (50 pixels)
        this._enemies.forEach((enemy, enemyIndex) => {
            const distance = Math.sqrt(
                Math.pow(enemy.x - (boulder.x + boulder.width/2), 2) +
                Math.pow(enemy.y - (boulder.y + boulder.height/2), 2)
            );
            if (distance < 50) {
                this._enemies.splice(enemyIndex, 1);
                this._addParticles(enemy.x, enemy.y, '#FFD700');
                console.log(`💥 Boulder explosion killed enemy at distance ${distance.toFixed(0)}`);
            }
        });

        // Reset Mario to level start if he's in explosion radius (50 pixels)
        const marioDistance = Math.sqrt(
            Math.pow(this._mario.x - (boulder.x + boulder.width/2), 2) +
            Math.pow(this._mario.y - (boulder.y + boulder.height/2), 2)
        );
        if (marioDistance < 50) {
            console.log(`💀 Mario killed by boulder explosion! Respawning at level start. Distance: ${marioDistance.toFixed(0)}`);
            this._addParticles(this._mario.x, this._mario.y, '#FF0000'); // Red death particles
            this._playSound('enemy_defeat');

            // Reset Mario to start position like other enemy deaths
            const level = this._levelData[this._currentLevelIndex];
            this._mario.x = level.startX;
            this._mario.y = level.startY;
            this._mario.velocityX = 0;
            this._mario.velocityY = 0;
        }

        // Boulder lands only on platforms, ground, stairs - NOT on walls or other boulders (they're destroyed on impact)
        if (hitObject && (hitType === 'platform' || hitType === 'stair')) {
            console.log(`🪨 Boulder landed on ${hitType}, creating additional platform`);
        }

        console.log(`🪨 Boulder landed at x=${impactX.toFixed(0)}, y=${impactY.toFixed(0)} - now a platform!`);
    }

    _updateStones() {
        this._stones.forEach((stone, index) => {
            // Apply gravity and movement (similar to boulders but simpler)
            stone.velocityY += 0.015; // Slightly more gravity than boulders
            stone.x += stone.velocityX;
            stone.y += stone.velocityY;

            // Check ground collision
            const groundLevel = this._config.canvasHeight - 50;
            if (stone.y + stone.height >= groundLevel) {
                // Stone hits ground - create small particle effect and disappear
                this._addParticles(stone.x + stone.width/2, stone.y + stone.height/2, '#A0522D');
                this._stones.splice(index, 1);
                return;
            }

            // Check collision with Mario (stones kill Mario!)
            if (this._isColliding(stone, this._mario)) {
                console.log(`🪨 Stone hit Mario! Respawning at level start.`);
                this._addParticles(this._mario.x, this._mario.y, '#FF0000'); // Red death particles
                this._playSound('enemy_defeat');

                // Reset Mario to start position like other deaths
                const level = this._levelData[this._currentLevelIndex];
                this._mario.x = level.startX;
                this._mario.y = level.startY;
                this._mario.velocityX = 0;
                this._mario.velocityY = 0;

                // Remove the stone that hit Mario
                this._stones.splice(index, 1);
                return;
            }

            // Check collision with platforms/walls (stones disappear on impact)
            let hasHit = false;

            // Check platforms
            this._platforms.forEach((platform) => {
                if (!hasHit && this._isColliding(stone, platform)) {
                    this._addParticles(stone.x + stone.width/2, stone.y + stone.height/2, '#A0522D');
                    this._stones.splice(index, 1);
                    hasHit = true;
                    return;
                }
            });

            // Check walls
            if (!hasHit) {
                this._walls.forEach((wall) => {
                    if (!hasHit && this._isColliding(stone, wall)) {
                        this._addParticles(stone.x + stone.width/2, stone.y + stone.height/2, '#A0522D');
                        this._stones.splice(index, 1);
                        hasHit = true;
                        return;
                    }
                });
            }

            // Remove stones that go off-screen
            if (stone.x < -100 || stone.x > this._levelWidth + 100 || stone.y > this._config.canvasHeight + 100) {
                this._stones.splice(index, 1);
            }
        });
    }

    _renderStones() {
        this._stones.forEach(stone => {
            // Draw small stone as a circle
            this._ctx.fillStyle = stone.color;
            this._ctx.beginPath();
            this._ctx.arc(stone.x + stone.width/2, stone.y + stone.height/2, stone.width/2, 0, 2 * Math.PI);
            this._ctx.fill();

            // Add small highlight for 3D effect
            this._ctx.fillStyle = '#D2B48C'; // Light brown highlight
            this._ctx.beginPath();
            this._ctx.arc(stone.x + stone.width/2 - 1, stone.y + stone.height/2 - 1, stone.width/4, 0, 2 * Math.PI);
            this._ctx.fill();
        });
    }

    _updateCamera() {
        // Follow Mario with smooth camera movement
        const targetX = this._mario.x - this._config.canvasWidth / 2;
        this._camera.x = Math.max(0, Math.min(targetX, this._levelWidth - this._config.canvasWidth));
    }

    _addParticles(x, y, color) {
        for (let i = 0; i < 8; i++) {
            this._particles.push({
                x: x,
                y: y,
                velocityX: (Math.random() - 0.5) * 10,
                velocityY: -Math.random() * 8 - 2,
                color: color,
                life: 60,
                maxLife: 60
            });
        }
    }

    _addSmallParticles(x, y, color) {
        // Only 2-3 small particles for walking dust
        for (let i = 0; i < 3; i++) {
            this._particles.push({
                x: x,
                y: y,
                velocityX: (Math.random() - 0.5) * 4, // Smaller velocity
                velocityY: -Math.random() * 3 - 1, // Less upward movement
                color: color,
                life: 30, // Shorter life
                maxLife: 30
            });
        }
    }

    _updateParticles() {
        this._particles = this._particles.filter(particle => {
            particle.x += particle.velocityX;
            particle.y += particle.velocityY;

            if (particle.isFinishStar) {
                // Slower gravity for stars and some sparkle effect
                particle.velocityY += 0.1; // Light gravity
                particle.velocityX *= 0.98; // Slight friction
            } else {
                particle.velocityY += 0.3; // Normal gravity
            }

            particle.life--;
            return particle.life > 0;
        });
    }

    _checkLevelCompletion() {
        const level = this._levelData[this._currentLevelIndex];

        // Debug: log Mario position vs end position
        if (this._mario.x > level.endX - 100) { // Close to end
            console.log(`🎯 Mario position: ${this._mario.x.toFixed(0)}, Level end: ${level.endX.toFixed(0)}`);
        }

        if (this._mario.x >= level.endX && !this._levelCompleted) {
            console.log(`🏁 Level ${this._currentLevel} completed!`);
            this._levelCompleted = true; // Prevent multiple triggers
            this._triggerFinishLineAnimation();
        }
    }

    _triggerFinishLineAnimation() {
        this._isCelebrating = true; // Block enemies but allow animations

        // Create star animation particles
        this._createFinishLineStars();
        this._playSound('finish_stars');

        // Complete level after animation
        setTimeout(() => {
            this._completeLevel();
        }, 2000);
    }

    _createFinishLineStars() {
        const centerX = this._mario.x;
        const centerY = this._mario.y;

        // Create explosion of stars
        for (let i = 0; i < 20; i++) {
            const angle = (Math.PI * 2 * i) / 20;
            const speed = 5 + Math.random() * 5;
            const distance = 50 + Math.random() * 100;

            this._particles.push({
                x: centerX,
                y: centerY,
                velocityX: Math.cos(angle) * speed,
                velocityY: Math.sin(angle) * speed,
                life: 2000,
                maxLife: 2000,
                color: i % 3 === 0 ? '#FFD700' : i % 3 === 1 ? '#FF69B4' : '#00BFFF',
                size: 8 + Math.random() * 4,
                isFinishStar: true
            });
        }

        console.log('🌟 Finish line star animation triggered!');
    }

    _createLevelCompleteStars() {
        const centerX = this._mario.x;
        const centerY = this._mario.y;

        // Create celebration stars around Mario
        for (let i = 0; i < 15; i++) {
            const angle = (Math.PI * 2 * i) / 15;
            const speed = 3 + Math.random() * 4;

            this._particles.push({
                x: centerX,
                y: centerY,
                velocityX: Math.cos(angle) * speed,
                velocityY: Math.sin(angle) * speed,
                life: 2500,
                maxLife: 2500,
                color: ['#FFD700', '#FF69B4', '#00BFFF', '#32CD32', '#FF4500'][Math.floor(Math.random() * 5)],
                size: 6 + Math.random() * 3,
                isLevelCompleteStar: true
            });
        }

        console.log('⭐ Level complete star animation created!');
    }

    _createEpicFinalStars() {
        const centerX = this._mario.x;
        const centerY = this._mario.y;

        // 🌟💥 ULTRA EPIC FINAL EXPLOSION - 8 MASSIVE WAVES! 💥🌟
        for (let wave = 0; wave < 8; wave++) {
            setTimeout(() => {
                // MASSIVE number of stars per wave (80, 100, 120, 140, 160, 180, 200, 220)
                const starsInWave = 80 + (wave * 20);

                for (let i = 0; i < starsInWave; i++) {
                    const angle = (Math.PI * 2 * i) / starsInWave;
                    const speed = 3 + Math.random() * 8 + (wave * 1.5);
                    const waveOffset = wave * 50; // Much bigger spread

                    this._particles.push({
                        x: centerX + (Math.random() - 0.5) * waveOffset,
                        y: centerY + (Math.random() - 0.5) * waveOffset,
                        velocityX: Math.cos(angle) * speed,
                        velocityY: Math.sin(angle) * speed - (Math.random() * 3), // More upward bias
                        life: 6000 + (wave * 800), // Longer lasting
                        maxLife: 6000 + (wave * 800),
                        color: ['#FFD700', '#FF69B4', '#00BFFF', '#32CD32', '#FF4500', '#9400D3', '#FF1493', '#00FF7F', '#FFFF00', '#FF6347', '#98FB98', '#DDA0DD'][Math.floor(Math.random() * 12)],
                        size: 10 + Math.random() * 8 + (wave * 0.5), // Bigger stars
                        isEpicFinalStar: true
                    });
                }

                // Play sound effects for each wave
                this._playSound('finish_stars');

                // Extra sound effect for bigger waves
                if (wave >= 4) {
                    setTimeout(() => this._playSound('powerup'), 100);
                }
            }, wave * 200); // Faster succession
        }

        // BONUS MEGA EXPLOSION at the end!
        setTimeout(() => {
            for (let i = 0; i < 300; i++) { // 300 bonus stars!
                const angle = Math.random() * Math.PI * 2;
                const speed = 2 + Math.random() * 12;

                this._particles.push({
                    x: centerX + (Math.random() - 0.5) * 200,
                    y: centerY + (Math.random() - 0.5) * 200,
                    velocityX: Math.cos(angle) * speed,
                    velocityY: Math.sin(angle) * speed - Math.random() * 4,
                    life: 8000,
                    maxLife: 8000,
                    color: ['#FFD700', '#FF1493', '#00FFFF', '#FF4500', '#9400D3'][Math.floor(Math.random() * 5)],
                    size: 15 + Math.random() * 10, // HUGE stars
                    isEpicFinalStar: true
                });
            }
            this._playSound('level_complete');
            console.log('🌟💥🎆 MEGA BONUS EXPLOSION! 300 GIANT STARS! 🎆💥🌟');
        }, 2000);

        console.log('🌟💥🎆 ULTRA EPIC FINAL STAR EXPLOSION ACTIVATED! OVER 1500+ STARS! 🎆💥🌟');
    }

    _completeLevel() {
        // NO SCORE for completing level anymore!
        this._isCelebrating = true; // Block enemies but allow animations

        // Play level complete sound
        this._playSound('level_complete');

        // Add star animations for every level completion
        this._createLevelCompleteStars();

        // Show level complete message
        this._showLevelCompleteMessage();

        if (this._currentLevelIndex < this._levelData.length - 1) {
            // Move to next level after delay
            setTimeout(() => {
                this._isCelebrating = false;
                this._startLevel(this._currentLevelIndex + 1);
            }, 3000); // Increased delay for star animation
        } else {
            // Game completed - EPIC FINAL STAR EXPLOSION
            this._createEpicFinalStars();
            setTimeout(() => {
                this._completeGame();
            }, 5000); // Longer delay for epic animation
        }
    }

    _showLevelCompleteMessage() {
        // Create level complete overlay
        const overlay = document.createElement('div');
        overlay.id = 'level-complete-overlay';
        overlay.style.position = 'fixed';
        overlay.style.top = '0';
        overlay.style.left = '0';
        overlay.style.width = '100%';
        overlay.style.height = '100%';
        overlay.style.backgroundColor = 'rgba(0, 150, 0, 0.8)';
        overlay.style.display = 'flex';
        overlay.style.flexDirection = 'column';
        overlay.style.justifyContent = 'center';
        overlay.style.alignItems = 'center';
        overlay.style.zIndex = '1000';
        overlay.style.color = 'white';
        overlay.style.textAlign = 'center';
        overlay.style.fontFamily = 'Arial, sans-serif';

        const isLastLevel = this._currentLevelIndex >= this._levelData.length - 1;

        overlay.innerHTML = `
            <h1 style="font-size: 3em; margin: 0; text-shadow: 2px 2px 4px rgba(0,0,0,0.5);">
                ${isLastLevel ? '🏆 VICTORY!' : '🎉 LEVEL COMPLETE!'}
            </h1>
            <h2 style="font-size: 2em; margin: 20px 0; text-shadow: 1px 1px 2px rgba(0,0,0,0.5);">
                ${isLastLevel ? 'You completed all levels!' : `Level ${this._currentLevel} Complete`}
            </h2>
            <p style="font-size: 1.5em; margin: 10px 0;">Score: ${this._score.toLocaleString()}</p>
            <p style="font-size: 1.2em; margin: 10px 0;">Questions Answered: ${this._questionsAnswered}</p>
            ${!isLastLevel ? '<p style="font-size: 1em; margin: 20px 0; opacity: 0.8;">Next level starting soon...</p>' : ''}
        `;

        document.body.appendChild(overlay);

        // Remove overlay after delay
        setTimeout(() => {
            const existingOverlay = document.getElementById('level-complete-overlay');
            if (existingOverlay) {
                existingOverlay.remove();
            }
        }, isLastLevel ? 5000 : 1800);
    }

    _completeGame() {
        this._isGameOver = true;

        // Show victory screen
        const overlay = document.createElement('div');
        overlay.style.position = 'fixed';
        overlay.style.top = '0';
        overlay.style.left = '0';
        overlay.style.width = '100%';
        overlay.style.height = '100%';
        overlay.style.backgroundColor = 'rgba(0, 100, 0, 0.9)';
        overlay.style.display = 'flex';
        overlay.style.justifyContent = 'center';
        overlay.style.alignItems = 'center';
        overlay.style.zIndex = '1000';
        overlay.style.color = 'white';
        overlay.style.textAlign = 'center';
        overlay.style.fontFamily = 'Arial, sans-serif';

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

        const content = document.createElement('div');
        content.innerHTML = `
            <h1 style="font-size: 48px; margin-bottom: 20px;">🏰 Congratulations! 🏰</h1>
            <h2 style="font-size: 32px; margin-bottom: 30px;">You completed Mario Educational Adventure!</h2>
            <div style="font-size: 20px; line-height: 2;">
                <p>🏆 Final Score: ${this._score}</p>
                <p>📚 Questions Answered: ${this._questionsAnswered}</p>
                <p>⏰ Time Played: ${playTime} seconds</p>
                <p>🎮 Levels Completed: ${this._config.maxLevels}</p>
            </div>
        `;

        const exitButton = document.createElement('button');
        exitButton.textContent = 'Return to Games';
        exitButton.style.cssText = `
            background: #FF6B6B;
            color: white;
            border: none;
            padding: 15px 30px;
            border-radius: 25px;
            font-size: 18px;
            font-weight: bold;
            cursor: pointer;
            margin-top: 30px;
        `;

        exitButton.addEventListener('click', () => {
            document.body.removeChild(overlay);
            // Try to go back to game selection or reload page
            if (window.history.length > 1) {
                window.history.back();
            } else {
                window.location.reload();
            }
        });

        content.appendChild(exitButton);
        overlay.appendChild(content);
        document.body.appendChild(overlay);
    }

    _restartLevel() {
        // Reset Mario to start position
        const level = this._levelData[this._currentLevelIndex];
        this._mario.x = level.startX;
        this._mario.y = level.startY;
        this._mario.velocityX = 0;
        this._mario.velocityY = 0;
        this._mario.onGround = false;

        // Reset camera
        this._camera.x = 0;
        this._camera.y = 0;

        // Subtract score penalty for death
        const penalty = 250;
        this._score = Math.max(0, this._score - penalty);
        this._playSound('death');
        console.log(`💀 Mario died! Score penalty: -${penalty}. New score: ${this._score}`);
    }

    _render() {
        // Clear canvas
        this._ctx.clearRect(0, 0, this._config.canvasWidth, this._config.canvasHeight);

        // Render background
        this._renderBackground();

        // Save context for camera translation
        this._ctx.save();
        this._ctx.translate(-this._camera.x, -this._camera.y);

        // Render platforms
        this._renderPlatforms();

        // Render question blocks
        this._renderQuestionBlocks();

        // Render enemies
        this._renderEnemies();

        // Render walls
        this._renderWalls();

        // Render advanced level elements
        this._renderPiranhaPlants();
        this._renderProjectiles();

        // Render level 4+ elements
        this._renderCatapults();
        this._renderBoulders();
        this._renderStones();

        // Render level 5+ elements
        this._renderFlyingEyes();

        // Render level 6 boss elements
        this._renderBoss();

        // Render castle (visual only)
        this._renderCastle();

        // Render finish line
        this._renderFinishLine();

        // Render Mario
        this._renderMario();

        // Render particles
        this._renderParticles();

        // Render debug hitboxes if needed
        this._renderDebugHitboxes();

        // Restore context
        this._ctx.restore();

        // Render UI
        this._renderUI();
    }

    _renderBackground() {
        // Sky gradient
        const gradient = this._ctx.createLinearGradient(0, 0, 0, this._config.canvasHeight);
        gradient.addColorStop(0, '#87CEEB');
        gradient.addColorStop(1, '#98FB98');
        this._ctx.fillStyle = gradient;
        this._ctx.fillRect(0, 0, this._config.canvasWidth, this._config.canvasHeight);

        // Clouds (fixed position, don't scroll with camera)
        this._ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';
        for (let i = 0; i < 5; i++) {
            const x = (i * 300 + 100 - this._camera.x * 0.3) % (this._config.canvasWidth + 200);
            const y = 80 + i * 30;
            this._renderCloud(x, y);
        }
    }

    _renderCloud(x, y) {
        this._ctx.beginPath();
        this._ctx.arc(x, y, 30, 0, Math.PI * 2);
        this._ctx.arc(x + 30, y, 40, 0, Math.PI * 2);
        this._ctx.arc(x + 60, y, 30, 0, Math.PI * 2);
        this._ctx.fill();
    }

    _renderPlatforms() {
        this._platforms.forEach(platform => {
            this._ctx.fillStyle = platform.color;
            this._ctx.fillRect(platform.x, platform.y, platform.width, platform.height);

            // Add outline
            this._ctx.strokeStyle = '#000';
            this._ctx.lineWidth = 2;
            this._ctx.strokeRect(platform.x, platform.y, platform.width, platform.height);
        });
    }

    _renderQuestionBlocks() {
        this._questionBlocks.forEach(block => {
            // Block
            this._ctx.fillStyle = block.color;
            this._ctx.fillRect(block.x, block.y, block.width, block.height);

            // Outline
            this._ctx.strokeStyle = '#000';
            this._ctx.lineWidth = 2;
            this._ctx.strokeRect(block.x, block.y, block.width, block.height);

            // Symbol
            this._ctx.fillStyle = '#000';
            this._ctx.font = 'bold 24px Arial';
            this._ctx.textAlign = 'center';
            this._ctx.textBaseline = 'middle';
            this._ctx.fillText(
                block.symbol,
                block.x + block.width / 2,
                block.y + block.height / 2
            );
        });
    }

    _renderEnemies() {
        this._enemies.forEach(enemy => {
            this._ctx.fillStyle = enemy.color;
            this._ctx.fillRect(enemy.x, enemy.y, enemy.width, enemy.height);

            // Simple face
            this._ctx.fillStyle = '#FFF';
            this._ctx.fillRect(enemy.x + 3, enemy.y + 3, 3, 3); // Eye
            this._ctx.fillRect(enemy.x + 14, enemy.y + 3, 3, 3); // Eye

            // Draw helmet for protected enemies
            if (enemy.hasHelmet) {
                this._ctx.fillStyle = '#C0C0C0'; // Silver helmet
                this._ctx.fillRect(enemy.x - 1, enemy.y - 4, enemy.width + 2, 6);

                // Helmet shine
                this._ctx.fillStyle = '#E8E8E8';
                this._ctx.fillRect(enemy.x + 2, enemy.y - 3, 4, 2);

                // Helmet symbol (shield)
                this._ctx.fillStyle = '#FFD700';
                this._ctx.fillRect(enemy.x + 8, enemy.y - 2, 4, 2);
            }
        });
    }

    _renderWalls() {
        this._walls.forEach(wall => {
            // Wall main body
            this._ctx.fillStyle = wall.color;
            this._ctx.fillRect(wall.x, wall.y, wall.width, wall.height);

            // Add brick pattern for visual appeal
            this._ctx.strokeStyle = '#654321'; // Darker brown for lines
            this._ctx.lineWidth = 1;

            // Horizontal lines
            for (let y = wall.y + 20; y < wall.y + wall.height; y += 20) {
                this._ctx.beginPath();
                this._ctx.moveTo(wall.x, y);
                this._ctx.lineTo(wall.x + wall.width, y);
                this._ctx.stroke();
            }

            // Vertical lines (offset every other row)
            for (let row = 0; row < Math.floor(wall.height / 20); row++) {
                const yPos = wall.y + row * 20;
                const offset = (row % 2) * 10; // Offset every other row

                for (let x = wall.x + offset + 20; x < wall.x + wall.width; x += 20) {
                    this._ctx.beginPath();
                    this._ctx.moveTo(x, yPos);
                    this._ctx.lineTo(x, Math.min(yPos + 20, wall.y + wall.height));
                    this._ctx.stroke();
                }
            }

            // Wall type indicator (for debugging)
            if (wall.type === 'tall') {
                this._ctx.fillStyle = '#FF0000';
                this._ctx.fillRect(wall.x + wall.width - 5, wall.y, 5, 20);
            }
        });
    }


    _renderPiranhaPlants() {
        this._piranhaPlants.forEach(plant => {
            if (plant.flattened) {
                // Flattened plant - just a green pancake on the ground
                this._ctx.fillStyle = '#556B2F'; // Dark olive green (dead/flat)
                this._ctx.fillRect(plant.x, plant.y + plant.height - 5, plant.width, 5);

                // Some scattered debris
                this._ctx.fillStyle = '#8B4513'; // Brown debris
                this._ctx.fillRect(plant.x + 5, plant.y + plant.height - 3, 3, 2);
                this._ctx.fillRect(plant.x + 20, plant.y + plant.height - 4, 2, 3);
                this._ctx.fillRect(plant.x + 12, plant.y + plant.height - 2, 4, 1);
            } else {
                // Normal living plant
                // Plant stem
                this._ctx.fillStyle = '#228B22'; // Forest green
                this._ctx.fillRect(plant.x + 10, plant.y, 10, plant.height);

                // Plant head (circular)
                this._ctx.fillStyle = '#32CD32'; // Lime green
                this._ctx.beginPath();
                this._ctx.arc(plant.x + 15, plant.y + 10, 12, 0, Math.PI * 2);
                this._ctx.fill();

                // Sharp teeth
                this._ctx.fillStyle = '#FFFFFF';
                for (let i = 0; i < 6; i++) {
                    const angle = (i * Math.PI * 2) / 6;
                    const toothX = plant.x + 15 + Math.cos(angle) * 8;
                    const toothY = plant.y + 10 + Math.sin(angle) * 8;
                    this._ctx.fillRect(toothX - 1, toothY - 1, 2, 4);
                }

                // Red mouth center
                this._ctx.fillStyle = '#DC143C'; // Crimson
                this._ctx.beginPath();
                this._ctx.arc(plant.x + 15, plant.y + 10, 6, 0, Math.PI * 2);
                this._ctx.fill();

                // Eyes
                this._ctx.fillStyle = '#000000';
                this._ctx.fillRect(plant.x + 10, plant.y + 5, 3, 3);
                this._ctx.fillRect(plant.x + 17, plant.y + 5, 3, 3);
            }
        });
    }

    _renderProjectiles() {
        this._projectiles.forEach(projectile => {
            // Fireball effect
            this._ctx.fillStyle = projectile.color;
            this._ctx.beginPath();
            this._ctx.arc(projectile.x + projectile.width/2, projectile.y + projectile.height/2, projectile.width/2, 0, Math.PI * 2);
            this._ctx.fill();

            // Inner glow
            this._ctx.fillStyle = '#FFFF00'; // Yellow center
            this._ctx.beginPath();
            this._ctx.arc(projectile.x + projectile.width/2, projectile.y + projectile.height/2, projectile.width/4, 0, Math.PI * 2);
            this._ctx.fill();
        });
    }

    _renderCatapults() {
        this._catapults.forEach(catapult => {
            // Catapult base
            this._ctx.fillStyle = catapult.color;
            this._ctx.fillRect(catapult.x, catapult.y + 40, catapult.width, 40);

            // Catapult arm
            this._ctx.fillStyle = '#654321'; // Dark brown
            this._ctx.fillRect(catapult.x + 10, catapult.y, 8, 50);

            // Bucket
            this._ctx.fillStyle = '#8B4513';
            this._ctx.fillRect(catapult.x + 5, catapult.y, 18, 12);

            // Support beams
            this._ctx.strokeStyle = '#654321';
            this._ctx.lineWidth = 3;
            this._ctx.beginPath();
            this._ctx.moveTo(catapult.x + 30, catapult.y + 40);
            this._ctx.lineTo(catapult.x + 14, catapult.y + 25);
            this._ctx.stroke();
        });
    }

    _renderBoulders() {
        this._boulders.forEach(boulder => {
            // Boulder body
            this._ctx.fillStyle = boulder.color;
            this._ctx.beginPath();
            this._ctx.arc(boulder.x + boulder.width/2, boulder.y + boulder.height/2, boulder.width/2, 0, Math.PI * 2);
            this._ctx.fill();

            // Boulder texture/cracks
            this._ctx.strokeStyle = '#555555';
            this._ctx.lineWidth = 1;
            this._ctx.beginPath();
            this._ctx.arc(boulder.x + boulder.width/2 - 5, boulder.y + boulder.height/2 - 3, 3, 0, Math.PI);
            this._ctx.stroke();
            this._ctx.beginPath();
            this._ctx.arc(boulder.x + boulder.width/2 + 4, boulder.y + boulder.height/2 + 2, 2, 0, Math.PI);
            this._ctx.stroke();

            // Show trajectory line for flying boulders (debug)
            if (!boulder.hasLanded && boulder.velocityX !== 0) {
                this._ctx.strokeStyle = 'rgba(255, 255, 255, 0.3)';
                this._ctx.lineWidth = 1;
                this._ctx.setLineDash([5, 5]);
                this._ctx.beginPath();
                this._ctx.moveTo(boulder.x + boulder.width/2, boulder.y + boulder.height/2);
                this._ctx.lineTo(boulder.x + boulder.velocityX * 10, boulder.y + boulder.velocityY * 10);
                this._ctx.stroke();
                this._ctx.setLineDash([]);
            }
        });
    }

    _renderFinishLine() {
        const level = this._levelData[this._currentLevelIndex];
        const finishX = level.endX;

        // Draw checkered flag pattern
        this._ctx.fillStyle = '#FFD700'; // Gold color
        this._ctx.fillRect(finishX - 5, 50, 10, this._config.canvasHeight - 100);

        // Add black and white checkered pattern
        const squareSize = 20;
        for (let y = 50; y < this._config.canvasHeight - 50; y += squareSize) {
            for (let x = 0; x < 10; x += squareSize / 2) {
                const isBlack = Math.floor((y - 50) / squareSize) % 2 === Math.floor(x / (squareSize / 2)) % 2;
                this._ctx.fillStyle = isBlack ? '#000000' : '#FFFFFF';
                this._ctx.fillRect(finishX - 5 + x, y, squareSize / 2, squareSize);
            }
        }

        // Add "FINISH" text
        this._ctx.save();
        this._ctx.translate(finishX, 30);
        this._ctx.rotate(-Math.PI / 2);
        this._ctx.fillStyle = '#FF0000';
        this._ctx.font = 'bold 16px Arial';
        this._ctx.textAlign = 'center';
        this._ctx.fillText('FINISH', 0, 0);
        this._ctx.restore();

        // Add arrow pointing to finish
        if (this._mario.x < finishX - 200) {
            this._ctx.fillStyle = '#FFD700';
            this._ctx.font = 'bold 20px Arial';
            this._ctx.textAlign = 'left';
            this._ctx.fillText('→ FINISH', finishX - 150, 25);
        }
    }

    _updateFlyingEyes() {
        const currentTime = Date.now();

        this._flyingEyes.forEach((eye, index) => {
            // Calculate distance to Mario
            const distanceToMario = Math.sqrt(
                Math.pow(eye.x - this._mario.x, 2) +
                Math.pow(eye.y - this._mario.y, 2)
            );

            // Determine if eye should chase Mario
            eye.isChasing = distanceToMario < eye.chaseDistance;

            // Handle dash behavior
            if (eye.isDashing) {
                eye.dashDuration--;
                if (eye.dashDuration <= 0) {
                    eye.isDashing = false;
                    eye.lastDashTime = currentTime;
                    console.log(`👁️ Eye finished dashing!`);
                }
                // During dash, maintain dash velocity (no other movement changes)
            } else {
                // Check if it's time to dash (only when chasing)
                if (eye.isChasing && currentTime - eye.lastDashTime > eye.dashInterval && Math.random() < 0.3) {
                    // Start dash in random 90-degree direction
                    const dashDirections = [
                        { x: 1, y: 0 },   // Right
                        { x: -1, y: 0 },  // Left
                        { x: 0, y: 1 },   // Down
                        { x: 0, y: -1 }   // Up
                    ];
                    const dashDir = dashDirections[Math.floor(Math.random() * 4)];

                    eye.velocityX = dashDir.x * eye.dashSpeed;
                    eye.velocityY = dashDir.y * eye.dashSpeed;
                    eye.isDashing = true;
                    eye.dashDuration = 20; // Dash for 20 frames (~0.33 seconds)
                    console.log(`👁️ Eye started dashing! Direction: ${dashDir.x}, ${dashDir.y}`);
                } else if (eye.isChasing) {
                    // Normal chase behavior - move toward Mario
                    const deltaX = this._mario.x - eye.x;
                    const deltaY = this._mario.y - eye.y;
                    const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);

                    if (distance > 0) {
                        // Normalize direction and apply chase speed
                        eye.velocityX = (deltaX / distance) * eye.chaseSpeed;
                        eye.velocityY = (deltaY / distance) * eye.chaseSpeed;
                    }

                    console.log(`👁️ Eye chasing Mario! Distance: ${distanceToMario.toFixed(0)}`);
                } else {
                    // Idle behavior - random floating movement (faster now)
                    if (currentTime - eye.lastDirectionChange > eye.directionChangeInterval) {
                        // Change direction randomly
                        eye.velocityX = (Math.random() - 0.5) * eye.idleSpeed * 2;
                        eye.velocityY = (Math.random() - 0.5) * eye.idleSpeed * 2;
                        eye.lastDirectionChange = currentTime;
                        eye.directionChangeInterval = 2000 + Math.random() * 3000;
                    }
                }
            }

            // Apply movement
            eye.x += eye.velocityX;
            eye.y += eye.velocityY;

            // Keep eyes within screen bounds
            if (eye.x < 0) {
                eye.x = 0;
                eye.velocityX = Math.abs(eye.velocityX);
            } else if (eye.x > this._levelWidth - eye.width) {
                eye.x = this._levelWidth - eye.width;
                eye.velocityX = -Math.abs(eye.velocityX);
            }

            if (eye.y < 0) {
                eye.y = 0;
                eye.velocityY = Math.abs(eye.velocityY);
            } else if (eye.y > this._config.canvasHeight - eye.height - 50) { // Stay above ground
                eye.y = this._config.canvasHeight - eye.height - 50;
                eye.velocityY = -Math.abs(eye.velocityY);
            }

            // Blinking animation
            eye.blinkTimer++;
            if (eye.blinkTimer > 120 + Math.random() * 180) { // Blink every 2-5 seconds
                eye.isBlinking = true;
                eye.blinkTimer = 0;
            }
            if (eye.isBlinking && eye.blinkTimer > 10) { // Blink lasts 10 frames
                eye.isBlinking = false;
            }

            // Check collision with Mario
            if (this._isColliding(this._mario, eye)) {
                // Eye can be stomped like normal enemies
                const overlapTop = (this._mario.y + this._mario.height) - eye.y;
                const overlapBottom = (eye.y + eye.height) - this._mario.y;

                if (this._mario.velocityY > 0 && overlapTop < overlapBottom) {
                    // Mario stomped the eye
                    this._flyingEyes.splice(index, 1);
                    this._mario.velocityY = this._config.jumpForce / 2; // Small bounce
                    this._addParticles(eye.x, eye.y, '#DC143C'); // Red particles
                    this._playSound('enemy_defeat');
                    console.log(`👁️ Mario stomped flying eye!`);
                } else {
                    // Eye hurts Mario - reset level
                    console.log(`💥 Mario hit by flying eye - restarting level`);
                    this._restartLevel();
                }
            }
        });
    }

    _renderFlyingEyes() {
        this._flyingEyes.forEach(eye => {
            // Draw eye body (white oval)
            this._ctx.fillStyle = '#FFFFFF';
            this._ctx.beginPath();
            this._ctx.ellipse(eye.x + eye.width/2, eye.y + eye.height/2, eye.width/2, eye.height/2, 0, 0, 2 * Math.PI);
            this._ctx.fill();

            if (!eye.isBlinking) {
                // Draw red iris
                this._ctx.fillStyle = eye.color;
                this._ctx.beginPath();
                this._ctx.ellipse(eye.x + eye.width/2, eye.y + eye.height/2, eye.width/3, eye.height/3, 0, 0, 2 * Math.PI);
                this._ctx.fill();

                // Draw black pupil that follows Mario
                const deltaX = this._mario.x - eye.x;
                const deltaY = this._mario.y - eye.y;
                const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);

                let pupilOffsetX = 0;
                let pupilOffsetY = 0;

                if (distance > 0) {
                    const maxOffset = 4; // Maximum pupil movement
                    pupilOffsetX = (deltaX / distance) * maxOffset;
                    pupilOffsetY = (deltaY / distance) * maxOffset;
                }

                this._ctx.fillStyle = eye.pupilColor;
                this._ctx.beginPath();
                this._ctx.arc(
                    eye.x + eye.width/2 + pupilOffsetX,
                    eye.y + eye.height/2 + pupilOffsetY,
                    eye.width/6,
                    0,
                    2 * Math.PI
                );
                this._ctx.fill();
            } else {
                // Draw closed eye (horizontal line)
                this._ctx.strokeStyle = '#000000';
                this._ctx.lineWidth = 2;
                this._ctx.beginPath();
                this._ctx.moveTo(eye.x + 5, eye.y + eye.height/2);
                this._ctx.lineTo(eye.x + eye.width - 5, eye.y + eye.height/2);
                this._ctx.stroke();
            }

            // Add subtle outline
            this._ctx.strokeStyle = '#CCCCCC';
            this._ctx.lineWidth = 1;
            this._ctx.beginPath();
            this._ctx.ellipse(eye.x + eye.width/2, eye.y + eye.height/2, eye.width/2, eye.height/2, 0, 0, 2 * Math.PI);
            this._ctx.stroke();
        });
    }

    _updateBoss() {
        if (!this._boss) return;

        const currentTime = Date.now();

        // Update boss collision cooldown
        if (this._bossCollisionCooldown > 0) {
            this._bossCollisionCooldown--;
        }

        // Update damage flash timer
        if (this._boss.damageFlashTimer > 0) {
            this._boss.damageFlashTimer--;
            if (this._boss.damageFlashTimer <= 0) {
                this._boss.isDamaged = false;
            }
        }

        // Boss collision with Mario (blocks the path) - with cooldown to prevent loop
        if (this._isColliding(this._mario, this._boss) && this._bossCollisionCooldown <= 0) {
            console.log(`👹 Mario hit boss body - bounced back!`);

            // TRUE velocity inversion: velocity = velocity * -1
            this._mario.velocityX = this._mario.velocityX * -1 - 3; // Invert + add knockback
            this._mario.velocityY = this._config.jumpForce * 0.7; // Bounce upward

            // Set collision cooldown (3 ticks)
            this._bossCollisionCooldown = 3;

            // Impact particles
            this._addParticles(
                this._mario.x + this._mario.width / 2,
                this._mario.y + this._mario.height / 2,
                '#FFFF00' // Yellow impact particles
            );

            // Impact sound
            this._playSound('enemy_defeat');

            console.log(`⏱️ Boss collision cooldown set: ${this._bossCollisionCooldown} ticks`);
        }
    }

    _renderBoss() {
        if (!this._boss) return;

        const ctx = this._ctx;
        const x = this._boss.x;
        const y = this._boss.y;
        const w = this._boss.width;
        const h = this._boss.height;

        // Boss main body (torso) - more humanoid proportions
        ctx.fillStyle = this._boss.isDamaged ? '#FF6666' : this._boss.color;
        ctx.fillRect(x + 20, y, w - 40, h * 0.6); // Torso

        // Boss legs (separated)
        ctx.fillRect(x + 10, y + h * 0.6, 35, h * 0.4); // Left leg
        ctx.fillRect(x + w - 45, y + h * 0.6, 35, h * 0.4); // Right leg

        // Boss head (bigger and more menacing)
        const headWidth = 60;
        const headHeight = 50;
        ctx.fillRect(x + (w - headWidth) / 2, y - headHeight, headWidth, headHeight);

        // Boss outline for all parts
        ctx.strokeStyle = '#000000';
        ctx.lineWidth = 3;
        ctx.strokeRect(x + 20, y, w - 40, h * 0.6); // Torso outline
        ctx.strokeRect(x + 10, y + h * 0.6, 35, h * 0.4); // Left leg outline
        ctx.strokeRect(x + w - 45, y + h * 0.6, 35, h * 0.4); // Right leg outline
        ctx.strokeRect(x + (w - headWidth) / 2, y - headHeight, headWidth, headHeight); // Head outline

        // Boss eyes (glowing red, larger)
        ctx.fillStyle = this._boss.eyeColor;
        const eyeSize = 12;
        ctx.fillRect(x + (w - headWidth) / 2 + 10, y - headHeight + 15, eyeSize, eyeSize); // Left eye
        ctx.fillRect(x + (w - headWidth) / 2 + headWidth - 22, y - headHeight + 15, eyeSize, eyeSize); // Right eye

        // Boss mouth (menacing)
        ctx.fillStyle = '#000000';
        ctx.fillRect(x + (w - headWidth) / 2 + 15, y - headHeight + 35, headWidth - 30, 8);

        // Shoulder spikes for more intimidating look
        ctx.fillStyle = '#8B4513';
        ctx.fillRect(x + 15, y + 5, 15, 25); // Left shoulder
        ctx.fillRect(x + w - 30, y + 5, 15, 25); // Right shoulder

        // Boss knees (damage zones) - integrated styling as kneepads
        ctx.fillStyle = '#FFD700'; // Gold kneepads
        ctx.fillRect(
            this._boss.leftKnee.x + 5,
            this._boss.leftKnee.y + 5,
            this._boss.leftKnee.width - 10,
            this._boss.leftKnee.height - 10
        );
        ctx.fillRect(
            this._boss.rightKnee.x + 5,
            this._boss.rightKnee.y + 5,
            this._boss.rightKnee.width - 10,
            this._boss.rightKnee.height - 10
        );

        // Kneepad outlines
        ctx.strokeStyle = '#B8860B'; // Dark goldenrod outline
        ctx.lineWidth = 2;
        ctx.strokeRect(
            this._boss.leftKnee.x + 5,
            this._boss.leftKnee.y + 5,
            this._boss.leftKnee.width - 10,
            this._boss.leftKnee.height - 10
        );
        ctx.strokeRect(
            this._boss.rightKnee.x + 5,
            this._boss.rightKnee.y + 5,
            this._boss.rightKnee.width - 10,
            this._boss.rightKnee.height - 10
        );

        // Boss health bar
        const healthBarWidth = 200;
        const healthBarHeight = 20;
        const healthBarX = this._boss.x + (this._boss.width / 2) - (healthBarWidth / 2);
        const healthBarY = this._boss.y - 40;

        // Health bar background
        ctx.fillStyle = '#FF0000';
        ctx.fillRect(healthBarX, healthBarY, healthBarWidth, healthBarHeight);

        // Health bar foreground
        const healthPercent = this._boss.health / this._boss.maxHealth;
        ctx.fillStyle = '#00FF00';
        ctx.fillRect(healthBarX, healthBarY, healthBarWidth * healthPercent, healthBarHeight);

        // Health bar border
        ctx.strokeStyle = '#000000';
        ctx.lineWidth = 2;
        ctx.strokeRect(healthBarX, healthBarY, healthBarWidth, healthBarHeight);

        // Render turrets on boss
        this._bossTurrets.forEach(turret => {
            ctx.fillStyle = turret.color;
            ctx.fillRect(turret.x, turret.y, turret.width, turret.height);
            ctx.strokeStyle = '#000000';
            ctx.lineWidth = 1;
            ctx.strokeRect(turret.x, turret.y, turret.width, turret.height);
        });
    }

    _renderMario() {
        // Mario body
        this._ctx.fillStyle = this._mario.color;
        this._ctx.fillRect(this._mario.x, this._mario.y, this._mario.width, this._mario.height);

        // Hat
        this._ctx.fillStyle = '#8B0000';
        this._ctx.fillRect(this._mario.x + 4, this._mario.y - 8, this._mario.width - 8, 12);

        // Face
        this._ctx.fillStyle = '#FFDBAC';
        this._ctx.fillRect(this._mario.x + 8, this._mario.y + 8, 16, 16);

        // Eyes
        this._ctx.fillStyle = '#000';
        const eyeOffset = this._mario.facing === 'right' ? 2 : -2;
        this._ctx.fillRect(this._mario.x + 10 + eyeOffset, this._mario.y + 12, 2, 2);
        this._ctx.fillRect(this._mario.x + 18 + eyeOffset, this._mario.y + 12, 2, 2);

        // Mustache
        this._ctx.fillRect(this._mario.x + 12, this._mario.y + 18, 8, 2);
    }

    _renderParticles() {
        this._particles.forEach(particle => {
            const alpha = particle.life / particle.maxLife;

            if (particle.isFinishStar) {
                // Render finish line stars as actual star symbols
                this._ctx.font = `${particle.size}px serif`;
                this._ctx.textAlign = 'center';
                this._ctx.textBaseline = 'middle';
                this._ctx.fillStyle = particle.color + Math.floor(alpha * 255).toString(16).padStart(2, '0');
                this._ctx.fillText('⭐', particle.x, particle.y);
            } else {
                // Regular particles
                this._ctx.fillStyle = particle.color + Math.floor(alpha * 255).toString(16).padStart(2, '0');
                this._ctx.fillRect(particle.x, particle.y, 4, 4);
            }
        });

        // Reset text alignment
        this._ctx.textAlign = 'left';
        this._ctx.textBaseline = 'top';
    }

    _renderCastle() {
        if (!this._castleStructure) return;

        const castle = this._castleStructure;

        // Set font for castle emoji
        this._ctx.font = `${castle.size}px serif`;
        this._ctx.textAlign = 'center';
        this._ctx.textBaseline = 'middle';

        // Render castle emoji
        this._ctx.fillText(castle.emoji, castle.x, castle.y);

        // Render princess in the castle
        if (castle.princess) {
            this._ctx.font = `${castle.princess.size}px serif`;
            this._ctx.fillText(castle.princess.emoji, castle.princess.x, castle.princess.y);
        }

        // Add sparkles around the massive castle (360px)
        this._ctx.font = '40px serif';
        this._ctx.fillText('✨', castle.x - 180, castle.y - 120);
        this._ctx.fillText('✨', castle.x + 180, castle.y - 120);
        this._ctx.fillText('✨', castle.x - 120, castle.y + 120);
        this._ctx.fillText('✨', castle.x + 120, castle.y + 120);

        // Additional sparkles for the massive castle
        this._ctx.font = '30px serif';
        this._ctx.fillText('✨', castle.x - 220, castle.y);
        this._ctx.fillText('✨', castle.x + 220, castle.y);
        this._ctx.fillText('✨', castle.x, castle.y - 200);
        this._ctx.fillText('✨', castle.x, castle.y + 180);

        // Extra sparkles for grandeur
        this._ctx.font = '25px serif';
        this._ctx.fillText('⭐', castle.x - 160, castle.y - 60);
        this._ctx.fillText('⭐', castle.x + 160, castle.y - 60);
        this._ctx.fillText('⭐', castle.x - 60, castle.y + 160);
        this._ctx.fillText('⭐', castle.x + 60, castle.y + 160);

        // Reset text alignment
        this._ctx.textAlign = 'left';
        this._ctx.textBaseline = 'top';
    }

    _renderUI() {
        if (this._uiOverlay) {
            this._uiOverlay.innerHTML = `
                <div>Score: ${this._score}</div>
                <div>Level: ${this._currentLevel}/${this._config.maxLevels}</div>
                <div>Questions: ${this._questionsAnswered}</div>
                <div style="margin-top: 10px; font-size: 14px;">
                    Use Arrow Keys or WASD to move, Space/Up to jump
                </div>
            `;
        }
    }

    _getRandomSentence() {
        const availableSentences = this._sentences.filter(s => !this._usedSentences.includes(s));
        if (availableSentences.length === 0) {
            // Reset used sentences if all are used
            this._usedSentences = [];
            return this._sentences[0];
        }

        const sentence = availableSentences[Math.floor(Math.random() * availableSentences.length)];
        this._usedSentences.push(sentence);
        return sentence;
    }

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

    _renderDebugHitboxes() {
        // Only render in debug mode (can be toggled)
        if (!window.DEBUG_HITBOXES) return;

        this._ctx.strokeStyle = '#FF0000';
        this._ctx.lineWidth = 2;

        // Mario hitbox
        this._ctx.strokeRect(this._mario.x, this._mario.y, this._mario.width, this._mario.height);

        // Platform hitboxes
        this._ctx.strokeStyle = '#00FF00';
        this._platforms.forEach(platform => {
            this._ctx.strokeRect(platform.x, platform.y, platform.width, platform.height);
        });

        // Wall hitboxes
        this._ctx.strokeStyle = '#8B4513';
        this._walls.forEach(wall => {
            this._ctx.strokeRect(wall.x, wall.y, wall.width, wall.height);
        });

        // Enemy hitboxes
        this._ctx.strokeStyle = '#FF00FF';
        this._enemies.forEach(enemy => {
            this._ctx.strokeRect(enemy.x, enemy.y, enemy.width, enemy.height);
        });

        // Question block hitboxes
        this._ctx.strokeStyle = '#FFFF00';
        this._questionBlocks.forEach(block => {
            this._ctx.strokeRect(block.x, block.y, block.width, block.height);
        });
    }
}

export default MarioEducational;