/**
 * PrerequisiteEngine - Enhanced dependency tracking with persistent storage
 * Manages vocabulary prerequisites and unlocks content based on mastery
 * Implements ProgressSystemInterface for strict contract enforcement
 */

import ProgressSystemInterface from '../interfaces/ProgressSystemInterface.js';
import VocabularyProgressManager from './VocabularyProgressManager.js';

class PrerequisiteEngine extends ProgressSystemInterface {
    constructor() {
        super('PrerequisiteEngine');

        this.chapterVocabulary = new Set();
        this.masteredWords = new Set();
        this.masteredPhrases = new Set();
        this.masteredGrammar = new Set();
        this.discoveredWords = new Set();
        this.contentAnalysis = null;

        // Enhanced persistence system
        this.progressManager = new VocabularyProgressManager();
        this.currentBookId = null;
        this.currentChapterId = null;
        this.isInitialized = false;

        // Basic words assumed to be known (no need to learn)
        this.assumedKnown = new Set([
            // Articles and determiners
            'a', 'an', 'the', 'this', 'that', 'these', 'those', 'some', 'any', 'each', 'every',

            // Pronouns
            'I', 'you', 'he', 'she', 'it', 'we', 'they', 'me', 'him', 'her', 'us', 'them',
            'my', 'your', 'his', 'her', 'its', 'our', 'their', 'mine', 'yours', 'hers', 'ours', 'theirs',

            // Prepositions
            'in', 'on', 'at', 'by', 'for', 'with', 'to', 'from', 'of', 'about', 'under', 'over',
            'through', 'during', 'before', 'after', 'above', 'below', 'up', 'down', 'out', 'off',

            // Common verbs
            'is', 'are', 'was', 'were', 'be', 'been', 'being', 'have', 'has', 'had', 'do', 'does', 'did',
            'will', 'would', 'could', 'should', 'can', 'may', 'might', 'must',

            // Conjunctions
            'and', 'or', 'but', 'because', 'if', 'when', 'where', 'how', 'why', 'what', 'who', 'which',

            // Common adverbs
            'not', 'no', 'yes', 'very', 'so', 'too', 'also', 'only', 'just', 'still', 'even',

            // Numbers
            'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten',
            'first', 'second', 'third', 'last', 'next'
        ]);
    }

    /**
     * Analyze chapter content and extract vocabulary requirements
     * @param {Object} chapterContent - Full chapter content data
     * @returns {Object} - Analysis results
     */
    analyzeChapter(chapterContent) {
        console.log('📊 Analyzing chapter prerequisites...');

        // Extract chapter vocabulary
        this.chapterVocabulary.clear();
        if (chapterContent.vocabulary) {
            Object.keys(chapterContent.vocabulary).forEach(word => {
                this.chapterVocabulary.add(word.toLowerCase());
            });
        }

        // Analyze all content types
        const analysis = {
            totalVocabulary: this.chapterVocabulary.size,
            phrases: this._analyzePhrases(chapterContent.phrases || {}),
            texts: this._analyzeTexts(chapterContent.texts || []),
            dialogs: this._analyzeDialogs(chapterContent.dialogs || []),
            audio: this._analyzeAudio(chapterContent.audio || []),
            images: this._analyzeImages(chapterContent.images || []),
            grammar: this._analyzeGrammar(chapterContent.grammar || {}),
            vocabularyCategories: this._categorizeVocabulary(chapterContent.vocabulary || {})
        };

        this.contentAnalysis = analysis;

        console.log('✅ Chapter analysis complete:', analysis);
        return analysis;
    }

    /**
     * Check if content can be unlocked based on current mastery
     * @param {string} contentType - Type of content (phrase, text, audio, etc.)
     * @param {Object} contentItem - Specific content item
     * @returns {Object} - Unlock status and missing prerequisites
     */
    canUnlock(contentType, contentItem) {
        const requiredWords = this.getPrerequisites(contentType, contentItem);
        const missingWords = requiredWords.filter(word => !this.isMastered(word));

        return {
            canUnlock: missingWords.length === 0,
            requiredWords,
            missingWords,
            masteredCount: requiredWords.length - missingWords.length,
            totalRequired: requiredWords.length
        };
    }

