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

/* ===== Config ===== */
const API_BASE = '/api';
const _tkuserBase = location.hostname.includes('technicalkorea.net')
    ? 'https://tkuser.technicalkorea.net'
    : `http://${location.hostname}:30380`;

/* ===== Token ===== */
function _cookieGet(n) { const m = document.cookie.match(new RegExp('(?:^|; )' + n + '=([^;]*)')); return m ? decodeURIComponent(m[1]) : null; }
function _cookieRemove(n) { let c = n + '=; path=/; max-age=0'; if (location.hostname.includes('technicalkorea.net')) c += '; domain=.technicalkorea.net; secure; samesite=lax'; document.cookie = c; }
function getToken() { return _cookieGet('sso_token') || localStorage.getItem('sso_token'); }
function getLoginUrl() {
    const h = location.hostname;
    const t = Date.now();
    if (h.includes('technicalkorea.net')) return location.protocol + '//tkds.technicalkorea.net/dashboard?redirect=' + encodeURIComponent(location.href) + '&_t=' + t;
    return location.protocol + '//' + h + ':30780/dashboard?redirect=' + encodeURIComponent(location.href) + '&_t=' + t;
}
function decodeToken(t) { try { const b = atob(t.split('.')[1].replace(/-/g,'+').replace(/_/g,'/')); return JSON.parse(new TextDecoder().decode(Uint8Array.from(b, c => c.charCodeAt(0)))); } catch { return null; } }

/* ===== 리다이렉트 루프 방지 ===== */
const _REDIRECT_KEY = '_sso_redirect_ts';
function _safeRedirect() {
    const last = parseInt(sessionStorage.getItem(_REDIRECT_KEY) || '0', 10);
    if (Date.now() - last < 5000) { console.warn('[tkfb] 리다이렉트 루프 감지'); return; }
    sessionStorage.setItem(_REDIRECT_KEY, String(Date.now()));
    location.href = getLoginUrl();
}

/* ===== API ===== */
async function api(path, opts = {}) {
    const token = getToken();
    const headers = { 'Authorization': token ? `Bearer ${token}` : '', ...(opts.headers||{}) };
    if (!(opts.body instanceof FormData)) headers['Content-Type'] = 'application/json';
    const res = await fetch(API_BASE + path, { ...opts, headers });
    if (res.status === 401) { _safeRedirect(); throw new Error('인증 만료'); }
    if (res.headers.get('content-type')?.includes('text/csv')) return res;
    const data = await res.json();
    if (!res.ok) throw new Error(data.error || data.message || '요청 실패');
    return data;
}

/* ===== Toast ===== */
function showToast(msg, type = 'success') {
    document.querySelector('.toast-message')?.remove();
    const el = document.createElement('div');
    el.className = `toast-message fixed bottom-4 right-4 px-4 py-3 rounded-lg text-white z-[10000] shadow-lg ${type==='success'?'bg-orange-500':'bg-red-500'}`;
    el.innerHTML = `<i class="fas ${type==='success'?'fa-check-circle':'fa-exclamation-circle'} mr-2"></i>${escapeHtml(msg)}`;
    document.body.appendChild(el);
    setTimeout(() => { el.classList.add('opacity-0'); setTimeout(() => el.remove(), 300); }, 3000);
}

/* ===== Escape ===== */
function escapeHtml(str) { if (!str) return ''; const d = document.createElement('div'); d.textContent = str; return d.innerHTML; }

/* ===== Helpers ===== */
function formatDate(d) { if (!d) return ''; return String(d).substring(0, 10); }
function formatTime(d) { if (!d) return ''; return String(d).substring(11, 16); }
function formatDateTime(d) { if (!d) return ''; return String(d).substring(0, 16).replace('T', ' '); }
function debounce(fn, ms) { let t; return function(...args) { clearTimeout(t); t = setTimeout(() => fn.apply(this, args), ms); }; }

/* ===== Logout ===== */
function doLogout() {
    if (!confirm('로그아웃?')) return;
    _cookieRemove('sso_token'); _cookieRemove('sso_user'); _cookieRemove('sso_refresh_token');
    ['sso_token','sso_user','sso_refresh_token','token','user','access_token','currentUser','current_user','userInfo','userPageAccess'].forEach(k => localStorage.removeItem(k));
    location.href = getLoginUrl() + '&logout=1';
}

