/**
 * 공통 헤더 컴포넌트
 * 권한 기반으로 메뉴를 동적으로 생성하고 부드러운 페이지 전환을 제공
 */

class CommonHeader {
    constructor() {
        this.currentUser = null;
        this.currentPage = '';
        this.menuItems = this.initMenuItems();
    }

    /**
     * 메뉴 아이템 정의
     */
    initMenuItems() {
        return [
            {
                id: 'issues_dashboard',
                title: '현황판',
                icon: 'fas fa-chart-line',
                url: '/issues-dashboard.html',
                pageName: 'issues_dashboard',
                color: 'text-slate-600',
                bgColor: 'text-slate-600 hover:bg-slate-100'
            },
            {
                id: 'issues_inbox',
                title: '수신함',
                icon: 'fas fa-inbox',
                url: '/issues-inbox.html',
                pageName: 'issues_inbox',
                color: 'text-slate-600',
                bgColor: 'text-slate-600 hover:bg-slate-100'
            },
            {
                id: 'issues_management',
                title: '관리함',
                icon: 'fas fa-cog',
                url: '/issues-management.html',
                pageName: 'issues_management',
                color: 'text-slate-600',
                bgColor: 'text-slate-600 hover:bg-slate-100'
            },
            {
                id: 'issues_archive',
                title: '폐기함',
                icon: 'fas fa-archive',
                url: '/issues-archive.html',
                pageName: 'issues_archive',
                color: 'text-slate-600',
                bgColor: 'text-slate-600 hover:bg-slate-100'
            },
            {
                id: 'reports',
                title: '보고서',
                icon: 'fas fa-chart-bar',
                url: '/reports.html',
                pageName: 'reports',
                color: 'text-slate-600',
                bgColor: 'text-slate-600 hover:bg-slate-100',
                subMenus: [
                    {
                        id: 'reports_daily',
                        title: '일일보고서',
                        icon: 'fas fa-file-excel',
                        url: '/reports-daily.html',
                        pageName: 'reports_daily',
                        color: 'text-slate-600'
                    },
                    {
                        id: 'reports_weekly',
                        title: '주간보고서',
                        icon: 'fas fa-calendar-week',
                        url: '/reports-weekly.html',
                        pageName: 'reports_weekly',
                        color: 'text-slate-600'
                    },
                    {
                        id: 'reports_monthly',
                        title: '월간보고서',
                        icon: 'fas fa-calendar-alt',
                        url: '/reports-monthly.html',
                        pageName: 'reports_monthly',
                        color: 'text-slate-600'
                    }
                ]
            },
            {
                id: 'ai_assistant',
                title: 'AI 어시스턴트',
                icon: 'fas fa-robot',
                url: '/ai-assistant.html',
                pageName: 'ai_assistant',
                color: 'text-purple-600',
                bgColor: 'text-purple-600 hover:bg-purple-50'
            },
            {
                id: 'report',
                title: '신고',
                icon: 'fas fa-exclamation-triangle',
                url: this.getReportUrl(),
                pageName: 'report',
                color: 'text-orange-600',
                bgColor: 'text-orange-600 hover:bg-orange-50',
                external: true
            },
        ];
    }

    /**
     * tkreport URL 생성
     */
    getReportUrl() {
        var host = window.location.hostname;
        var protocol = window.location.protocol;
        if (host.includes('technicalkorea.net')) {
            return protocol + '//tkreport.technicalkorea.net/pages/safety/issue-report.html';
        }
        return protocol + '//' + host + ':30100/pages/safety/issue-report.html';
    }

    /**
     * 헤더 초기화
     * @param {Object} user - 현재 사용자 정보
     * @param {string} currentPage - 현재 페이지 ID
     */
    async init(user, currentPage = '') {
        this.currentUser = user;
        this.currentPage = currentPage;
        
        // 권한 시스템이 로드될 때까지 대기
        await this.waitForPermissionSystem();
        
        this.render();
        this.bindEvents();
        
        // 키보드 단축키 초기화
        this.initializeKeyboardShortcuts();
        
        // 페이지 프리로더 초기화
        this.initializePreloader();
    }

