/**
 * ModuleLoader - 지연 로딩 및 모듈 관리
 * 필요한 모듈만 동적으로 로드하여 성능을 최적화합니다.
 */
class ModuleLoader {
    constructor() {
        console.log('🔧 ModuleLoader 초기화 시작');
        
        // 로드된 모듈 캐시
        this.loadedModules = new Map();
        
        // 로딩 중인 모듈 Promise 캐시 (중복 로딩 방지)
        this.loadingPromises = new Map();
        
        // 모듈 의존성 정의
        this.moduleDependencies = {
            'DocumentLoader': [],
            'HighlightManager': ['DocumentLoader'],
            'BookmarkManager': ['DocumentLoader'],
            'LinkManager': ['DocumentLoader'],
            'UIManager': []
        };
        
        // 모듈 경로 정의
        this.modulePaths = {
            'DocumentLoader': '/static/js/viewer/core/document-loader.js',
            'HighlightManager': '/static/js/viewer/features/highlight-manager.js',
            'BookmarkManager': '/static/js/viewer/features/bookmark-manager.js',
            'LinkManager': '/static/js/viewer/features/link-manager.js',
            'UIManager': '/static/js/viewer/features/ui-manager.js'
        };
        
        // 캐시 버스팅을 위한 버전
        this.version = '2025012607';
        
        console.log('✅ ModuleLoader 초기화 완료');
    }

    /**
     * 모듈 동적 로드
     */
    async loadModule(moduleName) {
        // 이미 로드된 모듈인지 확인
        if (this.loadedModules.has(moduleName)) {
            console.log(`✅ 모듈 캐시에서 반환: ${moduleName}`);
            return this.loadedModules.get(moduleName);
        }

        // 이미 로딩 중인 모듈인지 확인 (중복 로딩 방지)
        if (this.loadingPromises.has(moduleName)) {
            console.log(`⏳ 모듈 로딩 대기 중: ${moduleName}`);
            return await this.loadingPromises.get(moduleName);
        }

        console.log(`🔄 모듈 로딩 시작: ${moduleName}`);

        // 로딩 Promise 생성 및 캐시
        const loadingPromise = this._loadModuleScript(moduleName);
        this.loadingPromises.set(moduleName, loadingPromise);

        try {
            const moduleClass = await loadingPromise;
            
            // 로딩 완료 후 캐시에 저장
            this.loadedModules.set(moduleName, moduleClass);
            this.loadingPromises.delete(moduleName);
            
            console.log(`✅ 모듈 로딩 완료: ${moduleName}`);
            return moduleClass;
            
        } catch (error) {
            console.error(`❌ 모듈 로딩 실패: ${moduleName}`, error);
            this.loadingPromises.delete(moduleName);
            throw error;
        }
    }

    /**
     * 의존성을 포함한 모듈 로드
     */
    async loadModuleWithDependencies(moduleName) {
        console.log(`🔗 의존성 포함 모듈 로딩: ${moduleName}`);
        
        // 의존성 먼저 로드
        const dependencies = this.moduleDependencies[moduleName] || [];
        if (dependencies.length > 0) {
            console.log(`📦 의존성 로딩: ${dependencies.join(', ')}`);
            await Promise.all(dependencies.map(dep => this.loadModule(dep)));
        }
        
        // 메인 모듈 로드
        return await this.loadModule(moduleName);
    }

    /**
     * 여러 모듈 병렬 로드
     */
    async loadModules(moduleNames) {
        console.log(`🚀 병렬 모듈 로딩: ${moduleNames.join(', ')}`);
        
        const loadPromises = moduleNames.map(name => this.loadModuleWithDependencies(name));
        const results = await Promise.all(loadPromises);
        
        console.log(`✅ 병렬 모듈 로딩 완료: ${moduleNames.join(', ')}`);
        return results;
    }

    /**
     * 스크립트 동적 로딩
     */
    async _loadModuleScript(moduleName) {
        return new Promise((resolve, reject) => {
            // 이미 전역에 클래스가 있는지 확인
            if (window[moduleName]) {
                console.log(`✅ 모듈 이미 로드됨: ${moduleName}`);
                resolve(window[moduleName]);
                return;
            }

            console.log(`📥 스크립트 로딩 시작: ${moduleName}`);
            const script = document.createElement('script');
            script.src = `${this.modulePaths[moduleName]}?v=${this.version}`;
            script.async = true;
            
            script.onload = () => {
                console.log(`📥 스크립트 로드 완료: ${moduleName}`);
                
                // 스크립트 로드 후 잠시 대기 (클래스 등록 시간)
                setTimeout(() => {
                    if (window[moduleName]) {
                        console.log(`✅ 모듈 클래스 확인: ${moduleName}`);
                        resolve(window[moduleName]);
                    } else {
                        console.error(`❌ 모듈 클래스 없음: ${moduleName}`, Object.keys(window).filter(k => k.includes('Manager') || k.includes('Loader')));
                        reject(new Error(`모듈 클래스를 찾을 수 없음: ${moduleName}`));
                    }
                }, 10); // 10ms 대기
            };
            
            script.onerror = (error) => {
                console.error(`❌ 스크립트 로딩 실패: ${moduleName}`, error);
                reject(new Error(`스크립트 로딩 실패: ${moduleName}`));
            };
            
            document.head.appendChild(script);
        });
    }

    /**
     * 모듈 인스턴스 생성 (팩토리 패턴)
     */
    async createModuleInstance(moduleName, ...args) {
        const ModuleClass = await this.loadModuleWithDependencies(moduleName);
        return new ModuleClass(...args);
    }

    /**
     * 모듈 프리로딩 (백그라운드에서 미리 로드)
     */
    async preloadModules(moduleNames) {
        console.log(`🔮 모듈 프리로딩: ${moduleNames.join(', ')}`);
        
        // 백그라운드에서 로드 (에러 무시)
        const preloadPromises = moduleNames.map(async (name) => {
            try {
                await this.loadModuleWithDependencies(name);
                console.log(`✅ 프리로딩 완료: ${name}`);
            } catch (error) {
                console.warn(`⚠️ 프리로딩 실패: ${name}`, error);
            }
        });
        
        // 모든 프리로딩이 완료될 때까지 기다리지 않음
        Promise.all(preloadPromises);
    }

    /**
     * 사용하지 않는 모듈 언로드 (메모리 최적화)
     */
    unloadModule(moduleName) {
        if (this.loadedModules.has(moduleName)) {
            this.loadedModules.delete(moduleName);
            console.log(`🗑️ 모듈 언로드: ${moduleName}`);
        }
    }

    /**
     * 모든 모듈 언로드
     */
    unloadAllModules() {
        this.loadedModules.clear();
        this.loadingPromises.clear();
        console.log('🗑️ 모든 모듈 언로드 완료');
    }

    /**
     * 로드된 모듈 상태 확인
     */
    getLoadedModules() {
        return Array.from(this.loadedModules.keys());
    }

    /**
     * 메모리 사용량 추정
     */
    getMemoryUsage() {
        const loadedCount = this.loadedModules.size;
        const loadingCount = this.loadingPromises.size;
        
        return {
            loadedModules: loadedCount,
            loadingModules: loadingCount,
            totalModules: Object.keys(this.modulePaths).length,
            memoryEstimate: `${loadedCount * 50}KB` // 대략적인 추정
        };
    }
}

// 전역 모듈 로더 인스턴스
window.moduleLoader = new ModuleLoader();

// 전역으로 내보내기
window.ModuleLoader = ModuleLoader;
