/**
 * ImplementationValidator - Validates all progress item implementations at startup
 * Ensures ALL required methods are implemented before app runs
 */

import VocabularyDiscoveryItem from '../progress-items/VocabularyDiscoveryItem.js';
import VocabularyMasteryItem from '../progress-items/VocabularyMasteryItem.js';
import {
    PhraseItem,
    DialogItem,
    TextItem,
    AudioItem,
    ImageItem,
    GrammarItem
} from '../progress-items/ContentProgressItems.js';

class ImplementationValidator {
    static async validateAll() {
        console.log('%c🔍 VALIDATING DRS IMPLEMENTATIONS...',
            'background: #3b82f6; color: white; font-size: 16px; padding: 8px; font-weight: bold;'
        );

        const errors = [];
        const validations = [];

        // ========================================
        // 1. VALIDATE PROGRESS ITEMS
        // ========================================
        console.log('%c📦 PART 1: Validating Progress Items...',
            'background: #6366f1; color: white; font-size: 14px; padding: 6px; font-weight: bold;'
        );

        // Test VocabularyDiscoveryItem
        validations.push(
            this._testItem('VocabularyDiscoveryItem', () =>
                new VocabularyDiscoveryItem('test', { user_language: 'test' })
            )
        );

        // Test VocabularyMasteryItem
        validations.push(
            this._testItem('VocabularyMasteryItem', () =>
                new VocabularyMasteryItem('test', { user_language: 'test' })
            )
        );

        // Test PhraseItem
        validations.push(
            this._testItem('PhraseItem', () =>
                new PhraseItem('test', { text: 'test' })
            )
        );

        // Test DialogItem
        validations.push(
            this._testItem('DialogItem', () =>
                new DialogItem('test', { title: 'test' })
            )
        );

        // Test TextItem
        validations.push(
            this._testItem('TextItem', () =>
                new TextItem('test', { content: 'test' })
            )
        );

        // Test AudioItem
        validations.push(
            this._testItem('AudioItem', () =>
                new AudioItem('test', { url: 'test' })
            )
        );

        // Test ImageItem
        validations.push(
            this._testItem('ImageItem', () =>
                new ImageItem(0, { url: 'test' })
            )
        );

        // Test GrammarItem
        validations.push(
            this._testItem('GrammarItem', () =>
                new GrammarItem(0, { rule: 'test' })
            )
        );

        // Wait for all item validations
        const itemResults = await Promise.allSettled(validations);

        itemResults.forEach((result, index) => {
            if (result.status === 'rejected') {
                errors.push(result.reason);
            }
        });

        // ========================================
        // 2. VALIDATE PROGRESS SYSTEMS
        // ========================================
        console.log('%c🔧 PART 2: Validating Progress Systems...',
            'background: #6366f1; color: white; font-size: 14px; padding: 6px; font-weight: bold;'
        );

        const systemValidations = [];

        // Test ProgressTracker (if it implements ProgressSystemInterface)
        systemValidations.push(
            this._testProgressSystem('ProgressTracker', async () => {
                const { default: ProgressTracker } = await import('./ProgressTracker.js');
                return ProgressTracker;
            })
        );

        // Test PrerequisiteEngine (if it implements ProgressSystemInterface)
        systemValidations.push(
            this._testProgressSystem('PrerequisiteEngine', async () => {
                const { default: PrerequisiteEngine } = await import('./PrerequisiteEngine.js');
                return PrerequisiteEngine;
            })
        );

        const systemResults = await Promise.allSettled(systemValidations);

        systemResults.forEach((result, index) => {
            if (result.status === 'rejected') {
                errors.push(result.reason);
            }
        });

        // ========================================
        // 3. VALIDATE DRS EXERCISE MODULES
        // ========================================
        console.log('%c🎮 PART 3: Validating DRS Exercise Modules...',
            'background: #6366f1; color: white; font-size: 14px; padding: 6px; font-weight: bold;'
        );

        const exerciseValidations = [];

        // Test VocabularyModule
        exerciseValidations.push(
            this._testExerciseModule('VocabularyModule', async () => {
                const { default: VocabularyModule } = await import('../exercise-modules/VocabularyModule.js');
                return VocabularyModule;
            })
        );

        // Test TextAnalysisModule
        exerciseValidations.push(
            this._testExerciseModule('TextAnalysisModule', async () => {
                const { default: TextAnalysisModule } = await import('../exercise-modules/TextAnalysisModule.js');
                return TextAnalysisModule;
            })
        );

        // Test GrammarAnalysisModule
        exerciseValidations.push(
            this._testExerciseModule('GrammarAnalysisModule', async () => {
                const { default: GrammarAnalysisModule } = await import('../exercise-modules/GrammarAnalysisModule.js');
                return GrammarAnalysisModule;
            })
        );

        // Test TranslationModule
        exerciseValidations.push(
            this._testExerciseModule('TranslationModule', async () => {
                const { default: TranslationModule } = await import('../exercise-modules/TranslationModule.js');
                return TranslationModule;
            })
        );

        // Test OpenResponseModule
        exerciseValidations.push(
            this._testExerciseModule('OpenResponseModule', async () => {
                const { default: OpenResponseModule } = await import('../exercise-modules/OpenResponseModule.js');
                return OpenResponseModule;
            })
        );

        const exerciseResults = await Promise.allSettled(exerciseValidations);

        exerciseResults.forEach((result, index) => {
            if (result.status === 'rejected') {
                errors.push(result.reason);
            }
        });

        // ========================================
        // FINAL RESULT
        // ========================================
        if (errors.length > 0) {
            console.error('%c❌ VALIDATION FAILED',
                'background: red; color: white; font-size: 20px; padding: 10px; font-weight: bold;'
            );
            errors.forEach(e => console.error(e));
            return false;
        }

        console.log('%c✅ ALL DRS IMPLEMENTATIONS VALID',
            'background: #10b981; color: white; font-size: 16px; padding: 8px; font-weight: bold;'
        );
        return true;
    }