    /**
     * Get vocabulary prerequisites for specific content
     * @param {string} contentType - Type of content
     * @param {Object} contentItem - Content item
     * @returns {Array<string>} - Required vocabulary words
     */
    getPrerequisites(contentType, contentItem) {
        let text = '';

        // Extract text based on content type
        switch (contentType) {
            case 'phrase':
                text = contentItem.english || contentItem.text || '';
                break;
            case 'text':
                text = contentItem.content || contentItem.text || '';
                break;
            case 'dialog':
                text = contentItem.conversation ?
                    contentItem.conversation.map(line => line.english || line.text || '').join(' ') : '';
                break;
            case 'audio':
                text = contentItem.transcription || contentItem.text || '';
                break;
            case 'grammar':
                text = contentItem.example || contentItem.sentence || '';
                break;
            default:
                text = JSON.stringify(contentItem);
        }

        return this._extractPrerequisites(text);
    }

    /**
     * Mark vocabulary as mastered
     * @param {string} word - Word to mark as mastered
     * @param {Object} metadata - Additional metadata (attempts, sessionId, etc.)
     */
    markWordMastered(word, metadata = {}) {
        const normalizedWord = word.toLowerCase();
        if (this.chapterVocabulary.has(normalizedWord)) {
            const masteredEntry = {
                word: normalizedWord,
                masteredAt: new Date().toISOString(),
                attempts: 1,
                ...metadata
            };
            this.masteredWords.add(normalizedWord);
            console.log(`✅ Word mastered: ${word} at ${masteredEntry.masteredAt}`);
        }
    }

    /**
     * Mark word as discovered (seen/introduced but not necessarily mastered)
     * @param {string} word - Word to mark as discovered
     * @param {Object} metadata - Additional metadata
     */
    markWordDiscovered(word, metadata = {}) {
        const normalizedWord = word.toLowerCase();
        if (this.chapterVocabulary.has(normalizedWord)) {
            this.discoveredWords.add(normalizedWord);
            console.log(`👁️ Word discovered: ${word}`);
        }
    }

    /**
     * Check if a word has been discovered
     * @param {string} word - Word to check
     * @returns {boolean} - True if discovered or assumed known
     */
    isDiscovered(word) {
        const normalizedWord = word.toLowerCase();
        return this.assumedKnown.has(normalizedWord) ||
               this.discoveredWords.has(normalizedWord) ||
               this.masteredWords.has(normalizedWord) ||
               !this.chapterVocabulary.has(normalizedWord); // Non-chapter words assumed discovered
    }

    /**
     * Mark phrase as mastered
     * @param {string} phraseId - Phrase identifier to mark as mastered
     * @param {Object} metadata - Additional metadata (attempts, sessionId, etc.)
     */
    markPhraseMastered(phraseId, metadata = {}) {
        const masteredEntry = {
            phrase: phraseId,
            masteredAt: new Date().toISOString(),
            attempts: 1,
            ...metadata
        };
        this.masteredPhrases.add(phraseId);
        console.log(`✅ Phrase mastered: ${phraseId} at ${masteredEntry.masteredAt}`);
    }

    /**
     * Mark grammar concept as mastered
     * @param {string} grammarConcept - Grammar concept to mark as mastered
     * @param {Object} metadata - Additional metadata (attempts, sessionId, etc.)
     */
    markGrammarMastered(grammarConcept, metadata = {}) {
        const masteredEntry = {
            concept: grammarConcept,
            masteredAt: new Date().toISOString(),
            attempts: 1,
            ...metadata
        };
        this.masteredGrammar.add(grammarConcept);
        console.log(`✅ Grammar concept mastered: ${grammarConcept} at ${masteredEntry.masteredAt}`);
    }

    /**
     * Check if a word is considered mastered
     * @param {string} word - Word to check
     * @returns {boolean} - True if mastered or assumed known
     */
    isMastered(word) {
        const normalizedWord = word.toLowerCase();
        return this.assumedKnown.has(normalizedWord) ||
               this.masteredWords.has(normalizedWord) ||
               !this.chapterVocabulary.has(normalizedWord); // Non-chapter words assumed known
    }

    /**
     * Get available content based on current mastery
     * @param {string} contentType - Type of content to check
     * @param {Array} contentList - List of content items
     * @returns {Array} - Available content items with unlock status
     */
    getAvailableContent(contentType, contentList) {
        return contentList.map((item, index) => {
            const unlockStatus = this.canUnlock(contentType, item);
            return {
                ...item,
                index,
                unlockStatus,
                available: unlockStatus.canUnlock
            };
        });
    }

