// Vocabulary State Management
export class VocabularyState {
    #words = new Map();
    #currentWord = null;
    #currentMode = 'flashcard';
    #currentScene = 'coffee';
    #progress = {
        learned: 0,
        todayNew: 0,
        masteryRate: 0
    };
    #listeners = new Set();

    constructor() {
        this.loadFromStorage();
        this.initializeDefaultData();
    }

    // State getters
    getCurrentWord() {
        return this.#currentWord;
    }

    getCurrentMode() {
        return this.#currentMode;
    }

    getCurrentScene() {
        return this.#currentScene;
    }

    getProgress() {
        return { ...this.#progress };
    }

    getAllWords() {
        return Array.from(this.#words.values());
    }

    getWordsByStatus(status) {
        return this.getAllWords().filter(word => word.status === status);
    }

    // State setters
    setCurrentWord(word) {
        this.#currentWord = word;
        this.notify('currentWordChanged', word);
    }

    setCurrentMode(mode) {
        this.#currentMode = mode;
        this.notify('modeChanged', mode);
    }

    setCurrentScene(scene) {
        this.#currentScene = scene;
        this.notify('sceneChanged', scene);
    }

    // Word management
    addWord(wordData) {
        const word = {
            id: wordData.id || Date.now().toString(),
            word: wordData.word,
            phonetic: wordData.phonetic,
            definition: wordData.definition,
            example: wordData.example,
            translation: wordData.translation,
            status: wordData.status || 'new',
            difficulty: wordData.difficulty || 'normal',
            reviewCount: wordData.reviewCount || 0,
            correctCount: wordData.correctCount || 0,
            lastReview: wordData.lastReview || null,
            nextReview: wordData.nextReview || Date.now(),
            createdAt: wordData.createdAt || Date.now(),
            updatedAt: Date.now()
        };

        this.#words.set(word.id, word);
        this.updateProgress();
        this.saveToStorage();
        this.notify('wordAdded', word);
        
        return word;
    }

    updateWord(id, updates) {
        const word = this.#words.get(id);
        if (!word) return null;

        const updatedWord = {
            ...word,
            ...updates,
            updatedAt: Date.now()
        };

        this.#words.set(id, updatedWord);
        this.updateProgress();
        this.saveToStorage();
        this.notify('wordUpdated', updatedWord);
        
        return updatedWord;
    }

    deleteWord(id) {
        const word = this.#words.get(id);
        if (!word) return false;

        this.#words.delete(id);
        this.updateProgress();
        this.saveToStorage();
        this.notify('wordDeleted', word);
        
        return true;
    }

    // Review logic
    markWordReview(id, difficulty) {
        const word = this.#words.get(id);
        if (!word) return null;

        const now = Date.now();
        let nextReviewDelay;

        // Spaced repetition algorithm
        switch (difficulty) {
            case 'easy':
                nextReviewDelay = 3 * 24 * 60 * 60 * 1000; // 3 days
                break;
            case 'hard':
                nextReviewDelay = 10 * 60 * 1000; // 10 minutes
                break;
            case 'normal':
            default:
                nextReviewDelay = 24 * 60 * 60 * 1000; // 1 day
        }

        const updates = {
            reviewCount: word.reviewCount + 1,
            lastReview: now,
            nextReview: now + nextReviewDelay,
            difficulty: difficulty
        };

        // Update status based on review performance
        if (difficulty === 'easy' && word.reviewCount >= 2) {
            updates.status = 'learned';
        } else if (word.status === 'new') {
            updates.status = 'learning';
        }

        return this.updateWord(id, updates);
    }

    markWordCorrect(id) {
        const word = this.#words.get(id);
        if (!word) return null;

        return this.updateWord(id, {
            correctCount: word.correctCount + 1
        });
    }

    // Queue management
    getReviewQueue() {
        const now = Date.now();
        return this.getAllWords()
            .filter(word => word.nextReview <= now)
            .sort((a, b) => a.nextReview - b.nextReview);
    }

    getNewWords(limit = 10) {
        return this.getAllWords()
            .filter(word => word.status === 'new')
            .slice(0, limit);
    }

    // Progress calculation
    updateProgress() {
        const allWords = this.getAllWords();
        const learned = allWords.filter(word => word.status === 'learned').length;
        
        const today = new Date();
        today.setHours(0, 0, 0, 0);
        const todayTimestamp = today.getTime();
        
        const todayNew = allWords.filter(word => 
            word.createdAt >= todayTimestamp
        ).length;

        const totalReviews = allWords.reduce((sum, word) => sum + word.reviewCount, 0);
        const totalCorrect = allWords.reduce((sum, word) => sum + word.correctCount, 0);
        const masteryRate = totalReviews > 0 ? Math.round((totalCorrect / totalReviews) * 100) : 0;

        this.#progress = {
            learned,
            todayNew,
            masteryRate
        };

        this.notify('progressUpdated', this.#progress);
    }

    // Event system
    subscribe(listener) {
        this.#listeners.add(listener);
        return () => this.#listeners.delete(listener);
    }

    notify(event, data) {
        this.#listeners.forEach(listener => {
            try {
                listener(event, data);
            } catch (error) {
                console.error('State listener error:', error);
            }
        });
    }

    // Persistence
    saveToStorage() {
        try {
            const data = {
                words: Array.from(this.#words.values()),
                currentMode: this.#currentMode,
                currentScene: this.#currentScene,
                currentWordId: this.#currentWord?.id || null,
                progress: this.#progress
            };
            
            localStorage.setItem('dramaling-vocabulary', JSON.stringify(data));
        } catch (error) {
            console.error('Failed to save to storage:', error);
        }
    }

    loadFromStorage() {
        try {
            const data = localStorage.getItem('dramaling-vocabulary');
            if (!data) return;

            const parsed = JSON.parse(data);
            
            // Restore words
            if (parsed.words) {
                this.#words.clear();
                parsed.words.forEach(word => {
                    this.#words.set(word.id, word);
                });
            }

            // Restore current state
            this.#currentMode = parsed.currentMode || 'flashcard';
            this.#currentScene = parsed.currentScene || 'coffee';
            this.#progress = parsed.progress || this.#progress;

            // Restore current word
            if (parsed.currentWordId) {
                this.#currentWord = this.#words.get(parsed.currentWordId);
            }

            this.updateProgress();
        } catch (error) {
            console.error('Failed to load from storage:', error);
        }
    }

    // Initialize with sample data
    initializeDefaultData() {
        if (this.#words.size === 0) {
            const sampleWords = [
                {
                    word: 'confidence',
                    phonetic: '/ˈkɒnfɪdəns/',
                    definition: '信心；自信心；把握',
                    example: 'She spoke with great confidence during the presentation.',
                    translation: '她在簡報中表現出很大的自信。',
                    status: 'learning'
                },
                {
                    word: 'presentation',
                    phonetic: '/ˌprezənˈteɪʃən/',
                    definition: '簡報；呈現',
                    example: 'The presentation was very informative.',
                    translation: '這個簡報很有資訊性。',
                    status: 'learning'
                },
                {
                    word: 'colleague',
                    phonetic: '/ˈkɒliːɡ/',
                    definition: '同事；同僚',
                    example: 'I discussed the project with my colleague.',
                    translation: '我和同事討論了這個專案。',
                    status: 'new'
                },
                {
                    word: 'opportunity',
                    phonetic: '/ˌɒpəˈtjuːnɪti/',
                    definition: '機會；時機',
                    example: 'This is a great opportunity to learn.',
                    translation: '這是一個學習的好機會。',
                    status: 'learned'
                },
                {
                    word: 'achievement',
                    phonetic: '/əˈtʃiːvmənt/',
                    definition: '成就；成績',
                    example: 'Graduating from university was a great achievement.',
                    translation: '從大學畢業是一個偉大的成就。',
                    status: 'learning'
                }
            ];

            sampleWords.forEach(wordData => this.addWord(wordData));
            
            // Set first word as current
            if (this.#words.size > 0) {
                this.#currentWord = this.getAllWords()[0];
            }
        }
    }
}