    static async _testItem(className, createFn) {
        try {
            const item = createFn();

            // Test all required methods
            const requiredMethods = ['validate', 'serialize', 'getWeight', 'canComplete'];
            const mockUserProgress = { discoveredWords: [], masteredWords: [] };

            requiredMethods.forEach(method => {
                if (typeof item[method] !== 'function') {
                    throw new Error(`${className}: Missing method ${method}()`);
                }
            });

            // Actually call the methods to ensure they don't throw
            item.validate();
            item.serialize();
            item.getWeight();
            item.canComplete(mockUserProgress);

            console.log(`✅ ${className} - OK`);
            return true;
        } catch (error) {
            console.error(`❌ ${className} - FAILED:`, error.message);
            throw error;
        }
    }

    static async _testProgressSystem(systemName, loadFn) {
        try {
            const SystemClass = await loadFn();

            // Required methods from ProgressSystemInterface
            const requiredMethods = [
                // Vocabulary
                'markWordDiscovered',
                'markWordMastered',
                'isWordDiscovered',
                'isWordMastered',
                // Content
                'markPhraseCompleted',
                'markDialogCompleted',
                'markTextCompleted',
                'markAudioCompleted',
                'markImageCompleted',
                'markGrammarCompleted',
                // Prerequisites
                'canComplete',
                // Progress
                'getProgress',
                // Persistence
                'saveProgress',
                'loadProgress',
                // Utility
                'reset'
            ];

            const missingMethods = [];

            // Check prototype for methods
            requiredMethods.forEach(method => {
                if (typeof SystemClass.prototype[method] !== 'function') {
                    missingMethods.push(method);
                }
            });

            if (missingMethods.length > 0) {
                throw new Error(
                    `${systemName} is missing ProgressSystemInterface methods: ${missingMethods.join(', ')}`
                );
            }

            console.log(`✅ ${systemName} - OK`);
            return true;
        } catch (error) {
            console.error(`❌ ${systemName} - FAILED:`, error.message);
            throw error;
        }
    }

    static async _testExerciseModule(moduleName, loadFn) {
        try {
            const ModuleClass = await loadFn();

            // Required methods from DRSExerciseInterface
            const requiredMethods = [
                // Lifecycle
                'init',
                'render',
                'destroy',
                // Exercise logic
                'validate',
                'getResults',
                'handleUserInput',
                // Progress tracking
                'markCompleted',
                'getProgress',
                // Metadata
                'getExerciseType',
                'getExerciseConfig'
            ];

            const missingMethods = [];

            // Check prototype for methods
            requiredMethods.forEach(method => {
                if (typeof ModuleClass.prototype[method] !== 'function') {
                    missingMethods.push(method);
                }
            });

            if (missingMethods.length > 0) {
                throw new Error(
                    `${moduleName} is missing DRSExerciseInterface methods: ${missingMethods.join(', ')}`
                );
            }

            console.log(`✅ ${moduleName} - OK`);
            return true;
        } catch (error) {
            console.error(`❌ ${moduleName} - FAILED:`, error.message);
            throw error;
        }
    }
}

export default ImplementationValidator;
