/**
 * ProgressTracker - Manages progress state and persistence
 * Tracks completed items and calculates progress
 * Implements ProgressSystemInterface for strict contract enforcement
 */

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

class ProgressTracker extends ProgressSystemInterface {
    constructor(bookId, chapterId) {
        super('ProgressTracker');

        this.bookId = bookId;
        this.chapterId = chapterId;
        this.analyzer = new ContentProgressAnalyzer();
        this.completedItems = new Set();
        this.analysis = null;
        this.discoveredWords = new Set();
        this.masteredWords = new Set();
    }

    /**
     * Initialize tracker with chapter content
     * @param {Object} chapterContent - Chapter content data
     */
    async init(chapterContent) {
        console.log(`📊 Initializing ProgressTracker for ${this.bookId}/${this.chapterId}...`);

        // Analyze chapter content
        this.analysis = this.analyzer.analyzeChapter(chapterContent, this.chapterId);

        // Load saved progress
        await this._loadProgress();

        console.log(`✅ ProgressTracker initialized: ${this.completedItems.size}/${this.analysis.items.length} items completed`);
    }

    /**
     * Load progress from server
     * @private
     */
    async _loadProgress() {
        try {
            const { default: apiService } = await import('../../services/APIService.js');
            const progress = await apiService.loadDRSProgress(this.bookId, this.chapterId);

            if (progress.completedItems && Array.isArray(progress.completedItems)) {
                progress.completedItems.forEach(itemId => {
                    this.completedItems.add(itemId);
                });
            }

            console.log(`📥 Loaded ${this.completedItems.size} completed items from server`);
        } catch (error) {
            console.log(`📥 No saved progress found (starting fresh): ${error.message}`);
        }
    }

    /**
     * Mark an item as completed
     * @param {string} itemId - Item ID to mark as completed
     * @param {Object} metadata - Optional metadata
     * @returns {Object} - Updated progress
     */
    async markCompleted(itemId, metadata = {}) {
        const item = this.analysis.items.find(i => i.id === itemId);

        if (!item) {
            throw new Error(`Unknown progress item: ${itemId}`);
        }

        // Mark item as completed
        item.markCompleted();
        this.completedItems.add(itemId);

        console.log(`✅ Marked completed: ${itemId} (${item.type}, ${item.getWeight()} points)`);

        // Save progress
        await this._saveProgress();

        // Return updated progress
        return this.getProgress();
    }

    /**
     * Get current progress
     * @returns {Object} - Progress data with percentage and breakdown
     */
    getProgress() {
        const completed = Array.from(this.completedItems);
        const progressData = this.analyzer.calculateProgress(this.chapterId, completed);

        return {
            ...progressData,
            chapterId: this.chapterId,
            bookId: this.bookId,
            completedItems: completed,
            totalItems: this.analysis.items.length
        };
    }

    /**
     * Check if an item can be completed (prerequisites met)
     * @param {string} itemId - Item ID to check
     * @param {Object} userProgress - Current user progress state
     * @returns {boolean} - True if can be completed
     */
    canComplete(itemId, userProgress) {
        const item = this.analysis.items.find(i => i.id === itemId);

        if (!item) {
            return false;
        }

        return item.canComplete(userProgress);
    }

    /**
     * Get items by type
     * @param {string} type - Item type
     * @returns {Array} - Items of specified type
     */
    getItemsByType(type) {
        return this.analysis.items.filter(item => item.type === type);
    }

    /**
     * Get uncompleted items by type
     * @param {string} type - Item type
     * @returns {Array} - Uncompleted items of specified type
     */
    getUncompletedItemsByType(type) {
        return this.analysis.items.filter(item =>
            item.type === type && !this.completedItems.has(item.id)
        );
    }

    /**
     * Save progress to server
     * @private
     */
    async _saveProgress() {
        try {
            const { default: apiService } = await import('../../services/APIService.js');

            const completedItemsData = Array.from(this.completedItems).map(itemId => {
                const item = this.analysis.items.find(i => i.id === itemId);
                return {
                    id: itemId,
                    type: item.type,
                    completedAt: item.completedAt || new Date().toISOString()
                };
            });

            await apiService.saveProgress({
                system: 'drs-progress',
                bookId: this.bookId,
                chapterId: this.chapterId,
                progressData: {
                    completedItems: completedItemsData,
                    totalWeight: this.analysis.totalWeight,
                    lastUpdated: new Date().toISOString()
                }
            });

            console.log(`💾 Progress saved: ${this.completedItems.size} items`);
        } catch (error) {
            console.error(`❌ Failed to save progress:`, error);
        }
    }

    /**
     * Reset all progress
     */
    async reset() {
        this.completedItems.clear();
        this.analysis.items.forEach(item => item.completedAt = null);
        await this._saveProgress();
        console.log(`🔄 Progress reset for ${this.bookId}/${this.chapterId}`);
    }

    // ========================================
    // ProgressSystemInterface REQUIRED METHODS
    // ========================================

    async markWordDiscovered(word, metadata = {}) {
        this.discoveredWords.add(word);
        await this.markCompleted(`vocab-discovery-${word}`, { word, ...metadata });
    }

    async markWordMastered(word, metadata = {}) {
        this.masteredWords.add(word);
        await this.markCompleted(`vocab-mastery-${word}`, { word, ...metadata });
    }

    isWordDiscovered(word) {
        return this.discoveredWords.has(word) || this.completedItems.has(`vocab-discovery-${word}`);
    }

    isWordMastered(word) {
        return this.masteredWords.has(word) || this.completedItems.has(`vocab-mastery-${word}`);
    }

    async markPhraseCompleted(phraseId, metadata = {}) {
        await this.markCompleted(`phrase-${phraseId}`, metadata);
    }

    async markDialogCompleted(dialogId, metadata = {}) {
        await this.markCompleted(`dialog-${dialogId}`, metadata);
    }

    async markTextCompleted(textId, metadata = {}) {
        await this.markCompleted(`text-${textId}`, metadata);
    }

    async markAudioCompleted(audioId, metadata = {}) {
        await this.markCompleted(`audio-${audioId}`, metadata);
    }

    async markImageCompleted(imageId, metadata = {}) {
        await this.markCompleted(`image-${imageId}`, metadata);
    }

    async markGrammarCompleted(grammarId, metadata = {}) {
        await this.markCompleted(`grammar-${grammarId}`, metadata);
    }

    canComplete(itemType, itemId, context = {}) {
        const item = this.analysis?.items.find(i => i.id === itemId && i.type === itemType);
        if (!item) {
            return { canComplete: false, reason: 'Item not found', missingPrereqs: [] };
        }

        const userProgress = {
            discoveredWords: Array.from(this.discoveredWords),
            masteredWords: Array.from(this.masteredWords)
        };

        const canComplete = item.canComplete(userProgress);
        return {
            canComplete,
            reason: canComplete ? 'Prerequisites met' : 'Prerequisites not met',
            missingPrereqs: canComplete ? [] : ['Check vocabulary prerequisites']
        };
    }

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

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

export default ProgressTracker;