    /**
     * 권한 시스템 로드 대기
     */
    async waitForPermissionSystem() {
        let attempts = 0;
        const maxAttempts = 50; // 5초 대기
        
        while (!window.pagePermissionManager && attempts < maxAttempts) {
            await new Promise(resolve => setTimeout(resolve, 100));
            attempts++;
        }
        
        if (window.pagePermissionManager && this.currentUser) {
            window.pagePermissionManager.setUser(this.currentUser);
            // 권한 로드 대기
            await new Promise(resolve => setTimeout(resolve, 300));
        }
    }

    /**
     * 헤더 렌더링
     */
    render() {
        const headerHTML = this.generateHeaderHTML();
        
        // 기존 헤더가 있으면 교체, 없으면 body 상단에 추가
        let headerContainer = document.getElementById('common-header');
        if (headerContainer) {
            headerContainer.innerHTML = headerHTML;
        } else {
            headerContainer = document.createElement('div');
            headerContainer.id = 'common-header';
            headerContainer.innerHTML = headerHTML;
            document.body.insertBefore(headerContainer, document.body.firstChild);
        }
    }

    /**
     * 현재 페이지 업데이트
     * @param {string} pageName - 새로운 페이지 이름
     */
    updateCurrentPage(pageName) {
        this.currentPage = pageName;
        this.render();
    }

    /**
     * 헤더 HTML 생성
     */
    generateHeaderHTML() {
        const accessibleMenus = this.getAccessibleMenus();
        const userDisplayName = this.currentUser?.full_name || this.currentUser?.username || '사용자';
        const userRole = this.getUserRoleDisplay();

        return `
            <header class="bg-white shadow-sm border-b sticky top-0 z-50">
                <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
                    <div class="flex justify-between items-center h-16">
                        <!-- 로고 및 제목 -->
                        <div class="flex items-center">
                            <div class="flex-shrink-0 flex items-center">
                                <i class="fas fa-shield-halved text-2xl text-slate-700 mr-3"></i>
                                <h1 class="text-xl font-bold text-gray-900">부적합 관리</h1>
                            </div>
                        </div>

                        <!-- 네비게이션 메뉴 -->
                        <nav class="hidden md:flex space-x-2">
                            ${accessibleMenus.map(menu => this.generateMenuItemHTML(menu)).join('')}
                        </nav>

                        <!-- 사용자 정보 및 메뉴 -->
                        <div class="flex items-center space-x-4">
                            <!-- 사용자 정보 -->
                            <div class="flex items-center space-x-3">
                                <div class="text-right">
                                    <div class="text-sm font-medium text-gray-900">${userDisplayName}</div>
                                    <div class="text-xs text-gray-500">${userRole}</div>
                                </div>
                                <div class="w-8 h-8 bg-slate-600 rounded-full flex items-center justify-center">
                                    <span class="text-white text-sm font-semibold">
                                        ${userDisplayName.charAt(0).toUpperCase()}
                                    </span>
                                </div>
                            </div>

                            <!-- 드롭다운 메뉴 -->
                            <div class="relative">
                                <button id="user-menu-button" class="p-2 text-gray-400 hover:text-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 rounded-md">
                                    <i class="fas fa-chevron-down"></i>
                                </button>
                                <div id="user-menu" class="hidden absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-1 ring-1 ring-black ring-opacity-5">
                                    <a href="#" onclick="CommonHeader.showPasswordModal()" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
                                        <i class="fas fa-key mr-2"></i>비밀번호 변경
                                    </a>
                                    <a href="#" onclick="CommonHeader.logout()" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
                                        <i class="fas fa-sign-out-alt mr-2"></i>로그아웃
                                    </a>
                                </div>
                            </div>

                            <!-- 모바일 메뉴 버튼 -->
                            <button id="mobile-menu-button" class="md:hidden p-2 text-gray-400 hover:text-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 rounded-md">
                                <i class="fas fa-bars"></i>
                            </button>
                        </div>
                    </div>

                    <!-- 모바일 메뉴 -->
                    <div id="mobile-menu" class="md:hidden hidden border-t border-gray-200 py-3">
                        <div class="space-y-1">
                            ${accessibleMenus.map(menu => this.generateMobileMenuItemHTML(menu)).join('')}
                        </div>
                    </div>
                </div>
            </header>
        `;
    }