    /**
     * Get mastery progress statistics
     * @returns {Object} - Progress statistics
     */
    getMasteryProgress() {
        // Initialize sets if they don't exist
        if (!this.masteredTexts) this.masteredTexts = new Set();
        if (!this.masteredDialogs) this.masteredDialogs = new Set();
        if (!this.masteredAudios) this.masteredAudios = new Set();
        if (!this.masteredImages) this.masteredImages = new Set();

        return {
            vocabulary: {
                total: this.chapterVocabulary.size,
                mastered: this.masteredWords.size,
                percentage: Math.round((this.masteredWords.size / Math.max(this.chapterVocabulary.size, 1)) * 100)
            },
            phrases: {
                total: this.contentAnalysis?.phrases.total || 0,
                mastered: this.masteredPhrases.size,
                percentage: Math.round((this.masteredPhrases.size / Math.max(this.contentAnalysis?.phrases.total || 1, 1)) * 100)
            },
            texts: {
                total: this.contentAnalysis?.texts.total || 0,
                mastered: this.masteredTexts.size,
                percentage: Math.round((this.masteredTexts.size / Math.max(this.contentAnalysis?.texts.total || 1, 1)) * 100)
            },
            dialogs: {
                total: this.contentAnalysis?.dialogs.total || 0,
                mastered: this.masteredDialogs.size,
                percentage: Math.round((this.masteredDialogs.size / Math.max(this.contentAnalysis?.dialogs.total || 1, 1)) * 100)
            },
            audio: {
                total: this.contentAnalysis?.audio.total || 0,
                mastered: this.masteredAudios.size,
                percentage: Math.round((this.masteredAudios.size / Math.max(this.contentAnalysis?.audio.total || 1, 1)) * 100)
            },
            images: {
                total: this.contentAnalysis?.images.total || 0,
                mastered: this.masteredImages.size,
                percentage: Math.round((this.masteredImages.size / Math.max(this.contentAnalysis?.images.total || 1, 1)) * 100)
            },
            grammar: {
                total: this.contentAnalysis?.grammar.concepts || 0,
                mastered: this.masteredGrammar.size,
                percentage: Math.round((this.masteredGrammar.size / Math.max(this.contentAnalysis?.grammar.concepts || 1, 1)) * 100)
            }
        };
    }

    // Private Methods

    _extractPrerequisites(text) {
        if (!text) return [];

        // Extract words and filter for chapter vocabulary only
        const words = text.toLowerCase()
            .replace(/[^\w\s]/g, ' ') // Remove punctuation
            .split(/\s+/)
            .filter(word => word.length > 0)
            .map(word => this._getBaseForm(word));

        // Return only words that are in chapter vocabulary (prerequisites)
        return [...new Set(words)].filter(word =>
            this.chapterVocabulary.has(word) &&
            !this.assumedKnown.has(word)
        );
    }

    _getBaseForm(word) {
        // Simple stemming - can be enhanced with proper stemming library
        const normalizedWord = word.toLowerCase();

        // Remove common suffixes to find base form
        const suffixes = ['s', 'es', 'ed', 'ing', 'ly', 'er', 'est'];

        for (const suffix of suffixes) {
            if (normalizedWord.endsWith(suffix) && normalizedWord.length > suffix.length + 2) {
                const baseForm = normalizedWord.slice(0, -suffix.length);
                if (this.chapterVocabulary.has(baseForm)) {
                    return baseForm;
                }
            }
        }

        return normalizedWord;
    }

    _analyzePhrases(phrases) {
        // Convert object to array of entries
        const phraseEntries = Object.entries(phrases);

        const analysis = {
            total: phraseEntries.length,
            withPrerequisites: 0,
            averagePrerequisites: 0,
            categories: {}
        };

        let totalPrereqs = 0;
        phraseEntries.forEach(([phraseText, phraseData]) => {
            // Create phrase object with english text for getPrerequisites
            const phraseObj = {
                english: phraseText,
                translation: phraseData.user_language,
                context: phraseData.context || 'general',
                ...phraseData
            };

            const prereqs = this.getPrerequisites('phrase', phraseObj);
            if (prereqs.length > 0) {
                analysis.withPrerequisites++;
            }
            totalPrereqs += prereqs.length;

            // Categorize phrases
            const category = phraseData.context || 'general';
            analysis.categories[category] = (analysis.categories[category] || 0) + 1;
        });

        analysis.averagePrerequisites = Math.round((totalPrereqs / Math.max(phraseEntries.length, 1)) * 100) / 100;
        return analysis;
    }

