// 서비스 워커 해제 (push-sw.js 제외)
if ('serviceWorker' in navigator) {
    navigator.serviceWorker.getRegistrations().then(function(registrations) {
        registrations.forEach(function(registration) {
            if (!registration.active || !registration.active.scriptURL.includes('push-sw.js')) {
                registration.unregister();
            }
        });
    });
    if (typeof caches !== 'undefined') {
        caches.keys().then(function(names) {
            names.forEach(function(name) { caches.delete(name); });
        });
    }
}

/**
 * 중앙화된 인증 관리자
 * 페이지 간 이동 시 불필요한 API 호출을 방지하고 인증 상태를 효율적으로 관리
 */
class AuthManager {
    constructor() {
        this.currentUser = null;
        this.isAuthenticated = false;
        this.lastAuthCheck = null;
        this.authCheckInterval = 5 * 60 * 1000; // 5분마다 토큰 유효성 체크
        this.listeners = new Set();
        
        // 초기화
        this.init();
    }
    
    /**
     * 초기화
     */
    init() {
        
        // localStorage에서 사용자 정보 복원
        this.restoreUserFromStorage();
        
        // 토큰 만료 체크 타이머 설정
        this.setupTokenExpiryCheck();
        
        // 페이지 가시성 변경 시 토큰 체크
        document.addEventListener('visibilitychange', () => {
            if (!document.hidden && this.shouldCheckAuth()) {
                this.refreshAuth();
            }
        });
    }
    
    /**
     * 쿠키에서 값 읽기
     */
    _cookieGet(name) {
        const match = document.cookie.match(new RegExp('(?:^|; )' + name + '=([^;]*)'));
        return match ? decodeURIComponent(match[1]) : null;
    }

    /**
     * 쿠키 삭제
     */
    _cookieRemove(name) {
        let cookie = name + '=; path=/; max-age=0';
        if (window.location.hostname.includes('technicalkorea.net')) {
            cookie += '; domain=.technicalkorea.net; secure; samesite=lax';
        }
        document.cookie = cookie;
    }

    /**
     * SSO 토큰 가져오기 (쿠키 우선, localStorage 폴백)
     */
    _getToken() {
        return this._cookieGet('sso_token');
    }

    /**
     * SSO 사용자 정보 가져오기 (쿠키 우선, localStorage 폴백)
     */
    _getUser() {
        const ssoUser = this._cookieGet('sso_user');
        if (ssoUser && ssoUser !== 'undefined' && ssoUser !== 'null') {
            try { return JSON.parse(ssoUser); } catch(e) {}
        }
        return null;
    }

    /**
     * 중앙 로그인 URL
     */
    _getLoginUrl() {
        const hostname = window.location.hostname;
        if (hostname.includes('technicalkorea.net')) {
            return window.location.protocol + '//tkds.technicalkorea.net/dashboard?redirect=' + encodeURIComponent(window.location.href);
        }
        return window.location.protocol + '//' + hostname + ':30000/dashboard?redirect=' + encodeURIComponent(window.location.href);
    }

    /**
     * 저장소에서 사용자 정보 복원 (SSO 쿠키 + localStorage)
     */
    restoreUserFromStorage() {
        // 쿠키 우선 검증: 쿠키 없고 localStorage에만 토큰이 있으면 정리
        const cookieToken = this._cookieGet('sso_token');
        const localToken = localStorage.getItem('sso_token');
        if (!cookieToken && localToken) {
            ['sso_token','sso_user','sso_refresh_token','token','user','access_token',
             'currentUser','current_user','userInfo','userPageAccess'].forEach(k => localStorage.removeItem(k));
            return;
        }

        const token = this._getToken();
        const user = this._getUser();

        if (token && user) {
            try {
                this.currentUser = user;
                this.isAuthenticated = true;
                this.lastAuthCheck = Date.now();
            } catch (error) {
                console.error('사용자 정보 복원 실패:', error);
                this.clearAuth();
            }
        }
    }
    
    /**
     * 인증이 필요한지 확인
     */
    shouldCheckAuth() {
        if (!this.isAuthenticated) return true;
        if (!this.lastAuthCheck) return true;
        
        const timeSinceLastCheck = Date.now() - this.lastAuthCheck;
        return timeSinceLastCheck > this.authCheckInterval;
    }
    