    /**
     * 접근 가능한 메뉴 필터링
     */
    getAccessibleMenus() {
        return this.menuItems.filter(menu => {
            // admin은 모든 메뉴 접근 가능
            if (this.currentUser?.role === 'admin') {
                // 하위 메뉴가 있는 경우 하위 메뉴도 필터링
                if (menu.subMenus) {
                    menu.accessibleSubMenus = menu.subMenus;
                }
                return true;
            }
            
            // 권한 시스템이 로드되지 않았으면 기본 메뉴만
            if (!window.canAccessPage) {
                return ['issues_dashboard', 'issues_inbox'].includes(menu.id);
            }
            
            // 메인 메뉴 권한 체크
            const hasMainAccess = window.canAccessPage(menu.pageName);
            
            // 하위 메뉴가 있는 경우 접근 가능한 하위 메뉴 필터링
            if (menu.subMenus) {
                menu.accessibleSubMenus = menu.subMenus.filter(subMenu => 
                    window.canAccessPage(subMenu.pageName)
                );
                
                // 메인 메뉴 접근 권한이 없어도 하위 메뉴 중 하나라도 접근 가능하면 표시
                return hasMainAccess || menu.accessibleSubMenus.length > 0;
            }
            
            return hasMainAccess;
        });
    }

    /**
     * 데스크톱 메뉴 아이템 HTML 생성
     */
    generateMenuItemHTML(menu) {
        const isActive = this.currentPage === menu.id;
        const activeClass = isActive ? 'bg-slate-700 text-white' : `${menu.bgColor} ${menu.color}`;

        // 하위 메뉴가 있는 경우 드롭다운 메뉴 생성
        if (menu.accessibleSubMenus && menu.accessibleSubMenus.length > 0) {
            return `
                <div class="relative group">
                    <button class="nav-item flex items-center px-3 py-2 rounded-md text-sm font-medium transition-all duration-200 ${activeClass}"
                            data-page="${menu.id}">
                        <i class="${menu.icon} mr-2"></i>
                        ${menu.title}
                        <i class="fas fa-chevron-down ml-1 text-xs"></i>
                    </button>
                    
                    <!-- 드롭다운 메뉴 -->
                    <div class="absolute left-0 mt-1 w-48 bg-white rounded-md shadow-lg border border-gray-200 opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 z-50">
                        <div class="py-1">
                            ${menu.accessibleSubMenus.map(subMenu => `
                                <a href="${subMenu.url}" 
                                   class="flex items-center px-4 py-2 text-sm text-gray-700 hover:bg-slate-100 ${this.currentPage === subMenu.id ? 'bg-slate-100 text-slate-800 font-medium' : ''}"
                                   data-page="${subMenu.id}"
                                   onclick="CommonHeader.navigateToPage(event, '${subMenu.url}', '${subMenu.id}')">
                                    <i class="${subMenu.icon} mr-3 ${subMenu.color}"></i>
                                    ${subMenu.title}
                                </a>
                            `).join('')}
                        </div>
                    </div>
                </div>
            `;
        }
        
        // 외부 링크 (tkuser 등)
        if (menu.external) {
            return `
                <a href="${menu.url}"
                   class="nav-item flex items-center px-3 py-2 rounded-md text-sm font-medium transition-all duration-200 ${activeClass}"
                   data-page="${menu.id}">
                    <i class="${menu.icon} mr-2"></i>
                    ${menu.title}
                </a>
            `;
        }

        // 일반 메뉴 아이템
        return `
            <a href="${menu.url}"
               class="nav-item flex items-center px-3 py-2 rounded-md text-sm font-medium transition-all duration-200 ${activeClass}"
               data-page="${menu.id}"
               onclick="CommonHeader.navigateToPage(event, '${menu.url}', '${menu.id}')">
                <i class="${menu.icon} mr-2"></i>
                ${menu.title}
            </a>
        `;
    }