    _analyzeTexts(texts) {
        // Convert object to array if needed
        const textArray = Array.isArray(texts) ? texts : Object.values(texts);

        const analysis = {
            total: textArray.length,
            totalSentences: 0,
            averagePrerequisites: 0,
            categories: {}
        };

        let totalPrereqs = 0;
        textArray.forEach(text => {
            const prereqs = this.getPrerequisites('text', text);
            totalPrereqs += prereqs.length;

            // Count sentences
            const sentences = (text.content || text.text || '').split(/[.!?]+/).filter(s => s.trim().length > 0);
            analysis.totalSentences += sentences.length;

            // Categorize texts
            const category = text.category || text.type || 'general';
            analysis.categories[category] = (analysis.categories[category] || 0) + 1;
        });

        analysis.averagePrerequisites = Math.round((totalPrereqs / Math.max(textArray.length, 1)) * 100) / 100;
        return analysis;
    }

    _analyzeDialogs(dialogs) {
        // Convert object to array of entries if needed
        const dialogEntries = Array.isArray(dialogs) ? dialogs : Object.entries(dialogs);

        const analysis = {
            total: dialogEntries.length,
            totalLines: 0,
            averagePrerequisites: 0
        };

        let totalPrereqs = 0;
        dialogEntries.forEach(dialogItem => {
            // Handle both array format and object format
            const dialog = Array.isArray(dialogs) ? dialogItem : dialogItem[1];

            const prereqs = this.getPrerequisites('dialog', dialog);
            totalPrereqs += prereqs.length;

            if (dialog.conversation) {
                analysis.totalLines += dialog.conversation.length;
            }
        });

        analysis.averagePrerequisites = Math.round((totalPrereqs / Math.max(dialogEntries.length, 1)) * 100) / 100;
        return analysis;
    }

    _analyzeAudio(audioItems) {
        // Convert object to array if needed
        const audioArray = Array.isArray(audioItems) ? audioItems : Object.values(audioItems);

        return {
            total: audioArray.length,
            withTranscription: audioArray.filter(item => item.transcription).length,
            categories: audioArray.reduce((cats, item) => {
                const cat = item.type || 'general';
                cats[cat] = (cats[cat] || 0) + 1;
                return cats;
            }, {})
        };
    }

    _analyzeImages(imageItems) {
        // Convert object to array if needed
        const imageArray = Array.isArray(imageItems) ? imageItems : Object.values(imageItems);

        return {
            total: imageArray.length,
            withDescriptions: imageArray.filter(item => item.description).length,
            categories: imageArray.reduce((cats, item) => {
                const cat = item.category || item.type || 'general';
                cats[cat] = (cats[cat] || 0) + 1;
                return cats;
            }, {})
        };
    }

    _analyzeGrammar(grammarData) {
        const concepts = Object.keys(grammarData);
        return {
            concepts: concepts.length,
            conceptList: concepts,
            categories: concepts.reduce((cats, concept) => {
                const cat = grammarData[concept]?.category || 'general';
                cats[cat] = (cats[cat] || 0) + 1;
                return cats;
            }, {})
        };
    }

    _categorizeVocabulary(vocabulary) {
        const categories = {};

        Object.entries(vocabulary).forEach(([word, data]) => {
            const type = data.type || 'unknown';
            categories[type] = (categories[type] || 0) + 1;
        });

        return categories;
    }

    /**
     * Reset all mastery tracking
     */
    reset() {
        this.masteredWords.clear();
        this.masteredPhrases.clear();
        this.masteredGrammar.clear();
        console.log('🔄 Prerequisites reset');
    }

    /**
     * Export mastery state for persistence
     * @returns {Object} - Serializable mastery state
     */
    exportMasteryState() {
        return {
            masteredWords: Array.from(this.masteredWords),
            masteredPhrases: Array.from(this.masteredPhrases),
            masteredGrammar: Array.from(this.masteredGrammar),
            timestamp: new Date().toISOString()
        };
    }

    /**
     * Import mastery state from persistence
     * @param {Object} state - Previously exported mastery state
     */
    importMasteryState(state) {
        if (state.masteredWords) {
            this.masteredWords = new Set(state.masteredWords);
        }
        if (state.masteredPhrases) {
            this.masteredPhrases = new Set(state.masteredPhrases);
        }
        if (state.masteredGrammar) {
            this.masteredGrammar = new Set(state.masteredGrammar);
        }
        console.log('📥 Mastery state imported');
    }

    // =====================================================
    // ENHANCED PERSISTENCE METHODS
    // =====================================================