/* ===== Page Access ===== */
const _PA_CACHE_KEY = 'userPageAccess';
const _PA_CACHE_DURATION = 5 * 60 * 1000; // 5분
let _paPromise = null;

async function _fetchPageAccess(userId) {
    const cached = localStorage.getItem(_PA_CACHE_KEY);
    if (cached) {
        try {
            const c = JSON.parse(cached);
            if (Date.now() - c.timestamp < _PA_CACHE_DURATION) return c.keys;
        } catch { localStorage.removeItem(_PA_CACHE_KEY); }
    }
    if (_paPromise) return _paPromise;
    _paPromise = (async () => {
        try {
            const token = getToken();
            const res = await fetch(`${API_BASE}/users/${userId}/page-access`, {
                headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }
            });
            if (!res.ok) return [];
            const data = await res.json();
            const pages = data.data?.pageAccess || [];
            const keys = pages.filter(p => p.can_access == 1).map(p => p.page_key);
            localStorage.setItem(_PA_CACHE_KEY, JSON.stringify({ keys, timestamp: Date.now() }));
            return keys;
        } catch (e) {
            console.error('페이지 권한 조회 오류:', e);
            return [];
        } finally { _paPromise = null; }
    })();
    return _paPromise;
}

/* ===== Navbar ===== */
const NAV_MENU = [
    { cat: null, href: '/pages/dashboard-new.html', icon: 'fa-home', label: '대시보드', key: 'dashboard' },
    { cat: '작업 관리', items: [
        { href: '/pages/work/tbm.html', icon: 'fa-clipboard-list', label: 'TBM 관리', key: 'work.tbm' },
        { href: '/pages/work/report-create.html', icon: 'fa-file-alt', label: '작업보고서 작성', key: 'work.report_create' },
        { href: '/pages/work/analysis.html', icon: 'fa-chart-bar', label: '작업 분석', key: 'work.analysis', admin: true },
        { href: '/pages/work/nonconformity.html', icon: 'fa-exclamation-triangle', label: '부적합 현황', key: 'work.nonconformity' },
        { href: '/pages/work/schedule.html', icon: 'fa-calendar-alt', label: '공정표', key: 'work.schedule' },
        { href: '/pages/work/meetings.html', icon: 'fa-users', label: '생산회의록', key: 'work.meetings' },
        { href: '/pages/work/daily-status.html', icon: 'fa-chart-bar', label: '입력 현황', key: 'work.daily_status' },
        { href: '/pages/work/proxy-input.html', icon: 'fa-user-edit', label: '대리입력', key: 'work.proxy_input' },
    ]},
    { cat: '공장 관리', items: [
        { href: '/pages/admin/repair-management.html', icon: 'fa-tools', label: '시설설비 관리', key: 'factory.repair_management' },
        { href: '/pages/inspection/daily-patrol.html', icon: 'fa-route', label: '일일순회점검', key: 'inspection.daily_patrol' },
        { href: '/pages/attendance/checkin.html', icon: 'fa-user-check', label: '출근 체크', key: 'inspection.checkin' },
        { href: '/pages/attendance/work-status.html', icon: 'fa-briefcase', label: '근무 현황', key: 'inspection.work_status' },
    ]},
    { cat: '소모품 관리', items: [
        { href: '/pages/purchase/request.html', icon: 'fa-shopping-cart', label: '소모품 신청', key: 'purchase.request' },
        { href: '/pages/admin/purchase-analysis.html', icon: 'fa-chart-line', label: '소모품 분석', key: 'purchase.analysis', admin: true },
    ]},
    { cat: '근태 관리', items: [
        { href: '/pages/attendance/my-vacation-info.html', icon: 'fa-info-circle', label: '내 연차 정보', key: 'attendance.my_vacation_info' },
        { href: '/pages/attendance/monthly.html', icon: 'fa-calendar', label: '월간 근태', key: 'attendance.monthly' },
        { href: '/pages/attendance/vacation-request.html', icon: 'fa-paper-plane', label: '휴가 신청', key: 'attendance.vacation_request' },
        { href: '/pages/attendance/vacation-management.html', icon: 'fa-cog', label: '휴가 관리', key: 'attendance.vacation_management', admin: true },
        { href: '/pages/attendance/vacation-allocation.html', icon: 'fa-plus-circle', label: '휴가 발생 입력', key: 'attendance.vacation_allocation', admin: true },
        { href: '/pages/attendance/annual-overview.html', icon: 'fa-chart-pie', label: '연간 휴가 현황', key: 'attendance.annual_overview', admin: true },
        { href: '/pages/attendance/monthly-comparison.html', icon: 'fa-scale-balanced', label: '월간 비교·확인', key: 'attendance.monthly_comparison' },
    ]},
    { cat: '시스템 관리', admin: true, items: [
        { href: `${_tkuserBase}/?tab=users`, icon: 'fa-users-cog', label: '사용자 관리', key: 'admin.user_management', external: true },
        { href: `${_tkuserBase}/?tab=projects`, icon: 'fa-project-diagram', label: '프로젝트 관리', key: 'admin.projects', external: true },
        { href: `${_tkuserBase}/?tab=tasks`, icon: 'fa-tasks', label: '작업 관리', key: 'admin.tasks', external: true },
        { href: `${_tkuserBase}/?tab=workplaces`, icon: 'fa-building', label: '작업장 관리', key: 'admin.workplaces', external: true },
        { href: `${_tkuserBase}/?tab=equipments`, icon: 'fa-cogs', label: '설비 관리', key: 'admin.equipments', external: true },
        { href: `${_tkuserBase}/?tab=departments`, icon: 'fa-sitemap', label: '부서 관리', key: 'admin.departments', external: true },
        { href: `${_tkuserBase}/?tab=notificationRecipients`, icon: 'fa-bell', label: '알림 관리', key: 'admin.notifications', external: true },
        { href: '/pages/admin/attendance-report.html', icon: 'fa-clipboard-check', label: '출퇴근-보고서 대조', key: 'admin.attendance_report' },
    ]},
];