    /**
     * 모바일 메뉴 아이템 HTML 생성
     */
    generateMobileMenuItemHTML(menu) {
        const isActive = this.currentPage === menu.id;
        const activeClass = isActive ? 'bg-slate-100 text-slate-800 border-slate-600' : 'text-gray-700 hover:bg-gray-50';
        
        // 하위 메뉴가 있는 경우
        if (menu.accessibleSubMenus && menu.accessibleSubMenus.length > 0) {
            return `
                <div class="mobile-submenu-container">
                    <button class="w-full flex items-center justify-between px-3 py-2 rounded-md text-base font-medium border-l-4 border-transparent ${activeClass}"
                            onclick="this.nextElementSibling.classList.toggle('hidden')"
                            data-page="${menu.id}">
                        <div class="flex items-center">
                            <i class="${menu.icon} mr-3"></i>
                            ${menu.title}
                        </div>
                        <i class="fas fa-chevron-down text-xs"></i>
                    </button>
                    
                    <!-- 하위 메뉴 -->
                    <div class="hidden ml-6 mt-1 space-y-1">
                        ${menu.accessibleSubMenus.map(subMenu => `
                            <a href="${subMenu.url}" 
                               class="flex items-center px-3 py-2 rounded-md text-sm font-medium text-gray-600 hover:bg-slate-100 ${this.currentPage === subMenu.id ? 'bg-slate-100 text-slate-800' : ''}"
                               data-page="${subMenu.id}"
                               onclick="CommonHeader.navigateToPage(event, '${subMenu.url}', '${subMenu.id}')">
                                <i class="${subMenu.icon} mr-3 ${subMenu.color}"></i>
                                ${subMenu.title}
                            </a>
                        `).join('')}
                    </div>
                </div>
            `;
        }
        
        // 외부 링크
        if (menu.external) {
            return `
                <a href="${menu.url}"
                   class="nav-item block px-3 py-2 rounded-md text-base font-medium border-l-4 border-transparent ${activeClass}"
                   data-page="${menu.id}">
                    <i class="${menu.icon} mr-3"></i>
                    ${menu.title}
                </a>
            `;
        }

        // 일반 메뉴 아이템
        return `
            <a href="${menu.url}"
               class="nav-item block px-3 py-2 rounded-md text-base font-medium border-l-4 border-transparent ${activeClass}"
               data-page="${menu.id}"
               onclick="CommonHeader.navigateToPage(event, '${menu.url}', '${menu.id}')">
                <i class="${menu.icon} mr-3"></i>
                ${menu.title}
            </a>
        `;
    }

    /**
     * 사용자 역할 표시명 가져오기
     */
    getUserRoleDisplay() {
        const roleNames = {
            'admin': '관리자',
            'user': '사용자'
        };
        return roleNames[this.currentUser?.role] || '사용자';
    }

    /**
     * 이벤트 바인딩
     */
    bindEvents() {
        // 사용자 메뉴 토글
        const userMenuButton = document.getElementById('user-menu-button');
        const userMenu = document.getElementById('user-menu');
        
        if (userMenuButton && userMenu) {
            userMenuButton.addEventListener('click', (e) => {
                e.stopPropagation();
                userMenu.classList.toggle('hidden');
            });

            // 외부 클릭 시 메뉴 닫기
            document.addEventListener('click', () => {
                userMenu.classList.add('hidden');
            });
        }

        // 모바일 메뉴 토글
        const mobileMenuButton = document.getElementById('mobile-menu-button');
        const mobileMenu = document.getElementById('mobile-menu');
        
        if (mobileMenuButton && mobileMenu) {
            mobileMenuButton.addEventListener('click', () => {
                mobileMenu.classList.toggle('hidden');
            });
        }
    }

    /**
     * 페이지 네비게이션 (부드러운 전환)
     */
    static navigateToPage(event, url, pageId) {
        event.preventDefault();
        
        // 현재 페이지와 같으면 무시
        if (window.commonHeader?.currentPage === pageId) {
            return;
        }

        // 로딩 표시
        CommonHeader.showPageTransition();
        
        // 페이지 이동
        setTimeout(() => {
            window.location.href = url;
        }, 150); // 부드러운 전환을 위한 딜레이
    }

