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

/**
 * TeamWizardBattle - Team-based spell casting battle game
 * Two teams compete to deal the most damage to a shared boss
 */
class TeamWizardBattle extends Module {
    constructor(name, dependencies, config = {}) {
        super(name, ['eventBus']);

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

        this._eventBus = dependencies.eventBus;
        this._content = dependencies.content;
        this._config = {
            container: null,
            enemyAttackInterval: { min: 8000, max: 15000 },
            enemyDamage: { min: 12, max: 20 },
            maxPlayerHP: 100,
            maxEnemyHP: 500, // Increased HP for team battle
            maxRounds: 10,
            ...config
        };

        // Team battle state
        this._redTeamDPS = 0;
        this._blueTeamDPS = 0;
        this._currentTeam = 'red'; // 'red' or 'blue'
        this._currentRound = 1;
        this._teamSelectionDone = false;

        // Game state
        this._score = 0;
        this._enemyHP = this._config.maxEnemyHP;
        this._playerHP = this._config.maxPlayerHP;
        this._gameStartTime = null;

        // Spell system
        this._spells = { short: [], medium: [], long: [] };
        this._currentSpells = [];
        this._selectedSpell = null;
        this._selectedWords = [];
        this._spellStartTime = null;
        this._averageSpellTime = 0;
        this._spellCount = 0;

        // Enemy attack system
        this._enemyAttackTimer = null;
        this._nextEnemyAttack = 0;

        Object.seal(this);
    }

    /**
     * Get game metadata
     * @returns {Object} Game metadata
     */
    static getMetadata() {
        return {
            name: 'Team Wizard Battle',
            description: 'Two teams compete in a DPS race against a shared boss! Build sentences fast to deal maximum damage!',
            difficulty: 'advanced',
            category: 'rpg',
            estimatedTime: 15, // minutes
            skills: ['grammar', 'sentences', 'vocabulary', 'strategy', 'speed', 'teamwork']
        };
    }

