/**
 * 페이지 프리로더
 * 사용자가 방문할 가능성이 높은 페이지들을 미리 로드하여 성능 향상
 */

class PagePreloader {
    constructor() {
        this.preloadedPages = new Set();
        this.preloadQueue = [];
        this.isPreloading = false;
        this.preloadCache = new Map();
        this.resourceCache = new Map();
    }

    /**
     * 프리로더 초기화
     */
    init() {
        // 유휴 시간에 프리로딩 시작
        this.schedulePreloading();

        // 링크 호버 시 프리로딩
        this.setupHoverPreloading();

        // 기존 서비스 워커 해제 (캐시 문제 방지)
        this.unregisterServiceWorker();
    }

    /**
     * 우선순위 기반 프리로딩 스케줄링
     */
    schedulePreloading() {
        // 현재 사용자 권한에 따른 접근 가능한 페이지들
        const accessiblePages = this.getAccessiblePages();
        
        // 우선순위 설정
        const priorityPages = this.getPriorityPages(accessiblePages);
        
        // 유휴 시간에 프리로딩 시작
        if ('requestIdleCallback' in window) {
            requestIdleCallback(() => {
                this.startPreloading(priorityPages);
            }, { timeout: 2000 });
        } else {
            // requestIdleCallback 미지원 브라우저
            setTimeout(() => {
                this.startPreloading(priorityPages);
            }, 1000);
        }
    }

    /**
     * 접근 가능한 페이지 목록 가져오기
     */
    getAccessiblePages() {
        const allPages = [
            { id: 'issues_create', url: '/index.html', priority: 1 },
            { id: 'issues_view', url: '/issue-view.html', priority: 1 },
            { id: 'issues_manage', url: '/index.html#list', priority: 2 },
            { id: 'reports', url: '/reports.html', priority: 3 }
        ];

        // 권한 체크
        return allPages.filter(page => {
            if (!window.canAccessPage) return false;
            return window.canAccessPage(page.id);
        });
    }

    /**
     * 우선순위 기반 페이지 정렬
     */
    getPriorityPages(pages) {
        return pages
            .sort((a, b) => a.priority - b.priority)
            .slice(0, 3); // 최대 3개 페이지만 프리로드
    }

    /**
     * 프리로딩 시작
     */
    async startPreloading(pages) {
        if (this.isPreloading) return;
        
        this.isPreloading = true;

        for (const page of pages) {
            if (this.preloadedPages.has(page.url)) continue;
            
            try {
                await this.preloadPage(page);
                
                // 네트워크 상태 확인 (느린 연결에서는 중단)
                if (this.isSlowConnection()) {
                    break;
                }
                
                // CPU 부하 방지를 위한 딜레이
                await this.delay(500);
                
            } catch (error) {
                console.warn('프리로딩 실패:', page.id, error);
            }
        }

        this.isPreloading = false;
    }

    /**
     * 개별 페이지 프리로드
     */
    async preloadPage(page) {
        try {
            // HTML 프리로드
            const htmlResponse = await fetch(page.url, {
                method: 'GET',
                headers: { 'Accept': 'text/html' }
            });
            
            if (htmlResponse.ok) {
                const html = await htmlResponse.text();
                this.preloadCache.set(page.url, html);
                
                // 페이지 내 리소스 추출 및 프리로드
                await this.preloadPageResources(html, page.url);
                
                this.preloadedPages.add(page.url);
            }
            
        } catch (error) {
            console.warn(`프리로드 실패: ${page.id}`, error);
        }
    }

    /**
     * 페이지 리소스 프리로드 (CSS, JS)
     */
    async preloadPageResources(html, baseUrl) {
        const parser = new DOMParser();
        const doc = parser.parseFromString(html, 'text/html');
        
        // CSS 파일 프리로드
        const cssLinks = doc.querySelectorAll('link[rel="stylesheet"]');
        for (const link of cssLinks) {
            const href = this.resolveUrl(link.href, baseUrl);
            if (!this.resourceCache.has(href)) {
                this.preloadResource(href, 'style');
            }
        }
        
        // JS 파일 프리로드 (중요한 것만)
        const scriptTags = doc.querySelectorAll('script[src]');
        for (const script of scriptTags) {
            const src = this.resolveUrl(script.src, baseUrl);
            if (this.isImportantScript(src) && !this.resourceCache.has(src)) {
                this.preloadResource(src, 'script');
            }
        }
    }