    /**
     * 인증 상태 확인 (필요시에만 API 호출)
     */
    async checkAuth() {
        const token = this._getToken();
        if (!token) {
            this.clearAuth();
            return null;
        }

        // 최근에 체크했으면 캐시된 정보 사용
        if (this.isAuthenticated && !this.shouldCheckAuth()) {
            return this.currentUser;
        }

        return await this.refreshAuth();
    }
    
    /**
     * 강제로 인증 정보 새로고침 (API 호출)
     */
    async refreshAuth() {
        try {
            await this.waitForAPI();

            const user = await AuthAPI.getCurrentUser();

            this.currentUser = user;
            this.isAuthenticated = true;
            this.lastAuthCheck = Date.now();

            // localStorage 업데이트 (쿠키 소실 대비 백업)
            const token = this._getToken();
            if (token) localStorage.setItem('sso_token', token);
            localStorage.setItem('sso_user', JSON.stringify(user));

            this.notifyListeners('auth-success', user);
            return user;

        } catch (error) {
            console.error('인증 실패:', error);
            this.clearAuth();
            this.notifyListeners('auth-failed', error);
            return null;
        }
    }
    
    /**
     * API 로드 대기
     */
    async waitForAPI() {
        let attempts = 0;
        const maxAttempts = 50;
        
        while (typeof AuthAPI === 'undefined' && attempts < maxAttempts) {
            await new Promise(resolve => setTimeout(resolve, 100));
            attempts++;
        }
        
        if (typeof AuthAPI === 'undefined') {
            throw new Error('AuthAPI를 로드할 수 없습니다');
        }
    }
    
    /**
     * 인증 정보 클리어
     */
    clearAuth() {
        this.currentUser = null;
        this.isAuthenticated = false;
        this.lastAuthCheck = null;

        // SSO 쿠키 삭제
        this._cookieRemove('sso_token');
        this._cookieRemove('sso_user');
        this._cookieRemove('sso_refresh_token');

        // localStorage 삭제 (전 시스템 키 통일)
        ['sso_token','sso_user','sso_refresh_token','token','user','access_token','currentUser','current_user','userInfo','userPageAccess'].forEach(k => {
            localStorage.removeItem(k);
        });

        this.notifyListeners('auth-cleared');
    }
    
    /**
     * 로그인 처리
     */
    async login(username, password) {
        try {
            await this.waitForAPI();
            const data = await AuthAPI.login(username, password);

            this.currentUser = data.user;
            this.isAuthenticated = true;
            this.lastAuthCheck = Date.now();

            // localStorage 저장 (sso_token/sso_user로 통일)
            localStorage.setItem('sso_token', data.access_token);
            localStorage.setItem('sso_user', JSON.stringify(data.user));

            this.notifyListeners('login-success', data.user);
            return data;

        } catch (error) {
            console.error('로그인 실패:', error);
            this.clearAuth();
            throw error;
        }
    }
    
    /**
     * 로그아웃 처리
     */
    logout() {
        this.clearAuth();
        this.notifyListeners('logout');
        window.location.href = this._getLoginUrl() + '&logout=1';
    }
    
    /**
     * 토큰 만료 체크 타이머 설정
     */
    setupTokenExpiryCheck() {
        setInterval(() => {
            if (this.isAuthenticated) {
                this.refreshAuth().then(user => {
                    if (!user) {
                        // 인증 실패 — clearAuth()는 refreshAuth 내부에서 이미 처리됨
                        this.notifyListeners('token-expired');
                    }
                });
            }
        }, 30 * 60 * 1000);
    }
    
    /**
     * 이벤트 리스너 등록
     */
    addEventListener(callback) {
        this.listeners.add(callback);
    }
    
    /**
     * 이벤트 리스너 제거
     */
    removeEventListener(callback) {
        this.listeners.delete(callback);
    }
    
    /**
     * 리스너들에게 알림
     */
    notifyListeners(event, data = null) {
        this.listeners.forEach(callback => {
            try {
                callback(event, data);
            } catch (error) {
                console.error('리스너 콜백 오류:', error);
            }
        });
    }
    
    /**
     * 현재 사용자 정보 반환
     */
    getCurrentUser() {
        return this.currentUser;
    }
    
    /**
     * 인증 상태 반환
     */
    isLoggedIn() {
        return this.isAuthenticated && !!this.currentUser;
    }
}

// 전역 인스턴스 생성
window.authManager = new AuthManager();