// 하위 페이지 → 부모 페이지 키 매핑
const PAGE_KEY_ALIASES = {
    'dashboard_new': 'dashboard',
    'work.tbm_mobile': 'work.tbm',
    'work.tbm_create': 'work.tbm',
    'work.report_create_mobile': 'work.report_create',
    'admin.equipment_detail': 'admin.equipments',
    'admin.repair_management': 'factory.repair_management',
    'attendance.checkin': 'inspection.checkin',
    'attendance.work_status': 'inspection.work_status',
    'work.meeting_detail': 'work.meetings',
    'work.proxy_input': 'work.daily_status',
};

function _getCurrentPageKey() {
    const path = location.pathname;
    if (!path.startsWith('/pages/')) return 'dashboard';
    const raw = path.substring(7).replace('.html', '').replace(/\//g, '.').replace(/-/g, '_');
    return PAGE_KEY_ALIASES[raw] || raw;
}

function renderNavbar(accessibleKeys) {
    const nav = document.getElementById('sideNav');
    if (!nav) return;

    const currentKey = _getCurrentPageKey();
    const isAdmin = currentUser && ['admin', 'system', 'system admin'].includes(currentUser.role);

    let html = '';

    for (const entry of NAV_MENU) {
        if (!entry.cat) {
            // Top-level link (dashboard)
            const active = currentKey === entry.key;
            html += `<a href="${entry.href}" class="nav-link flex items-center gap-3 px-4 py-2.5 rounded-lg text-sm transition-colors ${active ? 'active' : 'text-gray-600 hover:bg-gray-100'}">
                <i class="fas ${entry.icon} w-5 text-center"></i><span>${entry.label}</span></a>`;
            continue;
        }

        // Category
        if (entry.admin && !isAdmin) continue;

        const visibleItems = entry.items.filter(item => {
            if (item.admin && !isAdmin) return false;
            if (isAdmin) return true;
            return accessibleKeys.includes(item.key);
        });

        if (visibleItems.length === 0) continue;

        const hasActive = visibleItems.some(item => currentKey === item.key);

        html += `<div class="nav-category${hasActive ? ' expanded' : ''}">
            <button class="nav-category-header" onclick="this.parentElement.classList.toggle('expanded')">
                <span>${entry.cat}</span><span class="nav-arrow">&#9662;</span>
            </button>
            <div class="nav-category-items">`;

        for (const item of visibleItems) {
            const active = currentKey === item.key;
            const target = item.external ? ' target="_blank"' : '';
            const arrow = item.external ? ' &#8599;' : '';
            html += `<a href="${item.href}"${target} class="nav-link flex items-center gap-3 px-4 py-2 rounded-lg text-sm transition-colors ${active ? 'active' : 'text-gray-600 hover:bg-gray-100'}" data-page-key="${item.key}">
                <i class="fas ${item.icon} w-5 text-center text-xs"></i><span>${item.label}${arrow}</span></a>`;
        }

        html += `</div></div>`;
    }

    nav.innerHTML = html;
}

/* ===== Mobile Menu ===== */
function toggleMobileMenu() {
    const nav = document.getElementById('sideNav');
    const overlay = document.getElementById('mobileOverlay');
    if (!nav) return;
    const isOpen = nav.classList.contains('mobile-open');
    nav.classList.toggle('mobile-open');
    if (overlay) overlay.classList.toggle('hidden', isOpen);
    document.body.style.overflow = isOpen ? '' : 'hidden';
}

/* ===== State ===== */
let currentUser = null;

/* ===== Init ===== */
async function initAuth() {
    // 쿠키 우선 검증
    const cookieToken = _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));
        _safeRedirect();
        return false;
    }

    const token = getToken();
    if (!token) { _safeRedirect(); return false; }
    const decoded = decodeToken(token);
    if (!decoded) { _safeRedirect(); return false; }
    sessionStorage.removeItem(_REDIRECT_KEY);
    if (!localStorage.getItem('sso_token')) localStorage.setItem('sso_token', token);

    currentUser = {
        id: decoded.user_id || decoded.id,
        username: decoded.username || decoded.sub,
        name: decoded.name || decoded.full_name,
        role: (decoded.role || decoded.access_level || '').toLowerCase()
    };

    const dn = currentUser.name || currentUser.username;
    const nameEl = document.getElementById('headerUserName');
    const avatarEl = document.getElementById('headerUserAvatar');
    if (nameEl) nameEl.textContent = dn;
    if (avatarEl) avatarEl.textContent = dn.charAt(0).toUpperCase();

    // Page access 기반 네비게이션
    const isAdmin = ['admin', 'system', 'system admin'].includes(currentUser.role);
    let accessibleKeys = [];
    if (!isAdmin) {
        accessibleKeys = await _fetchPageAccess(currentUser.id);
        // 현재 페이지 접근 권한 확인
        const pageKey = _getCurrentPageKey();
        if (pageKey && pageKey !== 'dashboard' && !pageKey.startsWith('profile.')) {
            if (!accessibleKeys.includes(pageKey)) {
                alert('이 페이지에 접근할 권한이 없습니다.');
                location.href = '/pages/dashboard-new.html';
                return false;
            }
        }
    }

    renderNavbar(accessibleKeys);

    // Mobile menu overlay
    const mobileBtn = document.getElementById('mobileMenuBtn');
    if (mobileBtn) mobileBtn.addEventListener('click', toggleMobileMenu);
    const overlay = document.getElementById('mobileOverlay');
    if (overlay) overlay.addEventListener('click', toggleMobileMenu);

    // 알림 벨 로드
    _loadNotificationBell();

    setTimeout(() => document.querySelectorAll('.fade-in').forEach(el => el.classList.add('visible')), 50);
    return true;
}

/* ===== 알림 벨 ===== */
function _loadNotificationBell() {
    const s = document.createElement('script');
    s.src = (location.hostname.includes('technicalkorea.net') ? 'https://tkds.technicalkorea.net' : location.protocol + '//' + location.hostname + ':30000') + '/shared/notification-bell.js?v=4';
    document.head.appendChild(s);
}

/* ===== Modal ESC 닫기 ===== */
document.addEventListener('keydown', e => {
    if (e.key === 'Escape') {
        document.querySelectorAll('.modal-overlay:not(.hidden)')
            .forEach(m => m.classList.add('hidden'));
    }
});