    /**
     * 리소스 프리로드
     */
    preloadResource(url, type) {
        const link = document.createElement('link');
        link.rel = 'preload';
        link.href = url;
        link.as = type;
        
        link.onload = () => {
            this.resourceCache.set(url, true);
        };
        
        link.onerror = () => {
            console.warn('리소스 프리로드 실패:', url);
        };
        
        document.head.appendChild(link);
    }

    /**
     * 중요한 스크립트 판별
     */
    isImportantScript(src) {
        const importantScripts = [
            'api.js',
            'permissions.js',
            'common-header.js',
            'page-manager.js'
        ];
        
        return importantScripts.some(script => src.includes(script));
    }

    /**
     * URL 해결
     */
    resolveUrl(url, baseUrl) {
        if (url.startsWith('http') || url.startsWith('//')) {
            return url;
        }
        
        const base = new URL(baseUrl, window.location.origin);
        return new URL(url, base).href;
    }

    /**
     * 호버 시 프리로딩 설정
     */
    setupHoverPreloading() {
        let hoverTimeout;
        
        document.addEventListener('mouseover', (e) => {
            const link = e.target.closest('a[href]');
            if (!link) return;
            
            const href = link.getAttribute('href');
            if (!href || href.startsWith('#') || href.startsWith('javascript:')) return;
            
            // 300ms 후 프리로드 (실제 클릭 의도 확인)
            hoverTimeout = setTimeout(() => {
                this.preloadOnHover(href);
            }, 300);
        });
        
        document.addEventListener('mouseout', (e) => {
            if (hoverTimeout) {
                clearTimeout(hoverTimeout);
                hoverTimeout = null;
            }
        });
    }

    /**
     * 호버 시 프리로드
     */
    async preloadOnHover(url) {
        if (this.preloadedPages.has(url)) return;
        
        try {
            const response = await fetch(url, {
                method: 'GET',
                headers: { 'Accept': 'text/html' }
            });
            
            if (response.ok) {
                const html = await response.text();
                this.preloadCache.set(url, html);
                this.preloadedPages.add(url);
            }
        } catch (error) {
            console.warn('호버 프리로드 실패:', url, error);
        }
    }

    /**
     * 느린 연결 감지
     */
    isSlowConnection() {
        if ('connection' in navigator) {
            const connection = navigator.connection;
            return connection.effectiveType === 'slow-2g' || 
                   connection.effectiveType === '2g' ||
                   connection.saveData === true;
        }
        return false;
    }

    /**
     * 딜레이 유틸리티
     */
    delay(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    /**
     * 기존 서비스 워커 해제 및 캐시 정리
     */
    async unregisterServiceWorker() {
        if ('serviceWorker' in navigator) {
            try {
                const registrations = await navigator.serviceWorker.getRegistrations();
                for (const registration of registrations) {
                    if (!registration.active || !registration.active.scriptURL.includes('push-sw.js')) {
                        await registration.unregister();
                    }
                }
                // 모든 캐시 삭제
                const cacheNames = await caches.keys();
                await Promise.all(cacheNames.map(name => caches.delete(name)));
            } catch (error) {
                // 무시
            }
        }
    }

    /**
     * 프리로드된 페이지 가져오기
     */
    getPreloadedPage(url) {
        return this.preloadCache.get(url);
    }

    /**
     * 캐시 정리
     */
    clearCache() {
        this.preloadCache.clear();
        this.resourceCache.clear();
        this.preloadedPages.clear();
    }
}

// 전역 인스턴스
window.pagePreloader = new PagePreloader();