    /**
     * 페이지 전환 로딩 표시
     */
    static showPageTransition() {
        // 기존 로딩이 있으면 제거
        const existingLoader = document.getElementById('page-transition-loader');
        if (existingLoader) {
            existingLoader.remove();
        }

        const loader = document.createElement('div');
        loader.id = 'page-transition-loader';
        loader.className = 'fixed inset-0 bg-white bg-opacity-75 flex items-center justify-center z-50';
        loader.innerHTML = `
            <div class="text-center">
                <div class="inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
                <p class="mt-2 text-sm text-gray-600">페이지를 로드하는 중...</p>
            </div>
        `;
        
        document.body.appendChild(loader);
    }

    /**
     * 비밀번호 변경 모달 표시
     */
    static showPasswordModal() {
        // 기존 모달이 있으면 제거
        const existingModal = document.getElementById('passwordChangeModal');
        if (existingModal) {
            existingModal.remove();
        }

        // 비밀번호 변경 모달 생성
        const modalHTML = `
            <div id="passwordChangeModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-[9999]">
                <div class="bg-white rounded-xl p-6 w-96 max-w-md mx-4 shadow-2xl">
                    <div class="flex justify-between items-center mb-4">
                        <h3 class="text-lg font-semibold text-gray-800">
                            <i class="fas fa-key mr-2 text-blue-500"></i>비밀번호 변경
                        </h3>
                        <button onclick="CommonHeader.hidePasswordModal()" class="text-gray-400 hover:text-gray-600 transition-colors">
                            <i class="fas fa-times text-lg"></i>
                        </button>
                    </div>
                    
                    <form id="passwordChangeForm" class="space-y-4">
                        <div>
                            <label class="block text-sm font-medium text-gray-700 mb-1">현재 비밀번호</label>
                            <input type="password" id="currentPasswordInput" 
                                class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" 
                                required placeholder="현재 비밀번호를 입력하세요">
                        </div>
                        
                        <div>
                            <label class="block text-sm font-medium text-gray-700 mb-1">새 비밀번호</label>
                            <input type="password" id="newPasswordInput" 
                                class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" 
                                required minlength="6" placeholder="새 비밀번호 (최소 6자)">
                        </div>
                        
                        <div>
                            <label class="block text-sm font-medium text-gray-700 mb-1">새 비밀번호 확인</label>
                            <input type="password" id="confirmPasswordInput" 
                                class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" 
                                required placeholder="새 비밀번호를 다시 입력하세요">
                        </div>
                        
                        <div class="flex gap-3 pt-4">
                            <button type="button" onclick="CommonHeader.hidePasswordModal()" 
                                class="flex-1 px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors">
                                취소
                            </button>
                            <button type="submit" 
                                class="flex-1 px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors">
                                <i class="fas fa-save mr-1"></i>변경
                            </button>
                        </div>
                    </form>
                </div>
            </div>
        `;

        document.body.insertAdjacentHTML('beforeend', modalHTML);

        // 폼 제출 이벤트 리스너 추가
        document.getElementById('passwordChangeForm').addEventListener('submit', CommonHeader.handlePasswordChange);

        // ESC 키로 모달 닫기
        document.addEventListener('keydown', function(e) {
            if (e.key === 'Escape') {
                CommonHeader.hidePasswordModal();
            }
        });
    }

    /**
     * 비밀번호 변경 모달 숨기기
     */
    static hidePasswordModal() {
        const modal = document.getElementById('passwordChangeModal');
        if (modal) {
            modal.remove();
        }
    }