    /**
     * Initialize the PrerequisiteEngine with persistent data
     * @param {string} bookId - Book identifier
     * @param {string} chapterId - Chapter identifier
     */
    async init(bookId, chapterId) {
        console.log('🔧 Initializing PrerequisiteEngine with persistence:', `${bookId}/${chapterId}`);

        this.currentBookId = bookId;
        this.currentChapterId = chapterId;

        try {
            // Load persistent progress data
            const progressData = await this.progressManager.loadProgress(bookId, chapterId);

            // Sync in-memory sets with persistent data
            this.discoveredWords = new Set(Object.keys(progressData.discovered));
            this.masteredWords = new Set(Object.keys(progressData.mastered));

            console.log('✅ PrerequisiteEngine initialized:', {
                discovered: this.discoveredWords.size,
                mastered: this.masteredWords.size
            });

            this.isInitialized = true;

        } catch (error) {
            console.error('❌ Error initializing PrerequisiteEngine:', error);
            this.isInitialized = false;
        }
    }

    /**
     * Check if a word is discovered (synchronous, uses cache)
     * @param {string} word - Word to check
     * @returns {boolean} - True if word is discovered
     */
    isDiscovered(word) {
        if (!this.isInitialized) {
            console.warn('⚠️ PrerequisiteEngine not initialized, assuming word not discovered:', word);
            return false;
        }

        const normalizedWord = word.toLowerCase();

        // Check if it's an assumed known word
        if (this.assumedKnown.has(normalizedWord)) {
            return true;
        }

        // Check discovered words cache
        return this.discoveredWords.has(normalizedWord);
    }

    /**
     * Check if a word is mastered (synchronous, uses cache)
     * @param {string} word - Word to check
     * @returns {boolean} - True if word is mastered
     */
    isMastered(word) {
        if (!this.isInitialized) {
            console.warn('⚠️ PrerequisiteEngine not initialized, assuming word not mastered:', word);
            return false;
        }

        const normalizedWord = word.toLowerCase();

        // Check if it's an assumed known word
        if (this.assumedKnown.has(normalizedWord)) {
            return true;
        }

        // Check mastered words cache
        return this.masteredWords.has(normalizedWord);
    }

    /**
     * Mark a word as discovered (async, persists data)
     * @param {string} word - Word to mark as discovered
     * @param {Object} metadata - Additional metadata (difficulty, timestamp, etc.)
     */
    async markWordDiscovered(word, metadata = {}) {
        if (!this.isInitialized) {
            console.warn('⚠️ PrerequisiteEngine not initialized, cannot mark word discovered:', word);
            return;
        }

        const normalizedWord = word.toLowerCase();

        // Skip if already discovered or assumed known
        if (this.isDiscovered(normalizedWord)) {
            return;
        }

        // Update in-memory cache
        this.discoveredWords.add(normalizedWord);

        // Persist to storage
        try {
            await this.progressManager.markWordDiscovered(
                this.currentBookId,
                this.currentChapterId,
                normalizedWord,
                metadata
            );
            console.log('📚 Word marked as discovered:', normalizedWord);
        } catch (error) {
            console.error('❌ Error marking word as discovered:', error);
            // Remove from cache if persistence failed
            this.discoveredWords.delete(normalizedWord);
        }
    }

    /**
     * Mark a word as mastered (async, persists data)
     * @param {string} word - Word to mark as mastered
     * @param {Object} metadata - Additional metadata (scores, timestamp, etc.)
     */
    async markWordMastered(word, metadata = {}) {
        if (!this.isInitialized) {
            console.warn('⚠️ PrerequisiteEngine not initialized, cannot mark word mastered:', word);
            return;
        }

        const normalizedWord = word.toLowerCase();

        // Ensure word is discovered first
        if (!this.isDiscovered(normalizedWord)) {
            await this.markWordDiscovered(normalizedWord, metadata);
        }

        // Skip if already mastered or assumed known
        if (this.isMastered(normalizedWord)) {
            return;
        }

        // Update in-memory cache
        this.masteredWords.add(normalizedWord);

        // Persist to storage
        try {
            await this.progressManager.markWordMastered(
                this.currentBookId,
                this.currentChapterId,
                normalizedWord,
                metadata
            );
            console.log('🏆 Word marked as mastered:', normalizedWord);
        } catch (error) {
            console.error('❌ Error marking word as mastered:', error);
            // Remove from cache if persistence failed
            this.masteredWords.delete(normalizedWord);
        }
    }

