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

class FillTheBlank extends Module {
    constructor(name, dependencies, config = {}) {
        super(name, ['eventBus']);

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

        this._eventBus = dependencies.eventBus;
        this._content = dependencies.content;
        this._config = {
            container: null,
            difficulty: 'medium',
            maxSentences: 20,
            ...config
        };

        this._score = 0;
        this._errors = 0;
        this._currentSentenceIndex = 0;
        this._isRunning = false;
        this._vocabulary = [];
        this._sentences = [];
        this._currentSentence = null;
        this._blanks = [];
        this._userAnswers = [];
        this._gameContainer = null;

        Object.seal(this);
    }

    static getMetadata() {
        return {
            id: 'fill-the-blank',
            name: 'Fill the Blank',
            description: 'Complete sentences by filling in missing words',
            version: '2.0.0',
            author: 'Class Generator',
            category: 'vocabulary',
            tags: ['vocabulary', 'sentences', 'completion', 'learning'],
            difficulty: {
                min: 1,
                max: 4,
                default: 2
            },
            estimatedDuration: 10,
            requiredContent: ['vocabulary', 'sentences']
        };
    }

    static getCompatibilityScore(content) {
        if (!content) {
            return 0;
        }

        let score = 0;

        const hasVocabulary = content.vocabulary && (
            typeof content.vocabulary === 'object' ||
            Array.isArray(content.vocabulary)
        );
        const hasSentences = content.sentences ||
                           content.story?.chapters ||
                           content.fillInBlanks;

        if (hasVocabulary) score += 40;
        if (hasSentences) score += 40;

        if (content.vocabulary && typeof content.vocabulary === 'object') {
            const vocabCount = Object.keys(content.vocabulary).length;
            if (vocabCount >= 10) score += 10;
            if (vocabCount >= 20) score += 5;
        }

        if (content.sentences && Array.isArray(content.sentences)) {
            const sentenceCount = content.sentences.length;
            if (sentenceCount >= 5) score += 5;
            if (sentenceCount >= 10) score += 5;
        }

        return Math.min(score, 100);
    }

    async init() {
        this._validateNotDestroyed();

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

        this._eventBus.on('game:start', this._handleGameStart.bind(this), this.name);
        this._eventBus.on('game:stop', this._handleGameStop.bind(this), this.name);
        this._eventBus.on('navigation:change', this._handleNavigationChange.bind(this), this.name);

        this._injectCSS();

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

            if (!content) {
                throw new Error('No content available');
            }

            this._extractVocabulary(content);
            this._extractSentences(content);

            if (this._vocabulary.length === 0) {
                throw new Error('No vocabulary found for Fill the Blank');
            }

            if (this._sentences.length === 0) {
                throw new Error('No sentences found for Fill the Blank');
            }

            this._createGameBoard();
            this._setupEventListeners();
            this._loadNextSentence();

            // Emit game ready event
            this._eventBus.emit('game:ready', {
                gameId: 'fill-the-blank',
                instanceId: this.name,
                vocabulary: this._vocabulary.length,
                sentences: this._sentences.length
            }, this.name);

        } catch (error) {
            console.error('Error starting Fill the Blank:', error);
            this._showInitError(error.message);
        }