    /**
     * 비밀번호 변경 처리
     */
    static async handlePasswordChange(e) {
        e.preventDefault();
        
        const currentPassword = document.getElementById('currentPasswordInput').value;
        const newPassword = document.getElementById('newPasswordInput').value;
        const confirmPassword = document.getElementById('confirmPasswordInput').value;
        
        // 새 비밀번호 확인
        if (newPassword !== confirmPassword) {
            CommonHeader.showToast('새 비밀번호가 일치하지 않습니다.', 'error');
            return;
        }

        if (newPassword.length < 6) {
            CommonHeader.showToast('새 비밀번호는 최소 6자 이상이어야 합니다.', 'error');
            return;
        }
        
        try {
            // AuthAPI가 있는지 확인
            if (typeof AuthAPI === 'undefined') {
                throw new Error('AuthAPI가 로드되지 않았습니다.');
            }

            // API를 통한 비밀번호 변경
            await AuthAPI.changePassword(currentPassword, newPassword);
            
            CommonHeader.showToast('비밀번호가 성공적으로 변경되었습니다.', 'success');
            CommonHeader.hidePasswordModal();
            
        } catch (error) {
            console.error('비밀번호 변경 실패:', error);
            CommonHeader.showToast('현재 비밀번호가 올바르지 않거나 변경에 실패했습니다.', 'error');
        }
    }

    /**
     * 토스트 메시지 표시
     */
    static showToast(message, type = 'success') {
        // 기존 토스트 제거
        const existingToast = document.querySelector('.toast-message');
        if (existingToast) {
            existingToast.remove();
        }

        const toast = document.createElement('div');
        toast.className = `toast-message fixed bottom-4 right-4 px-4 py-3 rounded-lg text-white z-[10000] shadow-lg transform transition-all duration-300 ${
            type === 'success' ? 'bg-green-500' : 'bg-red-500'
        }`;
        
        const icon = type === 'success' ? 'fa-check-circle' : 'fa-exclamation-circle';
        const _esc = s => { const d = document.createElement('div'); d.textContent = s; return d.innerHTML; };
        toast.innerHTML = `<i class="fas ${icon} mr-2"></i>${_esc(message)}`;
        
        document.body.appendChild(toast);
        
        // 애니메이션 효과
        setTimeout(() => toast.classList.add('translate-x-0'), 10);
        
        setTimeout(() => {
            toast.classList.add('opacity-0', 'translate-x-full');
            setTimeout(() => toast.remove(), 300);
        }, 3000);
    }

    /**
     * 로그아웃
     */
    static logout() {
        if (confirm('로그아웃 하시겠습니까?')) {
            if (window.authManager) {
                window.authManager.logout();
            } else {
                localStorage.removeItem('sso_token');
                localStorage.removeItem('sso_token');
                localStorage.removeItem('sso_user');
                localStorage.removeItem('sso_user');
                var hostname = window.location.hostname;
                if (hostname.includes('technicalkorea.net')) {
                    window.location.href = window.location.protocol + '//tkds.technicalkorea.net/dashboard';
                } else {
                    window.location.href = window.location.protocol + '//' + hostname + ':30000/dashboard';
                }
            }
        }
    }

    /**
     * 현재 페이지 업데이트
     */
    updateCurrentPage(pageId) {
        this.currentPage = pageId;
        
        // 활성 메뉴 업데이트
        document.querySelectorAll('.nav-item').forEach(item => {
            const itemPageId = item.getAttribute('data-page');
            if (itemPageId === pageId) {
                item.classList.add('bg-slate-700', 'text-white');
                item.classList.remove('text-slate-600', 'hover:bg-slate-100');
            } else {
                item.classList.remove('bg-slate-700', 'text-white');
                item.classList.add('text-slate-600');
            }
        });
    }

    /**
     * 키보드 단축키 초기화
     */
    initializeKeyboardShortcuts() {
        if (window.keyboardShortcuts) {
            window.keyboardShortcuts.setUser(this.currentUser);
        }
    }

    /**
     * 페이지 프리로더 초기화
     */
    initializePreloader() {
        if (window.pagePreloader) {
            // 사용자 설정 후 프리로더 초기화
            setTimeout(() => {
                window.pagePreloader.init();
            }, 1000); // 권한 시스템 로드 후 실행
        }
    }
}

// 전역 인스턴스
window.commonHeader = new CommonHeader();

// 전역 함수로 노출
window.CommonHeader = CommonHeader;