    /**
     * Get progress statistics
     * @returns {Object} - Progress statistics
     */
    async getProgressStats() {
        if (!this.isInitialized) {
            return { discovered: { count: 0, percentage: 0 }, mastered: { count: 0, percentage: 0 } };
        }

        return await this.progressManager.getProgressStats(this.currentBookId, this.currentChapterId);
    }

    /**
     * Force save all progress data
     */
    async forceSave() {
        if (!this.isInitialized) {
            console.warn('⚠️ PrerequisiteEngine not initialized, cannot force save');
            return;
        }

        await this.progressManager.forceSaveAll();
    }

    /**
     * Get discovered words as array
     * @returns {Array} - Array of discovered words
     */
    getDiscoveredWordsArray() {
        return Array.from(this.discoveredWords);
    }

    /**
     * Get mastered words as array
     * @returns {Array} - Array of mastered words
     */
    getMasteredWordsArray() {
        return Array.from(this.masteredWords);
    }

    // ========================================
    // ProgressSystemInterface REQUIRED METHODS
    // ========================================
    // Note: markWordDiscovered and markWordMastered are already implemented above (lines 583-655)
    // They handle both in-memory cache and persistence

    isWordDiscovered(word) {
        return this.isDiscovered(word);
    }

    isWordMastered(word) {
        return this.isMastered(word);
    }

    async markPhraseCompleted(phraseId, metadata = {}) {
        this.markPhraseMastered(phraseId);
    }

    async markDialogCompleted(dialogId, metadata = {}) {
        // Store in a new Set for dialogs
        if (!this.masteredDialogs) this.masteredDialogs = new Set();
        this.masteredDialogs.add(dialogId);
    }

    async markTextCompleted(textId, metadata = {}) {
        // Store in a new Set for texts
        if (!this.masteredTexts) this.masteredTexts = new Set();
        this.masteredTexts.add(textId);
    }

    async markAudioCompleted(audioId, metadata = {}) {
        if (!this.masteredAudios) this.masteredAudios = new Set();
        this.masteredAudios.add(audioId);
    }

    async markImageCompleted(imageId, metadata = {}) {
        if (!this.masteredImages) this.masteredImages = new Set();
        this.masteredImages.add(imageId);
    }

    async markGrammarCompleted(grammarId, metadata = {}) {
        this.markGrammarMastered(grammarId);
    }

    canComplete(itemType, itemId, context = {}) {
        // Check prerequisites based on item type
        if (itemType.includes('vocabulary')) {
            return {
                canComplete: true,
                reason: 'Vocabulary always available',
                missingPrereqs: []
            };
        }

        // For content items, check if required vocabulary is mastered
        const requiredWords = context.requiredWords || [];
        const missingWords = requiredWords.filter(word => !this.isMastered(word));

        return {
            canComplete: missingWords.length === 0,
            reason: missingWords.length === 0 ? 'All prerequisites met' : 'Missing vocabulary',
            missingPrereqs: missingWords
        };
    }

    getProgress(chapterId) {
        return {
            percentage: this.calculateMasteryPercentage(),
            completedWeight: this.masteredWords.size,
            totalWeight: this.chapterVocabulary.size,
            breakdown: {
                'vocabulary-mastery': { count: this.masteredWords.size, weight: this.masteredWords.size },
                'vocabulary-discovery': { count: this.discoveredWords.size, weight: this.discoveredWords.size },
                'phrase': { count: this.masteredPhrases.size, weight: this.masteredPhrases.size * 6 },
                'grammar': { count: this.masteredGrammar.size, weight: this.masteredGrammar.size * 6 }
            },
            completedBreakdown: {}
        };
    }

    async saveProgress(bookId, chapterId) {
        await this.progressManager.saveAllProgress();
    }

    async loadProgress(bookId, chapterId) {
        await this.loadPersistedProgress(bookId, chapterId);
        return this.getProgress(chapterId);
    }

    async reset(bookId, chapterId) {
        this.masteredWords.clear();
        this.masteredPhrases.clear();
        this.masteredGrammar.clear();
        this.discoveredWords.clear();
        if (this.masteredDialogs) this.masteredDialogs.clear();
        if (this.masteredTexts) this.masteredTexts.clear();
        if (this.masteredAudios) this.masteredAudios.clear();
        if (this.masteredImages) this.masteredImages.clear();
        await this.saveProgress(bookId, chapterId);
    }
}

export default PrerequisiteEngine;