        this._setInitialized();
    }

    async destroy() {
        this._validateNotDestroyed();

        this._cleanup();
        this._removeCSS();
        this._eventBus.off('game:start', this.name);
        this._eventBus.off('game:stop', this.name);
        this._eventBus.off('navigation:change', this.name);

        this._setDestroyed();
    }

    _handleGameStart(event) {
        this._validateInitialized();
        if (event.gameId === 'fill-the-blank') {
            this._startGame();
        }
    }

    _handleGameStop(event) {
        this._validateInitialized();
        if (event.gameId === 'fill-the-blank') {
            this._stopGame();
        }
    }

    _handleNavigationChange(event) {
        this._validateInitialized();
        if (event.from === '/games/fill-the-blank') {
            this._cleanup();
        }
    }

    async _startGame() {
        try {
            this._gameContainer = document.getElementById('game-content');
            if (!this._gameContainer) {
                throw new Error('Game container not found');
            }

            const content = await this._content.getCurrentContent();
            if (!content) {
                throw new Error('No content available');
            }

            this._extractVocabulary(content);
            this._extractSentences(content);

            if (this._vocabulary.length === 0) {
                throw new Error('No vocabulary found for Fill the Blank');
            }

            if (this._sentences.length === 0) {
                throw new Error('No sentences found for Fill the Blank');
            }

            this._createGameBoard();
            this._setupEventListeners();
            this._loadNextSentence();

        } catch (error) {
            console.error('Error starting Fill the Blank:', error);
            this._showInitError(error.message);
        }
    }

    _stopGame() {
        this._cleanup();
    }

    _cleanup() {
        this._isRunning = false;
        if (this._gameContainer) {
            this._gameContainer.innerHTML = '';
        }
    }

    _showInitError(message) {
        this._gameContainer.innerHTML = `
            <div class="game-error">
                <h3>❌ Loading Error</h3>
                <p>${message}</p>
                <p>The game requires vocabulary and sentences in compatible format.</p>
                <button onclick="window.app.getCore().router.navigate('/games')" class="back-btn">← Back to Games</button>
            </div>
        `;
    }

    _extractVocabulary(content) {
        this._vocabulary = [];

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

        this._vocabulary = this._vocabulary.filter(word =>
            word &&
            typeof word.original === 'string' &&
            typeof word.translation === 'string' &&
            word.original.trim() !== '' &&
            word.translation.trim() !== ''
        );

        if (this._vocabulary.length === 0) {
            this._vocabulary = [
                { original: 'hello', translation: 'bonjour', category: 'greetings' },
                { original: 'goodbye', translation: 'au revoir', category: 'greetings' },
                { original: 'thank you', translation: 'merci', category: 'greetings' },
                { original: 'cat', translation: 'chat', category: 'animals' },
                { original: 'dog', translation: 'chien', category: 'animals' },
                { original: 'house', translation: 'maison', category: 'objects' },
                { original: 'school', translation: 'école', category: 'places' },
                { original: 'book', translation: 'livre', category: 'objects' }
            ];
        }

        console.log(`Fill the Blank: ${this._vocabulary.length} words loaded`);
    }

    _extractSentences(content) {
        this._sentences = [];

        if (content.story?.chapters) {
            content.story.chapters.forEach(chapter => {
                if (chapter.sentences) {
                    chapter.sentences.forEach(sentence => {
                        if (sentence.original && sentence.translation) {
                            this._sentences.push({
                                original: sentence.original,
                                translation: sentence.translation,
                                source: 'story'
                            });
                        }
                    });
                }
            });
        }

        const directSentences = content.sentences;
        if (directSentences && Array.isArray(directSentences)) {
            directSentences.forEach(sentence => {
                if (sentence.english && sentence.chinese) {
                    this._sentences.push({
                        original: sentence.english,
                        translation: sentence.chinese,
                        source: 'sentences'
                    });
                } else if (sentence.original && sentence.translation) {
                    this._sentences.push({
                        original: sentence.original,
                        translation: sentence.translation,
                        source: 'sentences'
                    });
                }
            });
        }

        this._sentences = this._sentences.filter(sentence =>
            sentence.original &&
            sentence.original.split(' ').length >= 3 &&
            sentence.original.trim().length > 0
        );

        this._sentences = this._shuffleArray(this._sentences);

        if (this._sentences.length === 0) {
            this._sentences = this._createFallbackSentences();
        }

        this._sentences = this._sentences.slice(0, this._config.maxSentences);
        console.log(`Fill the Blank: ${this._sentences.length} sentences loaded`);
    }

    _createFallbackSentences() {
        const fallback = [];
        this._vocabulary.slice(0, 10).forEach(vocab => {
            fallback.push({
                original: `This is a ${vocab.original}.`,
                translation: `这是一个 ${vocab.translation}。`,
                source: 'fallback'
            });
        });
        return fallback;
    }

    _createGameBoard() {
        this._gameContainer.innerHTML = `
            <div class="fill-blank-wrapper">
                <div class="game-info">
                    <div class="game-stats">
                        <div class="stat-item">
                            <span class="stat-value" id="current-question">${this._currentSentenceIndex + 1}</span>
                            <span class="stat-label">/ ${this._sentences.length}</span>
                        </div>
                        <div class="stat-item">
                            <span class="stat-value" id="errors-count">${this._errors}</span>
                            <span class="stat-label">Errors</span>
                        </div>
                        <div class="stat-item">
                            <span class="stat-value" id="score-display">${this._score}</span>
                            <span class="stat-label">Score</span>
                        </div>
                    </div>
                </div>

                <div class="translation-hint" id="translation-hint">
                    <!-- Translation will appear here -->
                </div>

                <div class="sentence-container" id="sentence-container">
                    <!-- Sentence with blanks will appear here -->
                </div>

                <div class="input-area" id="input-area">
                    <!-- Inputs will appear here -->
                </div>

                <div class="game-controls">
                    <button class="control-btn secondary" id="hint-btn">💡 Hint</button>
                    <button class="control-btn primary" id="check-btn">✓ Check</button>
                    <button class="control-btn secondary" id="skip-btn">→ Next</button>
                </div>

                <div class="feedback-area" id="feedback-area">
                    <div class="instruction">
                        Complete the sentence by filling in the blanks!
                    </div>
                </div>
            </div>
        `;
    }

    _setupEventListeners() {
        document.getElementById('check-btn').addEventListener('click', () => this._checkAnswer());
        document.getElementById('hint-btn').addEventListener('click', () => this._showHint());
        document.getElementById('skip-btn').addEventListener('click', () => this._skipSentence());

        document.addEventListener('keydown', (e) => {
            if (e.key === 'Enter' && this._isRunning) {
                this._checkAnswer();
            }
        });
    }

    _loadNextSentence() {
        if (this._currentSentenceIndex >= this._sentences.length) {
            this._currentSentenceIndex = 0;
            this._sentences = this._shuffleArray(this._sentences);
            this._showFeedback(`🎉 All sentences completed! Starting over with a new order.`, 'success');
            setTimeout(() => {
                this._loadNextSentence();
            }, 1500);
            return;
        }

        this._isRunning = true;
        this._currentSentence = this._sentences[this._currentSentenceIndex];
        this._createBlanks();
        this._displaySentence();
        this._updateUI();
    }

    _createBlanks() {
        const words = this._currentSentence.original.split(' ');
        this._blanks = [];

        const numBlanks = Math.random() < 0.5 ? 1 : 2;
        const blankIndices = new Set();

        const vocabularyWords = [];
        const otherWords = [];

        words.forEach((word, index) => {
            const cleanWord = word.replace(/[.,!?;:"'()[\]{}\-–—]/g, '').toLowerCase();
            const isVocabularyWord = this._vocabulary.some(vocab =>
                vocab.original.toLowerCase() === cleanWord
            );

            if (isVocabularyWord) {
                vocabularyWords.push({ word, index, priority: 'vocabulary' });
            } else {
                otherWords.push({ word, index, priority: 'other', length: cleanWord.length });
            }
        });

        const selectedWords = [];

        const shuffledVocab = this._shuffleArray(vocabularyWords);
        for (let i = 0; i < Math.min(numBlanks, shuffledVocab.length); i++) {
            selectedWords.push(shuffledVocab[i]);
        }

        if (selectedWords.length < numBlanks) {
            const sortedOthers = otherWords.sort((a, b) => b.length - a.length);
            const needed = numBlanks - selectedWords.length;
            for (let i = 0; i < Math.min(needed, sortedOthers.length); i++) {
                selectedWords.push(sortedOthers[i]);
            }
        }

        selectedWords.forEach(item => blankIndices.add(item.index));

        words.forEach((word, index) => {
            if (blankIndices.has(index)) {
                this._blanks.push({
                    index: index,
                    word: word.replace(/[.,!?;:]$/, ''),
                    punctuation: word.match(/[.,!?;:]$/) ? word.match(/[.,!?;:]$/)[0] : '',
                    userAnswer: ''
                });
            }
        });
    }

    _displaySentence() {
        const words = this._currentSentence.original.split(' ');
        let sentenceHTML = '';
        let blankCounter = 0;

        words.forEach((word, index) => {
            const blank = this._blanks.find(b => b.index === index);
            if (blank) {
                sentenceHTML += `<span class="blank-wrapper">
                    <input type="text" class="blank-input"
                           id="blank-${blankCounter}"
                           placeholder="___"
                           maxlength="${blank.word.length + 2}">
                    ${blank.punctuation}
                </span> `;
                blankCounter++;
            } else {
                sentenceHTML += `<span class="word">${word}</span> `;
            }
        });

        document.getElementById('sentence-container').innerHTML = sentenceHTML;

        const translation = this._currentSentence.translation || '';
        document.getElementById('translation-hint').innerHTML = translation ?
            `<em>💭 ${translation}</em>` : '';

        const firstInput = document.getElementById('blank-0');
        if (firstInput) {
            setTimeout(() => firstInput.focus(), 100);
        }
    }

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

        let allCorrect = true;
        let correctCount = 0;

        this._blanks.forEach((blank, index) => {
            const input = document.getElementById(`blank-${index}`);
            const userAnswer = input.value.trim().toLowerCase();
            const correctAnswer = blank.word.toLowerCase();

            blank.userAnswer = input.value.trim();

            if (userAnswer === correctAnswer) {
                input.classList.remove('incorrect');
                input.classList.add('correct');
                correctCount++;
            } else {
                input.classList.remove('correct');
                input.classList.add('incorrect');
                allCorrect = false;
            }
        });

        if (allCorrect) {
            this._score += 10 * this._blanks.length;
            this._showFeedback(`🎉 Perfect! +${10 * this._blanks.length} points`, 'success');
            setTimeout(() => {
                this._currentSentenceIndex++;
                this._loadNextSentence();
            }, 1500);
        } else {
            this._errors++;
            if (correctCount > 0) {
                this._score += 5 * correctCount;
                this._showFeedback(`✨ ${correctCount}/${this._blanks.length} correct! +${5 * correctCount} points. Try again.`, 'partial');
            } else {
                this._showFeedback(`❌ Try again! (${this._errors} errors)`, 'error');
            }
        }

        this._updateUI();

        this._eventBus.emit('game:score-update', {
            gameId: 'fill-the-blank',
            score: this._score,
            module: this.name
        });
    }

    _showHint() {
        this._blanks.forEach((blank, index) => {
            const input = document.getElementById(`blank-${index}`);
            if (!input.value.trim()) {
                input.value = blank.word[0];
                input.focus();
            }
        });

        this._showFeedback('💡 First letter added!', 'info');
    }

    _skipSentence() {
        this._blanks.forEach((blank, index) => {
            const input = document.getElementById(`blank-${index}`);
            input.value = blank.word;
            input.classList.add('revealed');
        });

        this._showFeedback('📖 Answers revealed! Next sentence...', 'info');
        setTimeout(() => {
            this._currentSentenceIndex++;
            this._loadNextSentence();
        }, 2000);
    }

    _showFeedback(message, type = 'info') {
        const feedbackArea = document.getElementById('feedback-area');
        feedbackArea.innerHTML = `<div class="instruction ${type}">${message}</div>`;
    }

    _updateUI() {
        document.getElementById('current-question').textContent = this._currentSentenceIndex + 1;
        document.getElementById('errors-count').textContent = this._errors;
        document.getElementById('score-display').textContent = this._score;
    }

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

    _injectCSS() {
        const cssId = 'fill-the-blank-styles';
        if (document.getElementById(cssId)) return;

        const style = document.createElement('style');
        style.id = cssId;
        style.textContent = `
            .fill-blank-wrapper {
                max-width: 900px;
                margin: 0 auto;
                padding: 20px;
                font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
                background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                min-height: 100vh;
                color: white;
            }

            .game-info {
                background: rgba(255, 255, 255, 0.1);
                border-radius: 15px;
                padding: 20px;
                margin-bottom: 25px;
                backdrop-filter: blur(10px);
                border: 1px solid rgba(255, 255, 255, 0.2);
            }

            .game-stats {
                display: flex;
                justify-content: space-around;
                align-items: center;
            }

            .stat-item {
                text-align: center;
            }

            .stat-value {
                font-size: 2em;
                font-weight: bold;
                display: block;
                color: #fff;
            }

            .stat-label {
                font-size: 0.9em;
                opacity: 0.8;
                color: #e0e0e0;
            }

            .translation-hint {
                background: rgba(255, 255, 255, 0.1);
                border-radius: 12px;
                padding: 15px;
                margin-bottom: 20px;
                text-align: center;
                backdrop-filter: blur(10px);
                border: 1px solid rgba(255, 255, 255, 0.2);
                font-size: 1.1em;
                color: #f0f0f0;
            }

            .sentence-container {
                background: rgba(255, 255, 255, 0.95);
                border-radius: 15px;
                padding: 30px;
                margin-bottom: 25px;
                font-size: 1.4em;
                line-height: 1.8;
                text-align: center;
                color: #2c3e50;
                box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
                border: 1px solid rgba(255, 255, 255, 0.3);
            }

            .word {
                display: inline;
                color: #2c3e50;
                font-weight: 500;
            }

            .blank-wrapper {
                display: inline;
                position: relative;
            }

            .blank-input {
                background: white;
                border: 2px solid #ddd;
                border-radius: 8px;
                padding: 8px 12px;
                font-size: 1em;
                text-align: center;
                min-width: 80px;
                max-width: 150px;
                transition: all 0.3s ease;
                color: #2c3e50;
                font-weight: bold;
            }

            .blank-input:focus {
                outline: none;
                border-color: #667eea;
                box-shadow: 0 0 10px rgba(102, 126, 234, 0.3);
                transform: scale(1.05);
            }

            .blank-input.correct {
                border-color: #27ae60;
                background: linear-gradient(135deg, #d5f4e6, #a3e6c7);
                color: #1e8e3e;
            }

            .blank-input.incorrect {
                border-color: #e74c3c;
                background: linear-gradient(135deg, #ffeaea, #ffcdcd);
                color: #c0392b;
                animation: shake 0.5s ease-in-out;
            }

            .blank-input.revealed {
                border-color: #f39c12;
                background: linear-gradient(135deg, #fff3cd, #ffeaa7);
                color: #d35400;
            }

            @keyframes shake {
                0%, 100% { transform: translateX(0); }
                25% { transform: translateX(-5px); }
                75% { transform: translateX(5px); }
            }

            .game-controls {
                display: flex;
                justify-content: center;
                gap: 15px;
                margin: 25px 0;
            }

            .control-btn {
                padding: 12px 25px;
                border: none;
                border-radius: 25px;
                font-size: 1.1em;
                font-weight: bold;
                cursor: pointer;
                transition: all 0.3s ease;
                min-width: 120px;
            }

            .control-btn.primary {
                background: linear-gradient(135deg, #27ae60, #2ecc71);
                color: white;
                box-shadow: 0 4px 15px rgba(39, 174, 96, 0.3);
            }

            .control-btn.primary:hover {
                transform: translateY(-2px);
                box-shadow: 0 6px 20px rgba(39, 174, 96, 0.4);
            }

            .control-btn.secondary {
                background: rgba(255, 255, 255, 0.9);
                color: #667eea;
                border: 2px solid rgba(255, 255, 255, 0.5);
            }

            .control-btn.secondary:hover {
                background: white;
                transform: translateY(-2px);
                box-shadow: 0 4px 15px rgba(255, 255, 255, 0.3);
            }

            .feedback-area {
                background: rgba(255, 255, 255, 0.1);
                border-radius: 12px;
                padding: 20px;
                text-align: center;
                backdrop-filter: blur(10px);
                border: 1px solid rgba(255, 255, 255, 0.2);
                min-height: 60px;
                display: flex;
                align-items: center;
                justify-content: center;
            }

            .instruction {
                font-size: 1.1em;
                font-weight: 500;
                color: #f0f0f0;
            }

            .instruction.success {
                color: #2ecc71;
                font-weight: bold;
                animation: pulse 0.6s ease-in-out;
            }

            .instruction.error {
                color: #e74c3c;
                font-weight: bold;
                animation: pulse 0.6s ease-in-out;
            }

            .instruction.partial {
                color: #f39c12;
                font-weight: bold;
            }

            .instruction.info {
                color: #3498db;
                font-weight: bold;
            }

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

            .game-error {
                background: rgba(231, 76, 60, 0.1);
                border: 2px solid #e74c3c;
                border-radius: 15px;
                padding: 30px;
                text-align: center;
                color: white;
                backdrop-filter: blur(10px);
            }

            .game-error h3 {
                color: #e74c3c;
                margin-bottom: 15px;
            }

            .back-btn {
                background: linear-gradient(135deg, #95a5a6, #7f8c8d);
                color: white;
                border: none;
                padding: 12px 25px;
                border-radius: 25px;
                font-size: 1.1em;
                font-weight: bold;
                cursor: pointer;
                margin-top: 20px;
                transition: all 0.3s ease;
            }

            .back-btn:hover {
                transform: translateY(-2px);
                box-shadow: 0 4px 15px rgba(149, 165, 166, 0.4);
            }

            @media (max-width: 768px) {
                .fill-blank-wrapper {
                    padding: 15px;
                }

                .game-stats {
                    flex-direction: column;
                    gap: 15px;
                }

                .sentence-container {
                    font-size: 1.2em;
                    padding: 20px;
                }

                .blank-input {
                    min-width: 60px;
                    font-size: 0.9em;
                }

                .game-controls {
                    flex-direction: column;
                    align-items: center;
                }

                .control-btn {
                    width: 100%;
                    max-width: 200px;
                }
            }
        `;

        document.head.appendChild(style);
    }

    _removeCSS() {
        const cssElement = document.getElementById('fill-the-blank-styles');
        if (cssElement) {
            cssElement.remove();
        }
    }
}

export default FillTheBlank;