    /**
     * 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 storyChapters = content?.story?.chapters || [];
        const dialogues = content?.dialogues || [];
        const texts = content?.texts || [];
        const phrases = content?.phrases || {};
        const dialogs = content?.dialogs || {};

        let totalSentences = sentences.length;

        // Count sentences from story chapters
        storyChapters.forEach(chapter => {
            if (chapter.sentences) {
                totalSentences += chapter.sentences.length;
            }
        });

        // Count sentences from dialogues
        dialogues.forEach(dialogue => {
            if (dialogue.conversation) {
                totalSentences += dialogue.conversation.length;
            }
        });

        // Count phrases (object format with key-value pairs)
        if (typeof phrases === 'object') {
            totalSentences += Object.keys(phrases).length;
        }

        // Count dialog lines (alternative spelling, object format)
        if (typeof dialogs === 'object') {
            Object.values(dialogs).forEach(dialog => {
                if (dialog.lines && Array.isArray(dialog.lines)) {
                    totalSentences += dialog.lines.length;
                }
            });
        }

        // Count extractable sentences from texts (LEDU-style content)
        let extractableSentences = 0;
        texts.forEach(text => {
            if (text.content) {
                const sentencesInText = text.content.split(/[。！？\.\!\?]+/).filter(s => {
                    const trimmed = s.trim();
                    const wordCount = trimmed.split(/\s+/).length;
                    return trimmed && wordCount >= 3 && wordCount <= 15;
                });
                extractableSentences += sentencesInText.length;
            }
        });

        totalSentences += extractableSentences;

        // If we have enough sentences, use them
        if (totalSentences >= 9) {
            const score = Math.min(totalSentences / 30, 1);
            return {
                score,
                reason: `${totalSentences} sentences/phrases available for spell construction`,
                requirements: ['sentences', 'story', 'dialogues', 'texts', 'phrases', 'dialogs'],
                minSentences: 9,
                optimalSentences: 30,
                details: `Can create engaging spell combat with ${totalSentences} sentences/phrases`
            };
        }

        // Fallback: Check vocabulary for creating basic spell phrases
        let vocabCount = 0;
        let hasVocabulary = false;

        if (Array.isArray(content?.vocabulary)) {
            vocabCount = content.vocabulary.length;
            hasVocabulary = vocabCount > 0;
        } else if (content?.vocabulary && typeof content.vocabulary === 'object') {
            vocabCount = Object.keys(content.vocabulary).length;
            hasVocabulary = vocabCount > 0;
        }

        if (hasVocabulary && vocabCount >= 15) {
            // Can create basic spell phrases from vocabulary
            let score = 0.3; // Base score for vocabulary-based spells

            if (vocabCount >= 20) score += 0.1;
            if (vocabCount >= 30) score += 0.1;
            if (vocabCount >= 40) score += 0.1;

            return {
                score: Math.min(score, 0.6), // Cap at 60% for vocabulary-only content
                reason: `${vocabCount} vocabulary words available for spell creation`,
                requirements: ['vocabulary'],
                minWords: 15,
                optimalWords: 40,
                details: `Can create basic spell combat using ${vocabCount} vocabulary words`
            };
        }

        return {
            score: 0,
            reason: `Insufficient content (${totalSentences} sentences/phrases, ${vocabCount} vocabulary words)`,
            requirements: ['sentences', 'story', 'dialogues', 'texts', 'phrases', 'dialogs', 'vocabulary'],
            minSentences: 9,
            minWords: 15,
            details: 'Wizard Spell Caster needs at least 9 sentences/phrases or 15 vocabulary words'
        };
    }

    async init() {
        this._validateNotDestroyed();

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

            // Extract and validate spells
            this._extractSpells();
            if (this._getTotalSpellCount() < 9) {
                throw new Error(`Insufficient spells: need 9, got ${this._getTotalSpellCount()}`);
            }

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

            // Inject CSS
            this._injectCSS();

            // Initialize game interface
            this._createGameInterface();
            this._setupEventListeners();
            this._generateNewSpells();
            this._startEnemyAttackSystem();

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

            // Emit game ready event
            this._eventBus.emit('game:ready', {
                gameId: 'wizard-spell-caster',
                instanceId: this.name,
                spells: {
                    short: this._spells.short.length,
                    medium: this._spells.medium.length,
                    long: this._spells.long.length
                }
            }, this.name);

            this._setInitialized();

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

    async destroy() {
        this._validateNotDestroyed();

        // Clear timers
        if (this._enemyAttackTimer) {
            clearTimeout(this._enemyAttackTimer);
            this._enemyAttackTimer = null;
        }

        // Remove CSS
        this._removeCSS();

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

        // Emit game end event
        this._eventBus.emit('game:ended', {
            gameId: 'wizard-spell-caster',
            instanceId: this.name,
            score: this._score,
            playerHP: this._playerHP,
            enemyHP: this._enemyHP,
            spellsCast: this._spellCount,
            duration: this._gameStartTime ? Date.now() - this._gameStartTime : 0
        }, this.name);

        this._setDestroyed();
    }

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

        return {
            score: this._score,
            playerHP: this._playerHP,
            enemyHP: this._enemyHP,
            maxPlayerHP: this._config.maxPlayerHP,
            maxEnemyHP: this._config.maxEnemyHP,
            spellsCast: this._spellCount,
            averageSpellTime: this._averageSpellTime,
            isComplete: this._playerHP <= 0 || this._enemyHP <= 0,
            duration: this._gameStartTime ? Date.now() - this._gameStartTime : 0
        };
    }

    // Private methods
    _extractSpells() {
        this._spells = { short: [], medium: [], long: [] };

        // Extract from sentences
        if (this._content.sentences) {
            this._content.sentences.forEach(sentence => {
                const originalText = sentence.english || sentence.original_language;
                if (originalText) {
                    this._processSentence({
                        original: originalText,
                        translation: sentence.chinese || sentence.french || sentence.user_language || sentence.translation,
                        words: this._extractWordsFromSentence(originalText)
                    });
                }
            });
        }

        // Extract from story chapters
        if (this._content.story?.chapters) {
            this._content.story.chapters.forEach(chapter => {
                if (chapter.sentences) {
                    chapter.sentences.forEach(sentence => {
                        if (sentence.original) {
                            this._processSentence({
                                original: sentence.original,
                                translation: sentence.translation,
                                words: sentence.words || this._extractWordsFromSentence(sentence.original)
                            });
                        }
                    });
                }
            });
        }

        // Extract from dialogues
        if (this._content.dialogues) {
            this._content.dialogues.forEach(dialogue => {
                if (dialogue.conversation) {
                    dialogue.conversation.forEach(line => {
                        if (line.english && line.chinese) {
                            this._processSentence({
                                original: line.english,
                                translation: line.chinese,
                                words: this._extractWordsFromSentence(line.english)
                            });
                        }
                    });
                }
            });
        }

        // Extract from phrases (key-value object format)
        if (this._content.phrases && typeof this._content.phrases === 'object') {
            Object.entries(this._content.phrases).forEach(([english, phraseData]) => {
                const translation = typeof phraseData === 'string' ? phraseData : phraseData.user_language || phraseData.chinese;
                if (english && translation) {
                    this._processSentence({
                        original: english,
                        translation: translation,
                        words: this._extractWordsFromSentence(english)
                    });
                }
            });
        }

        // Extract from dialogs (alternative spelling of dialogues)
        if (this._content.dialogs && typeof this._content.dialogs === 'object') {
            Object.values(this._content.dialogs).forEach(dialog => {
                if (dialog.lines && Array.isArray(dialog.lines)) {
                    dialog.lines.forEach(line => {
                        if (line.text && line.user_language) {
                            this._processSentence({
                                original: line.text,
                                translation: line.user_language,
                                words: this._extractWordsFromSentence(line.text)
                            });
                        }
                    });
                }
            });
        }

        // Fallback: Extract from texts (for LEDU-style content)
        if (this._getTotalSpellCount() < 9 && this._content.texts && Array.isArray(this._content.texts)) {
            console.log('WizardSpellCaster: Extracting spells from texts as fallback');
            this._content.texts.forEach(text => {
                if (text.content) {
                    // Split text into sentences using Chinese punctuation and periods
                    const sentences = text.content.split(/[。！？\.\!\?]+/).filter(s => s.trim().length > 0);
                    sentences.forEach(sentence => {
                        const trimmed = sentence.trim();
                        // Only use sentences with reasonable length (3-15 words)
                        const wordCount = trimmed.split(/\s+/).length;
                        if (trimmed && wordCount >= 3 && wordCount <= 15) {
                            this._processSentence({
                                original: trimmed,
                                translation: trimmed, // In Chinese content, use same for both
                                words: this._extractWordsFromSentence(trimmed)
                            });
                        }
                    });
                }
            });
        }
    }

    _processSentence(sentenceData) {
        if (!sentenceData.original || !sentenceData.translation) return;

        const wordCount = sentenceData.words.length;
        const spellData = {
            english: sentenceData.original,
            translation: sentenceData.translation,
            words: sentenceData.words,
            damage: this._calculateDamage(wordCount),
            castTime: this._calculateCastTime(wordCount)
        };

        if (wordCount <= 4) {
            this._spells.short.push(spellData);
        } else if (wordCount <= 6) {
            this._spells.medium.push(spellData);
        } else {
            this._spells.long.push(spellData);
        }
    }

    _extractWordsFromSentence(sentence) {
        // Validate input sentence
        if (!sentence || typeof sentence !== 'string') {
            console.warn('WizardSpellCaster: Invalid sentence provided to _extractWordsFromSentence:', sentence);
            return [];
        }

        // Simple word extraction with punctuation handling
        const words = sentence.split(/\s+/).map(word => {
            return {
                word: word.replace(/[.!?,;:]/g, ''),
                translation: word.replace(/[.!?,;:]/g, ''),
                type: 'word'
            };
        }).filter(wordData => wordData.word.length > 0);

        // Add punctuation as separate elements
        const punctuation = sentence.match(/[.!?,;:]/g) || [];
        punctuation.forEach((punct, index) => {
            words.push({
                word: punct,
                translation: punct,
                type: 'punctuation',
                uniqueId: `punct_${index}_${Date.now()}_${Math.random()}`
            });
        });

        return words;
    }

    _calculateDamage(wordCount) {
        if (wordCount <= 3) return Math.floor(Math.random() * 10) + 15; // 15-25
        if (wordCount <= 5) return Math.floor(Math.random() * 15) + 30; // 30-45
        if (wordCount <= 7) return Math.floor(Math.random() * 20) + 50; // 50-70
        return Math.floor(Math.random() * 30) + 70; // 70-100
    }

    _calculateCastTime(wordCount) {
        if (wordCount <= 4) return 1000; // 1 second
        if (wordCount <= 6) return 2000; // 2 seconds
        return 3000; // 3 seconds
    }

    _getTotalSpellCount() {
        return this._spells.short.length + this._spells.medium.length + this._spells.long.length;
    }

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

        const style = document.createElement('style');
        style.id = cssId;
        style.textContent = `
            .wizard-game-wrapper {
                background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
                height: 100vh;
                color: white;
                font-family: 'Fantasy', serif;
                position: relative;
                overflow: hidden;
                display: flex;
                flex-direction: column;
            }

            .wizard-hud {
                display: flex;
                justify-content: space-between;
                padding: 8px 15px;
                background: rgba(0,0,0,0.3);
                border-bottom: 2px solid #ffd700;
                flex-shrink: 0;
            }

            .wizard-stats {
                display: flex;
                gap: 20px;
                align-items: center;
            }

            .health-bar {
                width: 120px;
                height: 16px;
                background: rgba(255,255,255,0.2);
                border-radius: 8px;
                overflow: hidden;
                border: 2px solid #ffd700;
            }

            .health-fill {
                height: 100%;
                background: linear-gradient(90deg, #ff4757, #ff6b7a);
                transition: width 0.3s ease;
            }

            .battle-area {
                display: flex;
                height: 180px;
                padding: 10px 20px;
                flex-shrink: 0;
            }

            .wizard-side {
                flex: 1;
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
            }

            .enemy-side {
                flex: 1;
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
            }

            .wizard-character {
                width: 80px;
                height: 80px;
                background: linear-gradient(45deg, #6c5ce7, #a29bfe);
                border-radius: 50%;
                display: flex;
                align-items: center;
                justify-content: center;
                font-size: 36px;
                margin-bottom: 8px;
                animation: float 3s ease-in-out infinite;
                box-shadow: 0 0 30px rgba(108, 92, 231, 0.6);
            }

            .enemy-character {
                width: 100px;
                height: 100px;
                background: linear-gradient(45deg, #ff4757, #ff6b7a);
                border-radius: 20px;
                display: flex;
                align-items: center;
                justify-content: center;
                font-size: 48px;
                margin-bottom: 8px;
                animation: enemyPulse 2s ease-in-out infinite;
                box-shadow: 0 0 40px rgba(255, 71, 87, 0.6);
            }

            @keyframes float {
                0%, 100% { transform: translateY(0px); }
                50% { transform: translateY(-10px); }
            }

            @keyframes enemyPulse {
                0%, 100% { transform: scale(1); }
                50% { transform: scale(1.05); }
            }

            .spell-casting-area {
                background: rgba(0,0,0,0.4);
                border: 2px solid #ffd700;
                border-radius: 15px;
                padding: 12px 15px;
                margin: 0 15px 10px 15px;
                flex: 1;
                overflow-y: auto;
                display: flex;
                flex-direction: column;
            }

            .spell-selection {
                display: grid;
                grid-template-columns: repeat(3, 1fr);
                gap: 10px;
                margin-bottom: 10px;
                flex-shrink: 0;
            }

            .spell-card {
                background: linear-gradient(135deg, #2c2c54, #40407a);
                border: 2px solid #ffd700;
                border-radius: 8px;
                padding: 10px;
                cursor: pointer;
                transition: all 0.3s ease;
                text-align: center;
            }

            .spell-card:hover {
                transform: translateY(-5px);
                box-shadow: 0 10px 25px rgba(255, 215, 0, 0.3);
                border-color: #fff;
            }

            .spell-card.selected {
                background: linear-gradient(135deg, #ffd700, #ffed4e);
                color: #000;
                transform: scale(1.05);
                animation: spellCharging 0.5s ease-in-out infinite alternate;
            }

            .spell-type {
                font-size: 12px;
                color: #ffd700;
                font-weight: bold;
                margin-bottom: 5px;
            }

            .spell-damage {
                font-size: 14px;
                color: #ff6b7a;
                font-weight: bold;
            }

            .sentence-builder {
                background: rgba(255,255,255,0.1);
                border-radius: 8px;
                padding: 10px;
                margin-bottom: 10px;
                min-height: 60px;
                border: 2px dashed #ffd700;
                flex-shrink: 0;
            }

            .word-bank {
                display: flex;
                flex-wrap: wrap;
                gap: 8px;
                margin-bottom: 10px;
                flex-shrink: 0;
            }

            .word-tile {
                background: linear-gradient(135deg, #5f27cd, #8854d0);
                color: white;
                padding: 6px 12px;
                border-radius: 15px;
                cursor: grab;
                user-select: none;
                transition: all 0.3s ease;
                border: 2px solid transparent;
                font-size: 0.9em;
            }

            .word-tile:hover {
                transform: scale(1.1);
                box-shadow: 0 5px 15px rgba(95, 39, 205, 0.4);
            }

            .word-tile.selected {
                background: linear-gradient(135deg, #ffd700, #ffed4e);
                color: #000;
                border-color: #fff;
            }

            .word-tile:active {
                cursor: grabbing;
            }

            .cast-button {
                background: linear-gradient(135deg, #ff6b7a, #ff4757);
                border: none;
                color: white;
                padding: 12px 25px;
                border-radius: 20px;
                font-size: 16px;
                font-weight: bold;
                cursor: pointer;
                transition: all 0.3s ease;
                box-shadow: 0 5px 15px rgba(255, 71, 87, 0.3);
                width: 100%;
                flex-shrink: 0;
            }

            .cast-button:hover {
                transform: translateY(-3px);
                box-shadow: 0 8px 25px rgba(255, 71, 87, 0.5);
            }

            .cast-button:disabled {
                background: #666;
                cursor: not-allowed;
                transform: none;
                box-shadow: none;
            }

            .exit-wizard-btn {
                padding: 8px 15px;
                background: rgba(255, 255, 255, 0.1);
                border: 2px solid rgba(255, 255, 255, 0.3);
                color: white;
                border-radius: 8px;
                cursor: pointer;
                font-size: 0.9rem;
                transition: all 0.3s ease;
            }

            .exit-wizard-btn:hover {
                background: rgba(255, 255, 255, 0.2);
                transform: translateY(-2px);
            }

            .damage-number {
                position: absolute;
                font-size: 36px;
                font-weight: bold;
                color: #ff4757;
                text-shadow: 2px 2px 4px rgba(0,0,0,0.8);
                pointer-events: none;
                animation: damageFloat 1.5s ease-out forwards;
            }

            @keyframes damageFloat {
                0% {
                    opacity: 1;
                    transform: translateY(0) scale(1);
                }
                100% {
                    opacity: 0;
                    transform: translateY(-100px) scale(1.5);
                }
            }

            .spell-effect {
                position: absolute;
                width: 100px;
                height: 100px;
                border-radius: 50%;
                pointer-events: none;
                animation: spellBlast 0.8s ease-out forwards;
            }

            .fire-effect {
                background: radial-gradient(circle, #ff6b7a, #ff4757, #ff3742, transparent);
                filter: drop-shadow(0 0 20px #ff4757);
                animation: spellBlast 0.8s ease-out forwards, fireGlow 0.8s ease-out;
            }

            .fireball-projectile {
                position: fixed;
                width: 60px;
                height: 60px;
                border-radius: 50%;
                background: radial-gradient(circle at 30% 30%, #fff, #ffd700, #ff6b7a, #ff4757);
                box-shadow: 0 0 40px #ff4757, 0 0 80px #ff6b7a, inset 0 0 20px #fff;
                pointer-events: none;
                z-index: 1000;
            }

            .fireball-trail {
                position: fixed;
                width: 40px;
                height: 40px;
                border-radius: 50%;
                background: radial-gradient(circle, #ff6b7a, transparent);
                pointer-events: none;
                z-index: 999;
                animation: fadeTrail 0.5s ease-out forwards;
            }

            @keyframes fadeTrail {
                0% {
                    opacity: 0.8;
                    transform: scale(1);
                }
                100% {
                    opacity: 0;
                    transform: scale(2);
                }
            }

            .fireball-spark {
                position: fixed;
                width: 8px;
                height: 8px;
                border-radius: 50%;
                background: #ffd700;
                box-shadow: 0 0 10px #ff4757;
                pointer-events: none;
                z-index: 998;
            }

            .lightning-bolt {
                position: fixed;
                pointer-events: none;
                z-index: 1000;
            }

            .lightning-segment {
                position: absolute;
                background: linear-gradient(90deg, transparent, #fff, #ffd700, #fff, transparent);
                box-shadow: 0 0 20px #ffd700, 0 0 40px #ffed4e;
                transform-origin: left center;
            }

            .lightning-spark {
                position: fixed;
                width: 10px;
                height: 10px;
                border-radius: 50%;
                background: #fff;
                box-shadow: 0 0 15px #ffd700, 0 0 30px #ffed4e;
                pointer-events: none;
                z-index: 999;
            }

            .lightning-flash {
                position: fixed;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                background: rgba(255, 255, 255, 0.3);
                pointer-events: none;
                z-index: 998;
                animation: lightningFlash 0.3s ease-out;
            }

            @keyframes lightningFlash {
                0%, 100% { opacity: 0; }
                50% { opacity: 1; }
            }

            .lightning-effect {
                background: radial-gradient(circle, #ffd700, #ffed4e, #fff200, transparent);
                filter: drop-shadow(0 0 25px #ffd700);
                animation: spellBlast 0.8s ease-out forwards, lightningPulse 0.8s ease-out;
            }

            .meteor-effect {
                background: radial-gradient(circle, #a29bfe, #6c5ce7, #5f3dc4, transparent);
                filter: drop-shadow(0 0 30px #6c5ce7);
                animation: spellBlast 0.8s ease-out forwards, meteorImpact 0.8s ease-out;
            }

            @keyframes spellBlast {
                0% {
                    transform: scale(0);
                    opacity: 1;
                }
                50% {
                    transform: scale(1.5);
                    opacity: 0.8;
                }
                100% {
                    transform: scale(3);
                    opacity: 0;
                }
            }

            @keyframes fireGlow {
                0%, 100% { filter: drop-shadow(0 0 20px #ff4757) hue-rotate(0deg); }
                50% { filter: drop-shadow(0 0 40px #ff4757) hue-rotate(30deg); }
            }

            @keyframes lightningPulse {
                0%, 100% { filter: drop-shadow(0 0 25px #ffd700) brightness(1); }
                50% { filter: drop-shadow(0 0 50px #ffd700) brightness(2); }
            }

            @keyframes meteorImpact {
                0% { filter: drop-shadow(0 0 30px #6c5ce7) contrast(1); }
                30% { filter: drop-shadow(0 0 60px #6c5ce7) contrast(1.5); }
                100% { filter: drop-shadow(0 0 30px #6c5ce7) contrast(1); }
            }

            @keyframes spellCharging {
                0% {
                    box-shadow: 0 0 20px rgba(255, 215, 0, 0.5);
                    transform: scale(1.05);
                }
                100% {
                    box-shadow: 0 0 40px rgba(255, 215, 0, 0.8);
                    transform: scale(1.07);
                }
            }

            .meteor-projectile {
                position: fixed;
                width: 80px;
                height: 80px;
                border-radius: 50%;
                background: radial-gradient(circle at 25% 25%, #fff, #a29bfe, #6c5ce7, #5f3dc4);
                box-shadow: 0 0 50px #6c5ce7, 0 0 100px #a29bfe, inset 0 0 30px rgba(255, 255, 255, 0.5);
                pointer-events: none;
                z-index: 1000;
            }

            .meteor-trail {
                position: fixed;
                width: 60px;
                height: 60px;
                border-radius: 50%;
                background: radial-gradient(circle, #a29bfe, #6c5ce7, transparent);
                pointer-events: none;
                z-index: 999;
                animation: fadeTrail 0.6s ease-out forwards;
            }

            .meteor-debris {
                position: fixed;
                width: 10px;
                height: 10px;
                background: linear-gradient(135deg, #a29bfe, #6c5ce7);
                box-shadow: 0 0 15px #6c5ce7;
                pointer-events: none;
                z-index: 998;
            }

            .meteor-spark {
                position: fixed;
                width: 12px;
                height: 12px;
                border-radius: 50%;
                background: #a29bfe;
                box-shadow: 0 0 20px #6c5ce7, 0 0 40px #a29bfe;
                pointer-events: none;
                z-index: 997;
            }

            .meteor-shockwave {
                position: fixed;
                width: 20px;
                height: 20px;
                border: 3px solid #a29bfe;
                border-radius: 50%;
                box-shadow: 0 0 20px #6c5ce7, inset 0 0 20px #6c5ce7;
                pointer-events: none;
                z-index: 996;
                transform: translate(-50%, -50%);
                animation: meteorShockwave 0.8s ease-out forwards;
            }

            @keyframes meteorShockwave {
                0% {
                    width: 20px;
                    height: 20px;
                    opacity: 1;
                    border-width: 5px;
                }
                50% {
                    opacity: 0.6;
                    border-width: 3px;
                }
                100% {
                    width: 200px;
                    height: 200px;
                    opacity: 0;
                    border-width: 1px;
                }
            }

            .mini-enemy {
                position: absolute;
                width: 60px;
                height: 60px;
                background: linear-gradient(45deg, #ff9ff3, #f368e0);
                border-radius: 50%;
                font-size: 30px;
                display: flex;
                align-items: center;
                justify-content: center;
                animation: miniEnemyFloat 3s ease-in-out infinite;
                z-index: 100;
            }

            @keyframes miniEnemyFloat {
                0%, 100% { transform: translateY(0px) rotate(0deg); }
                50% { transform: translateY(-15px) rotate(180deg); }
            }

            .magic-quirk {
                position: fixed;
                width: 200px;
                height: 200px;
                border-radius: 50%;
                background: conic-gradient(from 0deg, #ff0080, #0080ff, #ff0080);
                animation: magicQuirk 2s ease-in-out;
                z-index: 1000;
                pointer-events: none;
            }

            @keyframes magicQuirk {
                0% {
                    transform: translate(-50%, -50%) scale(0) rotate(0deg);
                    opacity: 1;
                }
                50% {
                    transform: translate(-50%, -50%) scale(1.5) rotate(180deg);
                    opacity: 0.8;
                }
                100% {
                    transform: translate(-50%, -50%) scale(0) rotate(360deg);
                    opacity: 0;
                }
            }

            .flying-bird {
                position: fixed;
                font-size: 48px;
                z-index: 500;
                pointer-events: none;
                width: 60px;
                height: 60px;
                display: flex;
                align-items: center;
                justify-content: center;
            }

            .bird-path-1 { animation: flyPath1 8s linear infinite; }
            .bird-path-2 { animation: flyPath2 6s linear infinite; }
            .bird-path-3 { animation: flyPath3 10s linear infinite; }

            @keyframes flyPath1 {
                0% { left: -100px; top: 20vh; transform: rotate(0deg) scale(1); }
                25% { left: 30vw; top: 5vh; transform: rotate(180deg) scale(1.5); }
                50% { left: 70vw; top: 40vh; transform: rotate(-90deg) scale(0.5); }
                75% { left: 100vw; top: 15vh; transform: rotate(270deg) scale(2); }
                100% { left: -100px; top: 20vh; transform: rotate(360deg) scale(1); }
            }

            @keyframes flyPath2 {
                0% { left: 50vw; top: -80px; transform: rotate(0deg) scale(0.5); }
                33% { left: 80vw; top: 20vh; transform: rotate(-225deg) scale(2.5); }
                66% { left: 20vw; top: 50vh; transform: rotate(315deg) scale(0.3); }
                100% { left: 50vw; top: -80px; transform: rotate(-630deg) scale(0.5); }
            }

            @keyframes flyPath3 {
                0% { left: 120vw; top: 10vh; transform: rotate(0deg) scale(1); }
                20% { left: 75vw; top: 70vh; transform: rotate(-360deg) scale(4); }
                40% { left: 25vw; top: 20vh; transform: rotate(540deg) scale(0.2); }
                60% { left: 85vw; top: 90vh; transform: rotate(-720deg) scale(3.5); }
                80% { left: 10vw; top: 5vh; transform: rotate(900deg) scale(0.4); }
                100% { left: 120vw; top: 10vh; transform: rotate(1800deg) scale(1); }
            }

            .screen-shake {
                animation: screenShake 0.5s ease-in-out;
            }

            @keyframes screenShake {
                0%, 100% { transform: translateX(0); }
                10% { transform: translateX(-10px); }
                20% { transform: translateX(10px); }
                30% { transform: translateX(-10px); }
                40% { transform: translateX(10px); }
                50% { transform: translateX(-10px); }
                60% { transform: translateX(10px); }
                70% { transform: translateX(-10px); }
                80% { transform: translateX(10px); }
                90% { transform: translateX(-10px); }
            }

            .enemy-attack-warning {
                position: absolute;
                top: -30px;
                left: 50%;
                transform: translateX(-50%);
                background: #ff4757;
                color: white;
                padding: 5px 15px;
                border-radius: 15px;
                font-size: 14px;
                font-weight: bold;
                animation: warningPulse 1s ease-in-out infinite;
                z-index: 100;
            }

            @keyframes warningPulse {
                0%, 100% { opacity: 1; transform: translateX(-50%) scale(1); }
                50% { opacity: 0.6; transform: translateX(-50%) scale(1.1); }
            }

            .enemy-attack-effect {
                position: absolute;
                width: 150px;
                height: 150px;
                border-radius: 50%;
                background: radial-gradient(circle, #ff4757, transparent);
                animation: enemyAttackBlast 1s ease-out;
                pointer-events: none;
                z-index: 200;
            }

            @keyframes enemyAttackBlast {
                0% { transform: scale(0); opacity: 1; }
                50% { transform: scale(1.5); opacity: 0.8; }
                100% { transform: scale(3); opacity: 0; }
            }

            .enemy-charging {
                animation: enemyCharging 2s ease-in-out;
            }

            @keyframes enemyCharging {
                0%, 100% {
                    background: linear-gradient(45deg, #ff4757, #ff6b7a);
                    transform: scale(1);
                }
                50% {
                    background: linear-gradient(45deg, #ff0000, #ff3333);
                    transform: scale(1.1);
                    box-shadow: 0 0 60px rgba(255, 0, 0, 0.8);
                }
            }

            .victory-screen, .defeat-screen {
                position: absolute;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background: rgba(0,0,0,0.8);
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
                z-index: 1000;
            }

            .result-title {
                font-size: 48px;
                margin-bottom: 20px;
                text-shadow: 2px 2px 4px rgba(0,0,0,0.8);
            }

            .victory-screen .result-title {
                color: #2ed573;
            }

            .defeat-screen .result-title {
                color: #ff4757;
            }

            .game-result-btn {
                margin: 10px;
                padding: 15px 30px;
                border: 2px solid white;
                border-radius: 10px;
                background: transparent;
                color: white;
                font-size: 18px;
                font-weight: bold;
                cursor: pointer;
                transition: all 0.3s ease;
            }

            .game-result-btn.victory {
                border-color: #2ed573;
                color: #2ed573;
            }

            .game-result-btn.victory:hover {
                background: #2ed573;
                color: white;
            }

            .game-result-btn.defeat {
                border-color: #ff4757;
                color: #ff4757;
            }

            .game-result-btn.defeat:hover {
                background: #ff4757;
                color: white;
            }

            .fail-message {
                position: fixed;
                top: 30%;
                left: 50%;
                transform: translateX(-50%);
                background: rgba(255, 71, 87, 0.9);
                color: white;
                padding: 20px 30px;
                border-radius: 15px;
                font-size: 24px;
                font-weight: bold;
                z-index: 1000;
                animation: failMessagePop 2s ease-out;
                text-align: center;
                border: 3px solid #ffd700;
            }

            @keyframes failMessagePop {
                0% { transform: translateX(-50%) scale(0); opacity: 0; }
                20% { transform: translateX(-50%) scale(1.2); opacity: 1; }
                80% { transform: translateX(-50%) scale(1); opacity: 1; }
                100% { transform: translateX(-50%) scale(0.8); opacity: 0; }
            }

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

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

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

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

            @media (max-width: 768px) {
                .wizard-game-wrapper {
                    padding: 10px;
                }

                .battle-area {
                    height: 50vh;
                    padding: 10px;
                }

                .wizard-character, .enemy-character {
                    width: 80px;
                    height: 80px;
                    font-size: 32px;
                }

                .spell-selection {
                    grid-template-columns: 1fr;
                    gap: 10px;
                }

                .word-bank {
                    gap: 5px;
                }

                .word-tile {
                    padding: 6px 12px;
                    font-size: 0.9rem;
                }
            }
        `;

        document.head.appendChild(style);
    }

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

    _createGameInterface() {
        this._config.container.innerHTML = `
            <div class="wizard-game-wrapper">
                <div class="wizard-hud">
                    <div class="wizard-stats">
                        <div>
                            <div style="color: #ff6666; font-weight: bold;">🔴 RED TEAM</div>
                            <div style="font-size: 1.5em; color: #ff6666;"><span id="red-team-dps">0</span> DPS</div>
                        </div>
                        <div>
                            <div>Round: <span id="current-round">1</span>/10</div>
                            <div style="margin-top: 5px; font-size: 0.9em; color: #ffd700;" id="current-team-display">🔴 RED TEAM TURN</div>
                        </div>
                    </div>
                    <div class="wizard-stats">
                        <div>
                            <div>Boss HP</div>
                            <div class="health-bar">
                                <div class="health-fill" id="enemy-health" style="width: 100%"></div>
                            </div>
                        </div>
                        <div>
                            <div style="color: #66b3ff; font-weight: bold;">🔵 BLUE TEAM</div>
                            <div style="font-size: 1.5em; color: #66b3ff;"><span id="blue-team-dps">0</span> DPS</div>
                        </div>
                    </div>
                </div>

                <div class="battle-area">
                    <div class="wizard-side">
                        <div class="wizard-character" id="current-player-character">👸</div>
                        <div id="current-player-name">Red Princess</div>
                    </div>
                    <div class="enemy-side">
                        <div class="enemy-character">👹</div>
                        <div>Grammar Demon</div>
                    </div>
                </div>

                <div class="spell-casting-area">
                    <div class="spell-selection" id="spell-selection">
                        <!-- Spell cards will be populated here -->
                    </div>

                    <div class="sentence-builder" id="sentence-builder">
                        <div style="color: #ffd700; margin-bottom: 5px; font-size: 0.9em;">Form your spell incantation:</div>
                        <div id="current-sentence" style="font-size: 16px; min-height: 24px;"></div>
                    </div>

                    <div class="word-bank" id="word-bank">
                        <!-- Words will be populated here -->
                    </div>

                    <button class="cast-button" id="cast-button" disabled>🔥 CAST SPELL 🔥</button>
                </div>
            </div>
        `;
    }

    _setupEventListeners() {
        // Cast button
        document.getElementById('cast-button').addEventListener('click', () => this._castSpell());

        // Exit button with spam-click protection
        const exitButton = document.getElementById('exit-wizard');
        if (exitButton) {
            exitButton.addEventListener('click', () => {
                exitButton.disabled = true; // Prevent spam clicking
                this._eventBus.emit('game:exit-request', { instanceId: this.name }, this.name);
            }, { once: true }); // Execute only once
        }
    }

    _generateNewSpells() {
        this._currentSpells = [];

        // Get one spell of each type
        if (this._spells.short.length > 0) {
            this._currentSpells.push({
                ...this._spells.short[Math.floor(Math.random() * this._spells.short.length)],
                type: 'short',
                name: 'Fireball',
                icon: '🔥'
            });
        }

        if (this._spells.medium.length > 0) {
            this._currentSpells.push({
                ...this._spells.medium[Math.floor(Math.random() * this._spells.medium.length)],
                type: 'medium',
                name: 'Lightning',
                icon: '⚡'
            });
        }

        if (this._spells.long.length > 0) {
            this._currentSpells.push({
                ...this._spells.long[Math.floor(Math.random() * this._spells.long.length)],
                type: 'long',
                name: 'Meteor',
                icon: '☄️'
            });
        }

        this._renderSpellCards();
        this._selectedSpell = null;
        this._selectedWords = [];
        this._updateWordBank();
        this._updateSentenceBuilder();

        // Re-enable cast button for next spell (critical for children spam-clicking!)
        const castButton = document.getElementById('cast-button');
        if (castButton) {
            castButton.disabled = false;
        }
    }

    _renderSpellCards() {
        const container = document.getElementById('spell-selection');
        if (!container) {
            console.warn('Spell selection container not found, skipping render');
            return;
        }
        container.innerHTML = this._currentSpells.map((spell, index) => `
            <div class="spell-card" data-spell-index="${index}">
                <div class="spell-type">${spell.icon} ${spell.name}</div>
                <div style="margin: 10px 0; font-size: 14px;">${spell.translation}</div>
                <div class="spell-damage">${spell.damage} damage</div>
            </div>
        `).join('');

        // Add click listeners
        container.querySelectorAll('.spell-card').forEach(card => {
            card.addEventListener('click', (e) => {
                const spellIndex = parseInt(e.currentTarget.dataset.spellIndex);
                this._selectSpell(spellIndex);
            });
        });
    }

    _selectSpell(index) {
        // Remove previous selection
        document.querySelectorAll('.spell-card').forEach(card => card.classList.remove('selected'));

        // Select new spell
        this._selectedSpell = this._currentSpells[index];
        document.querySelector(`[data-spell-index="${index}"]`).classList.add('selected');

        // Start timing for speed bonus
        this._spellStartTime = Date.now();

        // Reset word selection
        this._selectedWords = [];
        this._updateWordBank();
        this._updateSentenceBuilder();
    }

    _updateWordBank() {
        const container = document.getElementById('word-bank');

        if (!this._selectedSpell) {
            container.innerHTML = '<div style="color: #ffd700;">Select a spell first</div>';
            return;
        }

        // Get words and add punctuation
        const words = [...this._selectedSpell.words];

        // Shuffle the words including punctuation
        const shuffledWords = [...words].sort(() => Math.random() - 0.5);

        container.innerHTML = shuffledWords.map((wordData, index) => {
            const uniqueId = wordData.uniqueId || `word_${index}_${wordData.word}`;
            return `
                <div class="word-tile" data-word-index="${index}" data-word="${wordData.word}" data-unique-id="${uniqueId}">
                    ${wordData.word}
                </div>
            `;
        }).join('');

        // Add click listeners
        container.querySelectorAll('.word-tile').forEach(tile => {
            tile.addEventListener('click', (e) => {
                const word = e.currentTarget.dataset.word;
                const uniqueId = e.currentTarget.dataset.uniqueId;
                this._toggleWord(word, e.currentTarget, uniqueId);
            });
        });
    }

    _toggleWord(word, element, uniqueId) {
        const wordIndex = this._selectedWords.findIndex(selectedWord =>
            selectedWord.uniqueId === uniqueId
        );

        if (wordIndex > -1) {
            // Remove word
            this._selectedWords.splice(wordIndex, 1);
            element.classList.remove('selected');
        } else {
            // Add word with unique ID
            this._selectedWords.push({
                word: word,
                uniqueId: uniqueId
            });
            element.classList.add('selected');
        }

        this._updateSentenceBuilder();
        this._updateCastButton();
    }

    _updateSentenceBuilder() {
        const container = document.getElementById('current-sentence');
        const sentence = this._buildSentenceFromWords(this._selectedWords);
        container.textContent = sentence;
    }

    _buildSentenceFromWords(words) {
        let sentence = '';
        for (let i = 0; i < words.length; i++) {
            const wordText = typeof words[i] === 'string' ? words[i] : words[i].word;
            const isPunctuation = ['.', '!', '?', ',', ';', ':'].includes(wordText);

            if (i === 0) {
                sentence = wordText;
            } else if (isPunctuation) {
                sentence += wordText; // No space before punctuation
            } else {
                sentence += ' ' + wordText; // Space before regular words
            }
        }
        return sentence;
    }

    _updateCastButton() {
        const button = document.getElementById('cast-button');
        button.disabled = false;

        if (this._selectedSpell) {
            button.textContent = `🔥 CAST ${this._selectedSpell.name.toUpperCase()} 🔥`;
        } else {
            button.textContent = '🔥 CAST SPELL 🔥';
        }
    }

    _castSpell() {
        if (!this._selectedSpell) {
            this._showFailEffect('noSpell');
            return;
        }

        // Disable cast button immediately to prevent spam clicking
        const castButton = document.getElementById('cast-button');
        if (castButton) {
            castButton.disabled = true;
        }

        // Check if spell is correctly formed
        const expectedSentence = this._selectedSpell.english;
        const playerSentence = this._buildSentenceFromWords(this._selectedWords);
        const isCorrect = playerSentence === expectedSentence;

        if (isCorrect) {
            // Capture spell data before it gets reset by _generateNewSpells()
            const spellType = this._selectedSpell.type;
            const spellDamage = this._selectedSpell.damage;
            const spellData = { ...this._selectedSpell };

            // Successful cast!
            this._showCastingEffect(spellType);

            setTimeout(() => {
                this._showSpellEffect(spellType);
            }, 500);

            // Deal damage
            this._enemyHP = Math.max(0, this._enemyHP - spellDamage);
            this._updateEnemyHealth();
            this._showDamageNumber(spellDamage);

            // Calculate DPS based on speed
            let dpsEarned = spellDamage;
            if (this._spellStartTime) {
                const spellTime = (Date.now() - this._spellStartTime) / 1000;
                this._spellCount++;
                this._averageSpellTime = ((this._averageSpellTime * (this._spellCount - 1)) + spellTime) / this._spellCount;

                // Time-based DPS multiplier
                if (spellTime < 3) {
                    dpsEarned = Math.floor(spellDamage * 2.5); // CRITICAL HIT! 250%
                    this._showTimingFeedback('🔥 CRITICAL! 250% DPS!', '#ff0000');
                } else if (spellTime < 5) {
                    dpsEarned = Math.floor(spellDamage * 2.0); // EXCELLENT! 200%
                    this._showTimingFeedback('⚡ EXCELLENT! 200% DPS!', '#ff6600');
                } else if (spellTime < 8) {
                    dpsEarned = Math.floor(spellDamage * 1.5); // GOOD! 150%
                    this._showTimingFeedback('✨ GOOD! 150% DPS!', '#ffaa00');
                } else if (spellTime < 12) {
                    dpsEarned = spellDamage; // Normal damage
                    this._showTimingFeedback('👍 Normal DPS', '#ffff00');
                } else {
                    dpsEarned = Math.floor(spellDamage * 0.5); // SLOW! 50%
                    this._showTimingFeedback('🐌 TOO SLOW! 50% DPS', '#888888');
                }
            }

            // Add DPS to current team
            if (this._currentTeam === 'red') {
                this._redTeamDPS += dpsEarned;
                document.getElementById('red-team-dps').textContent = this._redTeamDPS;
            } else {
                this._blueTeamDPS += dpsEarned;
                document.getElementById('blue-team-dps').textContent = this._blueTeamDPS;
            }

            // Emit spell cast event
            this._eventBus.emit('team-wizard-battle:spell-cast', {
                gameId: 'team-wizard-battle',
                instanceId: this.name,
                spell: spellData,
                damage: spellDamage,
                dpsEarned,
                team: this._currentTeam,
                redDPS: this._redTeamDPS,
                blueDPS: this._blueTeamDPS
            }, this.name);

            // Check win/end condition
            if (this._enemyHP <= 0 || this._currentRound > this._config.maxRounds) {
                this._handleVictory();
                return;
            }

            // Switch teams and increment round if needed
            setTimeout(() => {
                this._switchTeam();
                this._generateNewSpells();
                this._spellStartTime = Date.now();
            }, 1500);
        } else {
            // Spell failed! Re-enable button after fail animation
            this._showFailEffect();
            setTimeout(() => {
                if (castButton) {
                    castButton.disabled = false;
                }
            }, 500);
        }
    }

    _showSpellEffect(type) {
        const enemyChar = document.querySelector('.enemy-character');
        if (!enemyChar) {
            console.warn('Enemy character not found, skipping spell effect');
            return;
        }
        const rect = enemyChar.getBoundingClientRect();

        // Special animations for different spell types
        if (type === 'short' || type === 'fire') {
            this._launchFireball(rect);
        } else if (type === 'medium' || type === 'lightning') {
            this._launchLightning(rect);
        } else if (type === 'long' || type === 'meteor') {
            this._launchMeteor(rect);
        } else {
            // Main spell effect for other types
            const effect = document.createElement('div');
            effect.className = `spell-effect ${type}-effect`;
            effect.style.position = 'fixed';
            effect.style.left = rect.left + rect.width/2 - 50 + 'px';
            effect.style.top = rect.top + rect.height/2 - 50 + 'px';
            document.body.appendChild(effect);

            setTimeout(() => {
                effect.remove();
            }, 800);
        }

        // Enhanced effects based on spell type
        this._createSpellParticles(type, rect);
        this._triggerSpellAnimation(type, enemyChar);
    }

    _launchFireball(targetRect) {
        const wizardChar = document.querySelector('.wizard-character');
        const wizardRect = wizardChar.getBoundingClientRect();

        // Create fireball
        const fireball = document.createElement('div');
        fireball.className = 'fireball-projectile';

        const startX = wizardRect.left + wizardRect.width / 2 - 30;
        const startY = wizardRect.top + wizardRect.height / 2 - 30;
        const endX = targetRect.left + targetRect.width / 2 - 30;
        const endY = targetRect.top + targetRect.height / 2 - 30;

        fireball.style.left = startX + 'px';
        fireball.style.top = startY + 'px';

        document.body.appendChild(fireball);

        // Animation parameters
        const duration = 500; // milliseconds
        const startTime = Date.now();
        const trailInterval = 30; // Create trail every 30ms
        let lastTrailTime = 0;

        const animate = () => {
            const elapsed = Date.now() - startTime;
            const progress = Math.min(elapsed / duration, 1);

            // Easing function (ease-in-out)
            const eased = progress < 0.5
                ? 2 * progress * progress
                : -1 + (4 - 2 * progress) * progress;

            // Calculate current position
            const currentX = startX + (endX - startX) * eased;
            const currentY = startY + (endY - startY) * eased;

            fireball.style.left = currentX + 'px';
            fireball.style.top = currentY + 'px';

            // Create trail effect
            if (elapsed - lastTrailTime > trailInterval) {
                this._createFireballTrail(currentX + 30, currentY + 30);
                this._createFireballSparks(currentX + 30, currentY + 30);
                lastTrailTime = elapsed;
            }

            // Continue animation or finish
            if (progress < 1) {
                requestAnimationFrame(animate);
            } else {
                // Impact effect
                fireball.remove();
                this._createFireballImpact(endX + 30, endY + 30);
            }
        };

        animate();
    }

    _createFireballTrail(x, y) {
        const trail = document.createElement('div');
        trail.className = 'fireball-trail';
        trail.style.left = (x - 20) + 'px';
        trail.style.top = (y - 20) + 'px';
        document.body.appendChild(trail);

        setTimeout(() => trail.remove(), 500);
    }

    _createFireballSparks(x, y) {
        const sparkCount = 3;
        for (let i = 0; i < sparkCount; i++) {
            const spark = document.createElement('div');
            spark.className = 'fireball-spark';

            const angle = Math.random() * Math.PI * 2;
            const distance = 20 + Math.random() * 30;
            const sparkX = x + Math.cos(angle) * distance;
            const sparkY = y + Math.sin(angle) * distance;

            spark.style.left = sparkX + 'px';
            spark.style.top = sparkY + 'px';

            document.body.appendChild(spark);

            // Animate spark
            const duration = 300 + Math.random() * 200;
            const startTime = Date.now();
            const startSparkX = sparkX;
            const startSparkY = sparkY;
            const velocityX = (Math.random() - 0.5) * 100;
            const velocityY = Math.random() * 50 - 100;

            const animateSpark = () => {
                const elapsed = Date.now() - startTime;
                const progress = elapsed / duration;

                if (progress < 1) {
                    const newX = startSparkX + velocityX * progress;
                    const newY = startSparkY + velocityY * progress + (progress * progress * 100);
                    spark.style.left = newX + 'px';
                    spark.style.top = newY + 'px';
                    spark.style.opacity = 1 - progress;
                    requestAnimationFrame(animateSpark);
                } else {
                    spark.remove();
                }
            };

            animateSpark();
        }
    }

    _createFireballImpact(x, y) {
        // Main explosion
        const explosion = document.createElement('div');
        explosion.className = 'spell-effect fire-effect';
        explosion.style.position = 'fixed';
        explosion.style.left = (x - 50) + 'px';
        explosion.style.top = (y - 50) + 'px';
        document.body.appendChild(explosion);

        setTimeout(() => explosion.remove(), 800);

        // Impact sparks
        const impactSparkCount = 12;
        for (let i = 0; i < impactSparkCount; i++) {
            const angle = (i / impactSparkCount) * Math.PI * 2;
            const spark = document.createElement('div');
            spark.className = 'fireball-spark';
            spark.style.left = x + 'px';
            spark.style.top = y + 'px';
            spark.style.width = '12px';
            spark.style.height = '12px';

            document.body.appendChild(spark);

            const distance = 60 + Math.random() * 40;
            const duration = 400;
            const startTime = Date.now();

            const animateImpactSpark = () => {
                const elapsed = Date.now() - startTime;
                const progress = elapsed / duration;

                if (progress < 1) {
                    const currentDistance = distance * progress;
                    const newX = x + Math.cos(angle) * currentDistance;
                    const newY = y + Math.sin(angle) * currentDistance;
                    spark.style.left = newX + 'px';
                    spark.style.top = newY + 'px';
                    spark.style.opacity = 1 - progress;
                    spark.style.transform = `scale(${1 - progress * 0.5})`;
                    requestAnimationFrame(animateImpactSpark);
                } else {
                    spark.remove();
                }
            };

            animateImpactSpark();
        }
    }

    _launchLightning(targetRect) {
        const wizardChar = document.querySelector('.wizard-character');
        const wizardRect = wizardChar.getBoundingClientRect();

        const startX = wizardRect.left + wizardRect.width / 2;
        const startY = wizardRect.top + wizardRect.height / 2;
        const endX = targetRect.left + targetRect.width / 2;
        const endY = targetRect.top + targetRect.height / 2;

        // Screen flash
        const flash = document.createElement('div');
        flash.className = 'lightning-flash';
        document.body.appendChild(flash);
        setTimeout(() => flash.remove(), 300);

        // Create lightning bolt with jagged segments
        const boltContainer = document.createElement('div');
        boltContainer.className = 'lightning-bolt';
        document.body.appendChild(boltContainer);

        const segments = 8;
        const points = [{ x: startX, y: startY }];

        // Generate jagged lightning path
        for (let i = 1; i < segments; i++) {
            const progress = i / segments;
            const baseX = startX + (endX - startX) * progress;
            const baseY = startY + (endY - startY) * progress;

            // Add random offset for jagged effect
            const offsetX = (Math.random() - 0.5) * 60;
            const offsetY = (Math.random() - 0.5) * 60;

            points.push({
                x: baseX + offsetX,
                y: baseY + offsetY
            });
        }

        points.push({ x: endX, y: endY });

        // Draw lightning segments
        for (let i = 0; i < points.length - 1; i++) {
            const segment = document.createElement('div');
            segment.className = 'lightning-segment';

            const dx = points[i + 1].x - points[i].x;
            const dy = points[i + 1].y - points[i].y;
            const length = Math.sqrt(dx * dx + dy * dy);
            const angle = Math.atan2(dy, dx) * (180 / Math.PI);

            segment.style.left = points[i].x + 'px';
            segment.style.top = points[i].y + 'px';
            segment.style.width = length + 'px';
            segment.style.height = (3 + Math.random() * 3) + 'px';
            segment.style.transform = `rotate(${angle}deg)`;

            boltContainer.appendChild(segment);
        }

        // Create electric sparks along the path
        for (let i = 0; i < 15; i++) {
            setTimeout(() => {
                const pointIndex = Math.floor(Math.random() * points.length);
                const point = points[pointIndex];
                this._createLightningSpark(point.x, point.y);
            }, i * 30);
        }

        // Remove lightning bolt after animation
        setTimeout(() => {
            boltContainer.remove();
        }, 400);

        // Impact effect
        setTimeout(() => {
            this._createLightningImpact(endX, endY);
        }, 200);
    }

    _createLightningSpark(x, y) {
        const spark = document.createElement('div');
        spark.className = 'lightning-spark';
        spark.style.left = x + 'px';
        spark.style.top = y + 'px';
        document.body.appendChild(spark);

        const angle = Math.random() * Math.PI * 2;
        const distance = 30 + Math.random() * 40;
        const duration = 300;
        const startTime = Date.now();

        const animate = () => {
            const elapsed = Date.now() - startTime;
            const progress = elapsed / duration;

            if (progress < 1) {
                const currentDist = distance * progress;
                const newX = x + Math.cos(angle) * currentDist;
                const newY = y + Math.sin(angle) * currentDist;
                spark.style.left = newX + 'px';
                spark.style.top = newY + 'px';
                spark.style.opacity = 1 - progress;
                requestAnimationFrame(animate);
            } else {
                spark.remove();
            }
        };

        animate();
    }

    _createLightningImpact(x, y) {
        // Main impact explosion
        const explosion = document.createElement('div');
        explosion.className = 'spell-effect lightning-effect';
        explosion.style.position = 'fixed';
        explosion.style.left = (x - 50) + 'px';
        explosion.style.top = (y - 50) + 'px';
        document.body.appendChild(explosion);

        setTimeout(() => explosion.remove(), 800);

        // Electric burst
        for (let i = 0; i < 20; i++) {
            const spark = document.createElement('div');
            spark.className = 'lightning-spark';
            const angle = (i / 20) * Math.PI * 2;
            const distance = 40 + Math.random() * 60;

            spark.style.left = x + 'px';
            spark.style.top = y + 'px';
            document.body.appendChild(spark);

            const duration = 400 + Math.random() * 200;
            const startTime = Date.now();

            const animate = () => {
                const elapsed = Date.now() - startTime;
                const progress = elapsed / duration;

                if (progress < 1) {
                    const currentDist = distance * progress;
                    const newX = x + Math.cos(angle) * currentDist;
                    const newY = y + Math.sin(angle) * currentDist;
                    spark.style.left = newX + 'px';
                    spark.style.top = newY + 'px';
                    spark.style.opacity = 1 - progress;
                    spark.style.transform = `scale(${1 - progress * 0.7})`;
                    requestAnimationFrame(animate);
                } else {
                    spark.remove();
                }
            };

            animate();
        }
    }

    _launchMeteor(targetRect) {
        // Create meteor starting from top of screen
        const meteor = document.createElement('div');
        meteor.className = 'meteor-projectile';

        // Random horizontal start position (from above the screen)
        const startX = targetRect.left + targetRect.width / 2 + (Math.random() - 0.5) * 300;
        const startY = -100; // Start above viewport
        const endX = targetRect.left + targetRect.width / 2 - 40;
        const endY = targetRect.top + targetRect.height / 2 - 40;

        meteor.style.left = startX + 'px';
        meteor.style.top = startY + 'px';

        document.body.appendChild(meteor);

        // Animation parameters
        const duration = 800; // milliseconds
        const startTime = Date.now();
        const trailInterval = 25;
        let lastTrailTime = 0;

        const animate = () => {
            const elapsed = Date.now() - startTime;
            const progress = Math.min(elapsed / duration, 1);

            // Accelerating fall (quadratic easing)
            const eased = progress * progress;

            // Calculate current position
            const currentX = startX + (endX - startX) * progress;
            const currentY = startY + (endY - startY) * eased;

            meteor.style.left = currentX + 'px';
            meteor.style.top = currentY + 'px';

            // Rotate meteor as it falls
            meteor.style.transform = `rotate(${progress * 360}deg) scale(${1 + progress * 0.5})`;

            // Create trail effect
            if (elapsed - lastTrailTime > trailInterval) {
                this._createMeteorTrail(currentX + 40, currentY + 40);
                this._createMeteorDebris(currentX + 40, currentY + 40);
                lastTrailTime = elapsed;
            }

            // Continue animation or finish
            if (progress < 1) {
                requestAnimationFrame(animate);
            } else {
                // Impact effect
                meteor.remove();
                this._createMeteorImpact(endX + 40, endY + 40);
            }
        };

        animate();
    }

    _createMeteorTrail(x, y) {
        const trail = document.createElement('div');
        trail.className = 'meteor-trail';
        trail.style.left = (x - 30) + 'px';
        trail.style.top = (y - 30) + 'px';
        document.body.appendChild(trail);

        setTimeout(() => trail.remove(), 600);
    }

    _createMeteorDebris(x, y) {
        const debrisCount = 2;
        for (let i = 0; i < debrisCount; i++) {
            const debris = document.createElement('div');
            debris.className = 'meteor-debris';

            // Debris flies off to the sides
            const angle = Math.PI / 2 + (Math.random() - 0.5) * Math.PI;
            const distance = 30 + Math.random() * 40;

            debris.style.left = x + 'px';
            debris.style.top = y + 'px';

            document.body.appendChild(debris);

            const duration = 400 + Math.random() * 200;
            const startTime = Date.now();

            const animateDebris = () => {
                const elapsed = Date.now() - startTime;
                const progress = elapsed / duration;

                if (progress < 1) {
                    const currentDist = distance * progress;
                    const newX = x + Math.cos(angle) * currentDist;
                    const newY = y + Math.sin(angle) * currentDist + (progress * progress * 80);
                    debris.style.left = newX + 'px';
                    debris.style.top = newY + 'px';
                    debris.style.opacity = 1 - progress;
                    debris.style.transform = `rotate(${progress * 720}deg) scale(${1 - progress})`;
                    requestAnimationFrame(animateDebris);
                } else {
                    debris.remove();
                }
            };

            animateDebris();
        }
    }

    _createMeteorImpact(x, y) {
        // Screen shake on impact
        document.body.classList.add('screen-shake');
        setTimeout(() => document.body.classList.remove('screen-shake'), 500);

        // Main explosion crater effect
        const explosion = document.createElement('div');
        explosion.className = 'spell-effect meteor-effect';
        explosion.style.position = 'fixed';
        explosion.style.left = (x - 50) + 'px';
        explosion.style.top = (y - 50) + 'px';
        document.body.appendChild(explosion);

        setTimeout(() => explosion.remove(), 800);

        // Shockwave rings
        for (let i = 0; i < 3; i++) {
            setTimeout(() => {
                const shockwave = document.createElement('div');
                shockwave.className = 'meteor-shockwave';
                shockwave.style.left = x + 'px';
                shockwave.style.top = y + 'px';
                document.body.appendChild(shockwave);

                setTimeout(() => shockwave.remove(), 800);
            }, i * 100);
        }

        // Impact debris explosion
        const debrisCount = 20;
        for (let i = 0; i < debrisCount; i++) {
            const debris = document.createElement('div');
            debris.className = 'meteor-debris';
            const angle = (i / debrisCount) * Math.PI * 2;
            const distance = 50 + Math.random() * 80;

            debris.style.left = x + 'px';
            debris.style.top = y + 'px';
            debris.style.width = (6 + Math.random() * 8) + 'px';
            debris.style.height = (6 + Math.random() * 8) + 'px';

            document.body.appendChild(debris);

            const duration = 600 + Math.random() * 400;
            const startTime = Date.now();

            const animate = () => {
                const elapsed = Date.now() - startTime;
                const progress = elapsed / duration;

                if (progress < 1) {
                    const currentDist = distance * progress;
                    const newX = x + Math.cos(angle) * currentDist;
                    const newY = y + Math.sin(angle) * currentDist - (50 * progress) + (progress * progress * 100);
                    debris.style.left = newX + 'px';
                    debris.style.top = newY + 'px';
                    debris.style.opacity = 1 - progress;
                    debris.style.transform = `rotate(${progress * 1080}deg) scale(${1 - progress * 0.5})`;
                    requestAnimationFrame(animate);
                } else {
                    debris.remove();
                }
            };

            animate();
        }

        // Purple impact sparks
        for (let i = 0; i < 12; i++) {
            const spark = document.createElement('div');
            spark.className = 'meteor-spark';
            const angle = (i / 12) * Math.PI * 2;
            const distance = 60 + Math.random() * 50;

            spark.style.left = x + 'px';
            spark.style.top = y + 'px';

            document.body.appendChild(spark);

            const duration = 500;
            const startTime = Date.now();

            const animate = () => {
                const elapsed = Date.now() - startTime;
                const progress = elapsed / duration;

                if (progress < 1) {
                    const currentDist = distance * (1 - Math.pow(1 - progress, 3));
                    const newX = x + Math.cos(angle) * currentDist;
                    const newY = y + Math.sin(angle) * currentDist;
                    spark.style.left = newX + 'px';
                    spark.style.top = newY + 'px';
                    spark.style.opacity = 1 - progress;
                    spark.style.transform = `scale(${1 - progress * 0.8})`;
                    requestAnimationFrame(animate);
                } else {
                    spark.remove();
                }
            };

            animate();
        }
    }

    _createSpellParticles(type, enemyRect) {
        const particleCount = type === 'meteor' ? 15 : type === 'lightning' ? 12 : 8;

        for (let i = 0; i < particleCount; i++) {
            const particle = document.createElement('div');
            particle.className = `spell-particle ${type}-particle`;

            const offsetX = (Math.random() - 0.5) * 200;
            const offsetY = (Math.random() - 0.5) * 200;

            particle.style.position = 'fixed';
            particle.style.left = enemyRect.left + enemyRect.width/2 + offsetX + 'px';
            particle.style.top = enemyRect.top + enemyRect.height/2 + offsetY + 'px';
            particle.style.width = '6px';
            particle.style.height = '6px';
            particle.style.borderRadius = '50%';
            particle.style.pointerEvents = 'none';
            particle.style.zIndex = '1000';

            if (type === 'fire') {
                particle.style.background = 'radial-gradient(circle, #ff6b7a, #ff4757)';
                particle.style.boxShadow = '0 0 10px #ff4757';
            } else if (type === 'lightning') {
                particle.style.background = 'radial-gradient(circle, #ffd700, #ffed4e)';
                particle.style.boxShadow = '0 0 15px #ffd700';
            } else if (type === 'meteor') {
                particle.style.background = 'radial-gradient(circle, #a29bfe, #6c5ce7)';
                particle.style.boxShadow = '0 0 20px #6c5ce7';
            }

            document.body.appendChild(particle);

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

    _triggerSpellAnimation(type, enemyChar) {
        if (type === 'meteor') {
            document.body.classList.add('screen-shake');
            setTimeout(() => document.body.classList.remove('screen-shake'), 500);
        }

        // Enemy hit reaction
        enemyChar.style.transform = 'scale(1.1)';
        enemyChar.style.filter = type === 'fire' ? 'hue-rotate(30deg)' :
                                 type === 'lightning' ? 'brightness(1.5)' :
                                 'contrast(1.3)';

        setTimeout(() => {
            enemyChar.style.transform = '';
            enemyChar.style.filter = '';
        }, 300);
    }

    _showCastingEffect(spellType) {
        const wizardChar = document.querySelector('.wizard-character');

        // Wizard glow effect
        wizardChar.style.filter = 'drop-shadow(0 0 20px #ffd700)';
        wizardChar.style.transform = 'scale(1.05)';

        setTimeout(() => {
            wizardChar.style.filter = '';
            wizardChar.style.transform = '';
        }, 600);
    }

    _showDamageNumber(damage) {
        const damageEl = document.createElement('div');
        damageEl.className = 'damage-number';
        damageEl.textContent = `-${damage}`;

        const enemyChar = document.querySelector('.enemy-character');
        const rect = enemyChar.getBoundingClientRect();

        damageEl.style.position = 'fixed';
        damageEl.style.left = rect.left + rect.width/2 + 'px';
        damageEl.style.top = rect.top + 'px';

        document.body.appendChild(damageEl);

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

    _showTimingFeedback(message, color) {
        const feedbackEl = document.createElement('div');
        feedbackEl.style.position = 'fixed';
        feedbackEl.style.top = '50%';
        feedbackEl.style.left = '50%';
        feedbackEl.style.transform = 'translate(-50%, -50%)';
        feedbackEl.style.fontSize = '2em';
        feedbackEl.style.fontWeight = 'bold';
        feedbackEl.style.color = color;
        feedbackEl.style.textShadow = '2px 2px 4px rgba(0,0,0,0.8)';
        feedbackEl.style.zIndex = '10000';
        feedbackEl.style.pointerEvents = 'none';
        feedbackEl.textContent = message;

        document.body.appendChild(feedbackEl);

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

    _showTeamSwitchPopup() {
        const popup = document.createElement('div');
        popup.style.position = 'fixed';
        popup.style.top = '50%';
        popup.style.left = '50%';
        popup.style.transform = 'translate(-50%, -50%) scale(0)';
        popup.style.background = 'rgba(0, 0, 0, 0.9)';
        popup.style.padding = '40px 60px';
        popup.style.borderRadius = '20px';
        popup.style.border = `4px solid ${this._currentTeam === 'red' ? '#ff6666' : '#66b3ff'}`;
        popup.style.boxShadow = `0 0 30px ${this._currentTeam === 'red' ? '#ff6666' : '#66b3ff'}`;
        popup.style.zIndex = '10000';
        popup.style.pointerEvents = 'none';
        popup.style.transition = 'transform 0.3s ease-out';
        popup.innerHTML = `
            <div style="font-size: 3em; text-align: center;">
                ${this._currentTeam === 'red' ? '👸' : '🧙‍♂️'}
            </div>
            <div style="font-size: 2em; font-weight: bold; color: ${this._currentTeam === 'red' ? '#ff6666' : '#66b3ff'}; text-align: center; margin-top: 10px;">
                ${this._currentTeam === 'red' ? '🔴 RED TEAM' : '🔵 BLUE TEAM'}
            </div>
            <div style="font-size: 1.5em; color: #ffd700; text-align: center; margin-top: 10px;">
                YOUR TURN!
            </div>
        `;

        document.body.appendChild(popup);

        // Animate in
        setTimeout(() => {
            popup.style.transform = 'translate(-50%, -50%) scale(1)';
        }, 10);

        // Animate out and remove
        setTimeout(() => {
            popup.style.transform = 'translate(-50%, -50%) scale(0)';
            setTimeout(() => {
                popup.remove();
            }, 300);
        }, 1200);
    }

    _switchTeam() {
        // Switch to other team
        this._currentTeam = this._currentTeam === 'red' ? 'blue' : 'red';

        // Update round counter when blue team finishes (full cycle complete)
        if (this._currentTeam === 'red') {
            this._currentRound++;
            const roundEl = document.getElementById('current-round');
            if (roundEl) {
                roundEl.textContent = this._currentRound;
            }
        }

        // Show team switch popup
        this._showTeamSwitchPopup();

        // Update turn display
        const teamDisplay = document.getElementById('current-team-display');
        if (teamDisplay) {
            if (this._currentTeam === 'red') {
                teamDisplay.textContent = '🔴 RED TEAM TURN';
                teamDisplay.style.color = '#ff6666';
            } else {
                teamDisplay.textContent = '🔵 BLUE TEAM TURN';
                teamDisplay.style.color = '#66b3ff';
            }
        }

        // Update player character
        const playerChar = document.getElementById('current-player-character');
        const playerName = document.getElementById('current-player-name');
        if (playerChar && playerName) {
            if (this._currentTeam === 'red') {
                playerChar.textContent = '👸';
                playerChar.style.color = '#ff6666';
                playerName.textContent = 'Red Princess';
                playerName.style.color = '#ff6666';
            } else {
                playerChar.textContent = '🧙‍♂️';
                playerChar.style.color = '#66b3ff';
                playerName.textContent = 'Blue Wizard';
                playerName.style.color = '#66b3ff';
            }
        }
    }

    _showFailEffect(type = 'random') {
        const effects = ['spawnMinion', 'loseHP', 'magicQuirk', 'flyingBirds'];
        const selectedEffect = type === 'random' ?
            effects[Math.floor(Math.random() * effects.length)] :
            type;

        this._showFailMessage();

        switch(selectedEffect) {
            case 'spawnMinion':
                this._spawnMiniEnemy();
                break;
            case 'loseHP':
                this._wizardTakesDamage();
                break;
            case 'magicQuirk':
                this._triggerMagicQuirk();
                break;
            case 'flyingBirds':
                this._summonFlyingBirds();
                break;
            case 'noSpell':
                this._showFailMessage('Select a spell first! 🪄');
                break;
        }
    }

    _showFailMessage(customMessage = null) {
        const messages = [
            "Spell backfired! 💥",
            "Magic went wrong! 🌀",
            "Oops! Wrong incantation! 😅",
            "The magic gods are not pleased! ⚡",
            "Your spell turned into chaos! 🎭",
            "Magic malfunction detected! 🔧"
        ];

        const message = customMessage || messages[Math.floor(Math.random() * messages.length)];

        const failEl = document.createElement('div');
        failEl.className = 'fail-message';
        failEl.textContent = message;

        document.body.appendChild(failEl);

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

    _spawnMiniEnemy() {
        const miniEnemy = document.createElement('div');
        miniEnemy.className = 'mini-enemy';
        miniEnemy.textContent = '👺';

        const mainEnemy = document.querySelector('.enemy-character');
        const rect = mainEnemy.getBoundingClientRect();

        miniEnemy.style.position = 'fixed';
        miniEnemy.style.left = (rect.left + Math.random() * 200 - 100) + 'px';
        miniEnemy.style.top = (rect.top + Math.random() * 200 - 100) + 'px';

        document.body.appendChild(miniEnemy);

        setTimeout(() => {
            miniEnemy.remove();
        }, 5000);

        this._enemyHP = Math.min(this._config.maxEnemyHP, this._enemyHP + 5);
        this._updateEnemyHealth();
    }

    _wizardTakesDamage() {
        this._playerHP = Math.max(0, this._playerHP - 10);
        const playerHealthEl = document.getElementById('player-health');
        if (playerHealthEl) {
            playerHealthEl.style.width = this._playerHP + '%';
        }

        document.body.classList.add('screen-shake');
        setTimeout(() => {
            document.body.classList.remove('screen-shake');
        }, 500);

        const damageEl = document.createElement('div');
        damageEl.className = 'damage-number';
        damageEl.textContent = '-10';
        damageEl.style.color = '#ff4757';

        const wizardChar = document.querySelector('.wizard-character');
        if (!wizardChar) {
            console.warn('Wizard character not found, skipping damage display');
            return;
        }
        const rect = wizardChar.getBoundingClientRect();

        damageEl.style.position = 'fixed';
        damageEl.style.left = rect.left + rect.width/2 + 'px';
        damageEl.style.top = rect.top + 'px';

        document.body.appendChild(damageEl);

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

        if (this._playerHP <= 0) {
            setTimeout(() => {
                this._handleDefeat();
            }, 1000);
        }
    }

    _triggerMagicQuirk() {
        const numQuirks = 2 + Math.floor(Math.random() * 2);

        for (let i = 0; i < numQuirks; i++) {
            setTimeout(() => {
                const quirk = document.createElement('div');
                quirk.className = 'magic-quirk';

                const x = 20 + Math.random() * 60;
                const y = 20 + Math.random() * 60;

                quirk.style.left = x + '%';
                quirk.style.top = y + '%';
                quirk.style.transform = 'translate(-50%, -50%)';

                document.body.appendChild(quirk);

                setTimeout(() => {
                    quirk.remove();
                }, 2000);
            }, i * 300);
        }

        setTimeout(() => {
            this._updateWordBank();
        }, 1000);
    }

    _summonFlyingBirds() {
        const birds = ['🐦', '🕊️', '🦅', '🦜', '🐧', '🦆', '🦢', '🐓', '🦃', '🦚'];
        const paths = ['bird-path-1', 'bird-path-2', 'bird-path-3'];
        const numBirds = 3 + Math.floor(Math.random() * 2);

        for (let i = 0; i < numBirds; i++) {
            setTimeout(() => {
                const bird = document.createElement('div');
                const pathClass = paths[i % paths.length];
                bird.className = `flying-bird ${pathClass}`;
                bird.textContent = birds[Math.floor(Math.random() * birds.length)];

                document.body.appendChild(bird);

                setTimeout(() => {
                    bird.remove();
                }, 15000);

            }, i * 500);
        }
    }

    _updateEnemyHealth() {
        const healthBar = document.getElementById('enemy-health');
        const percentage = (this._enemyHP / this._config.maxEnemyHP) * 100;
        healthBar.style.width = percentage + '%';
    }

    _getRandomAttackTime() {
        return this._config.enemyAttackInterval.min +
               Math.random() * (this._config.enemyAttackInterval.max - this._config.enemyAttackInterval.min);
    }

    _startEnemyAttackSystem() {
        // DISABLED for team battle mode - no enemy attacks, just DPS race!
        // this._scheduleNextEnemyAttack();
    }

    _scheduleNextEnemyAttack() {
        this._enemyAttackTimer = setTimeout(() => {
            this._executeEnemyAttack();
            this._scheduleNextEnemyAttack();
        }, this._getRandomAttackTime());
    }

    _executeEnemyAttack() {
        const enemyChar = document.querySelector('.enemy-character');

        this._showEnemyAttackWarning();
        enemyChar.classList.add('enemy-charging');

        setTimeout(() => {
            enemyChar.classList.remove('enemy-charging');
            this._dealEnemyDamage();
            this._showEnemyAttackEffect();
        }, 2000);
    }

    _showEnemyAttackWarning() {
        const enemyChar = document.querySelector('.enemy-character');

        const existingWarning = enemyChar.querySelector('.enemy-attack-warning');
        if (existingWarning) {
            existingWarning.remove();
        }

        const warning = document.createElement('div');
        warning.className = 'enemy-attack-warning';
        warning.textContent = '⚠️ INCOMING ATTACK!';

        enemyChar.style.position = 'relative';
        enemyChar.appendChild(warning);

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

    _dealEnemyDamage() {
        const damage = this._config.enemyDamage.min +
                      Math.floor(Math.random() * (this._config.enemyDamage.max - this._config.enemyDamage.min + 1));

        this._playerHP = Math.max(0, this._playerHP - damage);
        const playerHealthEl = document.getElementById('player-health');
        if (playerHealthEl) {
            playerHealthEl.style.width = this._playerHP + '%';
        }

        document.body.classList.add('screen-shake');
        setTimeout(() => {
            document.body.classList.remove('screen-shake');
        }, 500);

        const damageEl = document.createElement('div');
        damageEl.className = 'damage-number';
        damageEl.textContent = `-${damage}`;
        damageEl.style.color = '#ff4757';

        const wizardChar = document.querySelector('.wizard-character');
        if (!wizardChar) {
            console.warn('Wizard character not found, skipping damage display');
            return;
        }
        const rect = wizardChar.getBoundingClientRect();

        damageEl.style.position = 'fixed';
        damageEl.style.left = rect.left + rect.width/2 + 'px';
        damageEl.style.top = rect.top + 'px';

        document.body.appendChild(damageEl);

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

        // Emit enemy attack event
        this._eventBus.emit('wizard-spell-caster:enemy-attack', {
            gameId: 'wizard-spell-caster',
            instanceId: this.name,
            damage,
            playerHP: this._playerHP
        }, this.name);

        if (this._playerHP <= 0) {
            setTimeout(() => {
                this._handleDefeat();
            }, 1000);
        }
    }

    _showEnemyAttackEffect() {
        const effect = document.createElement('div');
        effect.className = 'enemy-attack-effect';

        const wizardChar = document.querySelector('.wizard-character');
        const rect = wizardChar.getBoundingClientRect();

        effect.style.position = 'fixed';
        effect.style.left = rect.left + rect.width/2 - 75 + 'px';
        effect.style.top = rect.top + rect.height/2 - 75 + 'px';

        document.body.appendChild(effect);

        setTimeout(() => {
            effect.remove();
        }, 1000);
    }

    _handleVictory() {
        if (this._enemyAttackTimer) {
            clearTimeout(this._enemyAttackTimer);
            this._enemyAttackTimer = null;
        }

        // Determine winning team
        const winningTeam = this._redTeamDPS > this._blueTeamDPS ? 'red' :
                           this._blueTeamDPS > this._redTeamDPS ? 'blue' : 'tie';

        let titleText = '🎉 BATTLE COMPLETE! 🎉';
        let winnerText = '';
        let titleColor = '#ffd700';

        if (winningTeam === 'red') {
            titleText = '🔴 RED TEAM WINS! 🔴';
            winnerText = 'Red Team dealt the most damage!';
            titleColor = '#ff6666';
        } else if (winningTeam === 'blue') {
            titleText = '🔵 BLUE TEAM WINS! 🔵';
            winnerText = 'Blue Team dealt the most damage!';
            titleColor = '#66b3ff';
        } else {
            titleText = '🤝 IT\'S A TIE! 🤝';
            winnerText = 'Both teams dealt equal damage!';
            titleColor = '#ffd700';
        }

        const victoryScreen = document.createElement('div');
        victoryScreen.className = 'victory-screen';
        victoryScreen.innerHTML = `
            <div class="result-title" style="color: ${titleColor};">${titleText}</div>
            <div style="font-size: 24px; margin-bottom: 20px;">${winnerText}</div>

            <div style="display: flex; justify-content: space-around; margin-bottom: 30px; gap: 40px;">
                <div style="flex: 1; text-align: center;">
                    <div style="color: #ff6666; font-size: 28px; font-weight: bold;">🔴 RED TEAM</div>
                    <div style="font-size: 48px; color: #ff6666; margin: 10px 0;">${this._redTeamDPS}</div>
                    <div style="font-size: 18px;">Total DPS</div>
                </div>

                <div style="font-size: 48px; color: #666;">VS</div>

                <div style="flex: 1; text-align: center;">
                    <div style="color: #66b3ff; font-size: 28px; font-weight: bold;">🔵 BLUE TEAM</div>
                    <div style="font-size: 48px; color: #66b3ff; margin: 10px 0;">${this._blueTeamDPS}</div>
                    <div style="font-size: 18px;">Total DPS</div>
                </div>
            </div>

            <div style="font-size: 16px; margin-bottom: 20px; color: #aaa;">
                Boss HP Remaining: ${this._enemyHP} / ${this._config.maxEnemyHP}<br>
                Rounds Played: ${this._currentRound - 1}
            </div>

            <div>
                <button class="game-result-btn victory" id="play-again-btn">🔄 Play Again</button>
                <button class="game-result-btn victory" id="exit-victory-btn">🏠 Back to Games</button>
            </div>
        `;

        this._config.container.appendChild(victoryScreen);

        // Add event listeners with spam-click protection
        const playAgainBtn = victoryScreen.querySelector('#play-again-btn');
        const exitBtn = victoryScreen.querySelector('#exit-victory-btn');

        playAgainBtn.addEventListener('click', () => {
            // Prevent spam clicking
            playAgainBtn.disabled = true;
            exitBtn.disabled = true;
            victoryScreen.remove();
            this._restartGame();
        }, { once: true }); // Execute only once

        exitBtn.addEventListener('click', () => {
            // Prevent spam clicking
            playAgainBtn.disabled = true;
            exitBtn.disabled = true;
            window.app.getCore().router.navigate('/games');
        }, { once: true }); // Execute only once

        // Emit victory event
        this._eventBus.emit('game:completed', {
            gameId: 'team-wizard-battle',
            instanceId: this.name,
            redTeamDPS: this._redTeamDPS,
            blueTeamDPS: this._blueTeamDPS,
            winningTeam,
            spellsCast: this._spellCount,
            duration: this._gameStartTime ? Date.now() - this._gameStartTime : 0
        }, this.name);
    }

    _handleDefeat() {
        if (this._enemyAttackTimer) {
            clearTimeout(this._enemyAttackTimer);
            this._enemyAttackTimer = null;
        }

        const defeatScreen = document.createElement('div');
        defeatScreen.className = 'defeat-screen';
        defeatScreen.innerHTML = `
            <div class="result-title">💀 DEFEATED 💀</div>
            <div style="font-size: 24px; margin-bottom: 10px;">The Grammar Demon proved too strong!</div>
            <div style="font-size: 18px; margin-bottom: 20px;">Final Score: ${this._score}</div>
            <div>
                <button class="game-result-btn defeat" id="try-again-btn">🔄 Try Again</button>
                <button class="game-result-btn defeat" id="exit-defeat-btn">🏠 Back to Games</button>
            </div>
        `;

        this._config.container.appendChild(defeatScreen);

        // Add event listeners
        defeatScreen.querySelector('#try-again-btn').addEventListener('click', () => {
            defeatScreen.remove();
            this._restartGame();
        });

        defeatScreen.querySelector('#exit-defeat-btn').addEventListener('click', () => {
            window.app.getCore().router.navigate('/games');
        });

        // Emit defeat event
        this._eventBus.emit('game:completed', {
            gameId: 'wizard-spell-caster',
            instanceId: this.name,
            score: this._score,
            result: 'defeat',
            spellsCast: this._spellCount,
            duration: this._gameStartTime ? Date.now() - this._gameStartTime : 0
        }, this.name);
    }

    _restartGame() {
        // Reset game state
        this._score = 0;
        this._enemyHP = this._config.maxEnemyHP;
        this._playerHP = this._config.maxPlayerHP;
        this._spellStartTime = Date.now();
        this._averageSpellTime = 0;
        this._spellCount = 0;
        this._selectedSpell = null;
        this._selectedWords = [];

        // Reset team battle state
        this._redTeamDPS = 0;
        this._blueTeamDPS = 0;
        this._currentTeam = 'red';
        this._currentRound = 1;

        // Update UI
        const redDPSEl = document.getElementById('red-team-dps');
        if (redDPSEl) {
            redDPSEl.textContent = this._redTeamDPS;
        }
        const blueDPSEl = document.getElementById('blue-team-dps');
        if (blueDPSEl) {
            blueDPSEl.textContent = this._blueTeamDPS;
        }
        const roundEl = document.getElementById('current-round');
        if (roundEl) {
            roundEl.textContent = this._currentRound;
        }
        const teamDisplay = document.getElementById('current-team-display');
        if (teamDisplay) {
            teamDisplay.textContent = '🔴 RED TEAM TURN';
            teamDisplay.style.color = '#ff6666';
        }

        // Reset player character to Red Princess
        const playerChar = document.getElementById('current-player-character');
        const playerName = document.getElementById('current-player-name');
        if (playerChar && playerName) {
            playerChar.textContent = '👸';
            playerChar.style.color = '#ff6666';
            playerName.textContent = 'Red Princess';
            playerName.style.color = '#ff6666';
        }

        const enemyHealthEl = document.getElementById('enemy-health');
        if (enemyHealthEl) {
            enemyHealthEl.style.width = '100%';
        }

        // Restart enemy attacks
        this._startEnemyAttackSystem();

        // Generate new spells
        this._generateNewSpells();
    }

    _showError(message) {
        if (this._config.container) {
            this._config.container.innerHTML = `
                <div class="game-error">
                    <h3>❌ Team Wizard Battle Error</h3>
                    <p>${message}</p>
                    <p>This game requires sentences for team spell construction battle.</p>
                    <button class="back-btn" onclick="history.back()">← Go Back</button>
                </div>
            `;
        }
    }

    _handlePause() {
        if (this._enemyAttackTimer) {
            clearTimeout(this._enemyAttackTimer);
            this._enemyAttackTimer = null;
        }
        this._eventBus.emit('game:paused', { instanceId: this.name }, this.name);
    }

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

export default TeamWizardBattle;