(function () {
    if (window.__MELON_LITE_NAV_INITED) return;
    window.__MELON_LITE_NAV_INITED = true;

    const SAFE_FILES = new Set([
        '', 'index.php', 'search.php', 'song.php',
        'artists.php', 'artist.php', 'albums.php', 'album.php',
        'genres.php', 'genre.php', 'folders.php', 'folder.php',
        'new.php', 'recent.php', 'liked.php', 'popular.php',
        'playlists.php', 'playlist_view.php', 'playlist_create.php', 'playlist_edit.php', 'stats.php', 'listening_notes.php',
        'tags.php', 'tag.php',
        'recommend.php', 'auto_playlists.php', 'auto_playlist.php',
        'lyrics_edit.php',
        'song_edit.php', 'settings.php', 'user_settings.php', 'help.php', 'policies.php', 'updates.php', 'status.php',
        'users.php', 'api_tokens.php', 'scan.php', 'metadata.php', 'metadata_quality.php', 'metadata_requests.php', 'bulk_edit.php',
        'duplicates.php', 'missing_files.php', 'maintenance.php', 'backup_center.php',
        'announcements.php', 'patch_notes.php', 'service_status.php', 'jobs.php', 'feedback.php', 'playback_failures.php',
        'discovery.php', 'music_upload.php', 'music_requests.php',
        'diagnostics.php', 'logs.php', 'log_view.php', 'audit_logs.php', 'alerts.php',
        'performance.php', 'listening_stats.php', 'smart_organize.php', 'tag_manage.php',
        'name_merge.php', 'import.php', 'restore.php'
    ]);
    const UNSAFE_PREFIXES = ['/api/', '/ajax/', '/storage/', '/vendor/'];
    const UNSAFE_FILES = new Set([
        'logout.php', 'setup_admin.php', 'stream.php', 'cover.php', 'download.php',
        'lyrics_save.php', 'lyrics_delete.php', 'song_update.php',
        'playlist_delete.php', 'auto_playlist_save.php',
        'backup.php', 'backup_download.php', 'backup_delete.php',
        'restore_run.php', 'export.php', 'settings_save.php',
        'bulk_update.php', 'metadata_action.php', 'metadata_request_submit.php', 'missing_action.php',
        'log_clear.php', 'settings_export.php', 'settings_import.php'
    ]);
    let currentController = null;
    let navSeq = 0;
    let loadingTimer = null;
    const disabledDuringNavigation = new Set();

    function scrubUrlForLog(url) {
        try {
            const safe = new URL(url.href || url, window.location.origin);
            ['csrf_token', 'token', 'password', 'auth', 'key'].forEach(function (key) {
                if (safe.searchParams.has(key)) safe.searchParams.set(key, '[redacted]');
            });
            return safe.pathname + safe.search + safe.hash;
        } catch (err) {
            return '[url]';
        }
    }

    function safeClientMessage(err) {
        const raw = err && err.message ? String(err.message) : String(err || '');
        if (!raw) return 'unknown client error';
        if (/(SQLSTATE|PDOException|Stack trace|Fatal error|Warning:|Notice:|[A-Z]:[\\\/]|\/(?:Users|laragon|xampp|var|home|srv|www)\/)/i.test(raw)) {
            return 'internal error';
        }
        return raw.replace(/\s+/g, ' ').slice(0, 180);
    }

    function apiMessage(value, fallback) {
        if (window.MelonLiteApi && typeof window.MelonLiteApi.safeMessage === 'function') {
            return window.MelonLiteApi.safeMessage(value || fallback);
        }
        return safeClientMessage(value || fallback || '');
    }

    function codeFromStatus(status) {
        if (status === 401) return 'UNAUTHORIZED';
        if (status === 403) return 'FORBIDDEN';
        if (status === 404) return 'NOT_FOUND';
        if (status >= 500) return 'SERVER_ERROR';
        return 'INVALID_REQUEST';
    }

    function normalizeApiPayload(payload, response) {
        const status = response ? response.status : 400;
        if (!payload || typeof payload !== 'object') payload = {};
        const code = String(payload.error_code || payload.code || codeFromStatus(status)).toUpperCase();
        return {
            success: payload.success === true,
            error_code: code,
            code: code,
            data: payload.data && typeof payload.data === 'object' ? payload.data : {},
            message: apiMessage(payload.message, status === 401 ? '로그인이 필요합니다.' : '요청을 처리할 수 없습니다.')
        };
    }

    function makePjaxApiError(payload, response) {
        const normalized = normalizeApiPayload(payload, response);
        const err = new Error(normalized.message);
        err.name = 'PjaxApiError';
        err.code = normalized.error_code;
        err.status = response ? response.status : 400;
        err.payload = normalized;
        err.noRetry = true;
        return err;
    }

    async function parsePjaxJsonResponse(response) {
        const text = await response.text();
        try {
            return text ? JSON.parse(text.replace(/^\uFEFF/, '')) : {};
        } catch (err) {
            return {
                success: false,
                error_code: codeFromStatus(response.status || 500),
                message: '요청 응답을 확인할 수 없습니다.'
            };
        }
    }

    function resolveAuthRedirectUrl(err, url) {
        const payload = err && err.payload ? err.payload : {};
        const data = payload.data || {};
        const target = data.login_url || data.setup_url;
        if (target) {
            try {
                return new URL(target, window.location.href).href;
            } catch (noop) {}
        }
        const root = ensureStableBasePath();
        const current = scrubUrlForLog(url || window.location.href).replace(/^\/+/, '');
        return new URL(`login.php?return=${encodeURIComponent(current)}`, window.location.origin + root).href;
    }

    function handlePjaxApiError(err, url) {
        const code = String(err && err.code ? err.code : '').toUpperCase();
        const message = apiMessage(err && err.message, '요청을 처리할 수 없습니다.');
        const type = code === 'UNAUTHORIZED' || code === 'CSRF_FAILED' ? 'warning' : 'error';
        if (window.showToast) window.showToast(message, type);
        if (code === 'UNAUTHORIZED') {
            const redirectUrl = resolveAuthRedirectUrl(err, url);
            if (!isPlayerActive()) {
                window.location.href = redirectUrl;
            }
        }
    }

    function reportClientIssue(label, err) {
        try {
            console.warn('[MelonLite]', label, safeClientMessage(err));
        } catch (noop) {}
    }

    function inferAppRootPath() {
        if (window.APP_ROOT_PATH) return String(window.APP_ROOT_PATH);
        const script = document.querySelector('script[src*="assets/js/app-navigation.js"]');
        if (script && script.src) {
            try {
                const scriptUrl = new URL(script.src, window.location.href);
                return scriptUrl.pathname.replace(/assets\/js\/app-navigation\.js.*$/i, '');
            } catch (err) {}
        }
        const path = window.location.pathname.replace(/\\/g, '/');
        if (path.includes('/admin/')) return path.replace(/\/admin\/[^/]*$/i, '/');
        return path.replace(/\/[^/]*$/i, '/');
    }

    function ensureStableBasePath() {
        let root = inferAppRootPath();
        if (!root.startsWith('/')) {
            try {
                root = new URL(root, window.location.origin).pathname;
            } catch (err) {
                root = '/';
            }
        }
        if (!root.endsWith('/')) root += '/';
        window.APP_ROOT_PATH = root;
        window.APP_BASE_PATH = root;
        return root;
    }

    function shouldNormalizeUrl(raw) {
        if (!raw) return false;
        const value = String(raw).trim();
        if (value === '' || value === '#') return false;
        return !/^(#|javascript:|mailto:|tel:|data:|blob:)/i.test(value);
    }

    function normalizeUrlAttribute(element, attr) {
        const raw = element.getAttribute(attr);
        if (!shouldNormalizeUrl(raw)) return;
        try {
            const url = new URL(raw, window.location.href);
            if (url.origin !== window.location.origin) return;
            element.setAttribute(attr, url.href);
        } catch (err) {}
    }

    function normalizeInternalUrls(scope) {
        ensureStableBasePath();
        const root = scope || document;
        root.querySelectorAll('a[href]').forEach(function (link) {
            normalizeUrlAttribute(link, 'href');
        });
        root.querySelectorAll('form[action]').forEach(function (form) {
            normalizeUrlAttribute(form, 'action');
        });
    }

    function contentRoot() {
        return document.getElementById('app-content') || document.querySelector('[data-pjax-root]') || document.querySelector('.content-body');
    }

    function isSafeUrl(url) {
        if (url.origin !== window.location.origin) return false;
        if (url.hash && url.pathname === window.location.pathname && url.search === window.location.search) return false;
        const path = url.pathname.replace(/\\/g, '/');
        if (UNSAFE_PREFIXES.some(prefix => path.includes(prefix))) return false;
        const file = path.substring(path.lastIndexOf('/') + 1);
        if (UNSAFE_FILES.has(file)) return false;
        return SAFE_FILES.has(file);
    }

    function isPlayerActive() {
        const audio = document.getElementById('audio-player');
        if (audio && !audio.paused && !audio.ended) return true;
        if (window.AppPlayer && typeof window.AppPlayer.getState === 'function') {
            try {
                const state = window.AppPlayer.getState();
                return Boolean(state && state.isPlaying);
            } catch (err) {}
        }
        return false;
    }

    function notifyNavigationProblem(url, err) {
        const message = '페이지를 내부 이동으로 열지 못했습니다. 음악 재생을 유지하기 위해 새로고침 이동을 막았습니다.';
        if (window.showToast) window.showToast(message, 'warning');
        reportClientIssue('PJAX blocked full reload while playing: ' + scrubUrlForLog(url), err);
    }

    function shouldHandleLink(link, event) {
        if (!link || event.defaultPrevented) return false;
        if (event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return false;
        if (link.target && link.target !== '_self') return false;
        if (link.hasAttribute('download') || link.dataset.noPjax !== undefined || link.dataset.fullReload !== undefined) return false;
        const href = link.getAttribute('href') || '';
        if (!href || href === '#' || href.startsWith('#')) return false;
        if (/^(javascript:|mailto:|tel:)/i.test(href)) return false;
        let url;
        try {
            url = new URL(href, window.location.href);
        } catch (err) {
            return false;
        }
        return isSafeUrl(url);
    }

    function formToUrl(form) {
        const method = String(form.getAttribute('method') || 'GET').toUpperCase();
        if (method !== 'GET') return null;
        if (form.dataset.noPjax !== undefined || form.dataset.fullReload !== undefined) return null;
        const action = form.getAttribute('action') || window.location.href;
        let url;
        try {
            url = new URL(action, window.location.href);
        } catch (err) {
            return null;
        }
        if (!isSafeUrl(url)) return null;
        const params = new URLSearchParams();
        const formData = new FormData(form);
        formData.forEach(function (value, key) {
            if (value === null || value === undefined) return;
            const text = String(value);
            if (text === '') return;
            params.append(key, text);
        });
        url.search = params.toString();
        return url;
    }

    function ensureLoadingIndicator() {
        let indicator = document.getElementById('melon-lite-page-loading');
        if (indicator) return indicator;

        indicator = document.createElement('div');
        indicator.id = 'melon-lite-page-loading';
        indicator.className = 'melon-lite-page-loading';
        indicator.setAttribute('role', 'status');
        indicator.setAttribute('aria-live', 'polite');
        indicator.setAttribute('aria-hidden', 'true');
        indicator.innerHTML = '<span class="page-loading-spinner" aria-hidden="true"></span><span class="page-loading-text">\uB85C\uB529\uC911...</span>';
        document.body.appendChild(indicator);
        return indicator;
    }

    function setLoading(isLoading) {
        document.body.classList.toggle('pjax-loading', isLoading);
        const indicator = ensureLoadingIndicator();
        indicator.classList.toggle('show', isLoading);
        indicator.setAttribute('aria-hidden', isLoading ? 'false' : 'true');
        const root = contentRoot();
        if (root) root.setAttribute('aria-busy', isLoading ? 'true' : 'false');
        if (loadingTimer) {
            window.clearTimeout(loadingTimer);
            loadingTimer = null;
        }
        if (isLoading) {
            loadingTimer = window.setTimeout(function () {
                document.body.classList.remove('pjax-loading');
                indicator.classList.remove('show');
                indicator.setAttribute('aria-hidden', 'true');
                const currentRoot = contentRoot();
                if (currentRoot) currentRoot.setAttribute('aria-busy', 'false');
                restoreNavigationControls();
            }, 18000);
        } else {
            restoreNavigationControls();
        }
    }

    function setNavigationControls(form) {
        if (!form || !form.querySelectorAll) return;
        form.querySelectorAll('button[type="submit"], input[type="submit"]').forEach(function (control) {
            if (control.disabled) return;
            control.disabled = true;
            control.setAttribute('aria-disabled', 'true');
            disabledDuringNavigation.add(control);
        });
    }

    function restoreNavigationControls() {
        disabledDuringNavigation.forEach(function (control) {
            if (!control || !control.isConnected) return;
            control.disabled = false;
            control.removeAttribute('aria-disabled');
        });
        disabledDuringNavigation.clear();
    }

    function extractContent(html) {
        const parser = new DOMParser();
        const doc = parser.parseFromString(html, 'text/html');
        const nextContent = doc.getElementById('app-content') || doc.querySelector('[data-pjax-root]') || doc.querySelector('.content-body');
        if (!nextContent) throw new Error('content root not found');
        return {
            title: doc.title || document.title,
            bodyClass: doc.body ? doc.body.className : document.body.className,
            html: nextContent.innerHTML
        };
    }

    function executeContentScripts(root) {
        if (!root) return;
        root.querySelectorAll('script').forEach(function (oldScript) {
            const script = document.createElement('script');
            Array.from(oldScript.attributes).forEach(function (attr) {
                script.setAttribute(attr.name, attr.value);
            });
            script.text = oldScript.textContent || '';
            oldScript.replaceWith(script);
        });
    }

    function countActiveFilterParams(panel) {
        const params = new URLSearchParams(window.location.search || '');
        const names = new Set();
        panel.querySelectorAll('select[name], input[name], textarea[name]').forEach(function (control) {
            const type = String(control.getAttribute('type') || '').toLowerCase();
            const name = control.getAttribute('name');
            if (!name || type === 'hidden' || type === 'submit' || type === 'button' || name === 'csrf_token' || name === 'page') return;
            if (!params.has(name)) return;
            const value = String(params.get(name) || '').trim();
            if (value === '') return;
            names.add(name);
        });
        return names.size;
    }

    function initMobileFilterPanels() {
        const root = contentRoot() || document;
        const selector = [
            '.list-filter-section',
            '.advanced-filter-panel',
            'form.compact-filter-form',
            'form.filter-sort-form',
            'form.advanced-filter-form',
            'form.log-filter-form',
            'form.playlist-filter-form'
        ].join(',');

        root.querySelectorAll(selector).forEach(function (panel, index) {
            if (!panel || panel.closest('.mobile-filter-shell')) return;
            if (panel.closest('.settings-grid') && !panel.classList.contains('compact-filter-form')) return;
            if (!panel.querySelector('select, input:not([type="hidden"]), textarea, .filter-tab, button, .btn')) return;

            const id = panel.id || ('mobile-filter-panel-' + Date.now() + '-' + index);
            panel.id = id;
            panel.classList.add('mobile-filter-panel');

            const shell = document.createElement('div');
            shell.className = 'mobile-filter-shell';

            const activeCount = countActiveFilterParams(panel);
            const button = document.createElement('button');
            button.type = 'button';
            button.className = 'mobile-filter-toggle';
            button.setAttribute('aria-controls', id);
            button.setAttribute('aria-expanded', 'false');
            button.innerHTML = [
                '<span class="mobile-filter-toggle-main"><i class="fas fa-sliders" aria-hidden="true"></i><span>\uD544\uD130</span></span>',
                activeCount > 0 ? '<span class="mobile-filter-count">' + activeCount + '\uAC1C \uC801\uC6A9</span>' : '<span class="mobile-filter-hint">\uC5F4\uAE30</span>'
            ].join('');

            panel.parentNode.insertBefore(shell, panel);
            shell.appendChild(button);
            shell.appendChild(panel);

            button.addEventListener('click', function () {
                const isOpen = shell.classList.toggle('is-open');
                button.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
                const hint = button.querySelector('.mobile-filter-hint');
                if (hint) hint.textContent = isOpen ? '\uB2EB\uAE30' : '\uC5F4\uAE30';
            });
        });
    }

    function initPage() {
        try {
            normalizeInternalUrls(document);
        } catch (err) {
            reportClientIssue('URL normalize failed', err);
        }
        try {
            if (window.MelonLiteRebindPlayerPage) window.MelonLiteRebindPlayerPage();
            if (window.AppPlayer && typeof window.AppPlayer.syncState === 'function') window.AppPlayer.syncState();
        } catch (err) {
            reportClientIssue('Player page init failed', err);
        }
        try {
            if (window.MelonLiteInitPlaylistPage) window.MelonLiteInitPlaylistPage();
        } catch (err) {
            reportClientIssue('Playlist page init failed', err);
        }
        try {
            if (window.MelonLiteInitTagsPage) window.MelonLiteInitTagsPage();
        } catch (err) {
            reportClientIssue('Tags page init failed', err);
        }
        try {
            if (window.MelonLiteInitNotesPage) window.MelonLiteInitNotesPage();
        } catch (err) {
            reportClientIssue('Notes page init failed', err);
        }
        try {
            if (window.MelonLiteInitSearchPage) window.MelonLiteInitSearchPage();
        } catch (err) {
            reportClientIssue('Search page init failed', err);
        }
        try {
            initMobileFilterPanels();
        } catch (err) {
            reportClientIssue('Mobile filter init failed', err);
        }
        try {
            if (window.MelonLiteInitLyricsPage) window.MelonLiteInitLyricsPage();
        } catch (err) {
            reportClientIssue('Lyrics page init failed', err);
        }
        try {
            // PJAX 이동 후 교체된 폼에도 CSRF 토큰 자동 주입
            var csrfToken = window.APP_CSRF_TOKEN;
            if (csrfToken) {
                var root = contentRoot();
                var forms = root ? root.querySelectorAll('form[method="POST"], form[method="post"]') : [];
                forms.forEach(function (form) {
                    if (!form.querySelector('input[name="csrf_token"]')) {
                        var inp = document.createElement('input');
                        inp.type = 'hidden';
                        inp.name = 'csrf_token';
                        inp.value = csrfToken;
                        form.appendChild(inp);
                    }
                });
            }
        } catch (err) {
            reportClientIssue('CSRF inject failed', err);
        }
        try {
            if (window.MelonLiteSidebar) window.MelonLiteSidebar.updateActive(window.location.href);
        } catch (err) {
            reportClientIssue('Sidebar active update failed', err);
        }
        document.dispatchEvent(new CustomEvent('melonlite:page-ready', { detail: { url: window.location.href } }));
    }

    function mergeBodyClassName(nextClassName) {
        const next = new Set(String(nextClassName || '').split(/\s+/).filter(Boolean));
        [
            'is-standalone',
            'sidebar-collapsed',
            'guest-preview-mode',
            'is-offline',
            'is-tablet-layout',
            'is-tablet-portrait',
            'is-tablet-landscape',
            'is-mobile-layout',
            'is-desktop-layout'
        ].forEach(function (className) {
            if (document.body.classList.contains(className)) next.add(className);
        });
        document.body.className = Array.from(next).join(' ');
    }

    function closeTransientUiForNavigation() {
        document.body.classList.remove(
            'expand-player-open',
            'pwa-install-open',
            'guest-preview-ended',
            'mobile-sidebar-open',
            'modal-open',
            'queue-panel-open',
            'download-modal-open',
            'feedback-modal-open',
            'metadata-request-modal-open',
            'onboarding-modal-open'
        );

        [
            'expand-player-overlay',
            'playlist-modal',
            'queue-panel',
            'pwa-install-banner',
            'pwa-guide-modal',
            'guest-preview-prompt',
            'download-modal',
            'metadata-request-modal',
            'onboarding-modal'
        ].forEach(function (id) {
            const element = document.getElementById(id);
            if (!element) return;
            element.style.display = 'none';
            if ('hidden' in element) element.hidden = true;
            element.setAttribute('aria-hidden', 'true');
        });

        document.querySelectorAll('.modal-overlay, .pwa-install-modal, .guest-preview-prompt').forEach(function (element) {
            element.style.display = 'none';
            if ('hidden' in element) element.hidden = true;
            element.setAttribute('aria-hidden', 'true');
        });

        document.querySelectorAll('.melon-lite-toast').forEach(function (toast) {
            toast.classList.remove('show');
            if (toast.__hideTimer) window.clearTimeout(toast.__hideTimer);
        });

        const sidebar = document.getElementById('app-sidebar');
        const overlay = document.getElementById('sidebar-overlay');
        const hamburger = document.getElementById('mobile-hamburger');
        if (sidebar) sidebar.classList.remove('open');
        if (overlay) overlay.classList.remove('open');
        if (hamburger) hamburger.setAttribute('aria-expanded', 'false');
    }

    function applyContent(payload, url, shouldPush) {
        const root = contentRoot();
        if (!root) throw new Error('current content root not found');
        closeTransientUiForNavigation();
        root.innerHTML = payload.html;
        executeContentScripts(root);
        document.title = payload.title;
        if (payload.bodyClass) mergeBodyClassName(payload.bodyClass);
        if (shouldPush) history.pushState({ pjax: true, url: url.href }, '', url.href);
        window.scrollTo({ top: 0, left: 0, behavior: 'auto' });
        initPage();
    }

    async function fetchPjaxPayload(url, signal, retry) {
        const requestUrl = retry ? new URL(url.href) : url;
        if (retry) requestUrl.searchParams.set('_pjax_retry', String(Date.now()));
        const response = await fetch(requestUrl.href, {
            method: 'GET',
            credentials: 'same-origin',
            cache: retry ? 'reload' : 'no-store',
            signal,
            headers: {
                'X-Requested-With': 'XMLHttpRequest',
                'X-MelonLite-PJAX': '1',
                'Cache-Control': retry ? 'no-cache, max-age=0' : 'no-cache'
            }
        });
        if (response.url) {
            try {
                const responseUrl = new URL(response.url);
                if (/\/offline\.php$/i.test(responseUrl.pathname) && !/\/offline\.php$/i.test(url.pathname)) {
                    throw new Error('offline fallback response');
                }
            } catch (urlErr) {
                if (urlErr && urlErr.message === 'offline fallback response') throw urlErr;
            }
        }
        const contentType = response.headers.get('content-type') || '';
        if (!response.ok) {
            if (contentType.includes('application/json')) {
                throw makePjaxApiError(await parsePjaxJsonResponse(response), response);
            }
            throw new Error(`HTTP ${response.status}`);
        }
        if (contentType.includes('application/json')) {
            const payload = await parsePjaxJsonResponse(response);
            if (payload && payload.success === false) {
                throw makePjaxApiError(payload, response);
            }
            throw new Error('json response');
        }
        if (!contentType.includes('text/html')) throw new Error('non html response');
        return extractContent(await response.text());
    }

    async function navigateTo(url, options = {}) {
        const root = contentRoot();
        if (!root) {
            window.location.href = url.href;
            return;
        }
        const seq = ++navSeq;
        if (currentController) currentController.abort();
        currentController = new AbortController();
        setLoading(true);
        try {
            if (window.MelonLiteSidebar) window.MelonLiteSidebar.saveScroll();
            let payload;
            try {
                payload = await fetchPjaxPayload(url, currentController.signal, false);
            } catch (firstErr) {
                if (firstErr && firstErr.name === 'AbortError') throw firstErr;
                if (firstErr && firstErr.noRetry) throw firstErr;
                payload = await fetchPjaxPayload(url, currentController.signal, true);
            }
            if (seq !== navSeq) return;
            applyContent(payload, url, options.push !== false);
        } catch (err) {
            if (err.name === 'AbortError') return;
            if (err.name === 'PjaxApiError') {
                handlePjaxApiError(err, url);
                return;
            }
            reportClientIssue('PJAX fallback', err);
            try {
                if (window.AppPlayer && typeof window.AppPlayer.saveState === 'function') {
                    window.AppPlayer.saveState();
                }
                localStorage.setItem('melon_lite_last_pjax_error', JSON.stringify({
                    message: safeClientMessage(err),
                    url: scrubUrlForLog(url),
                    at: Date.now()
                }));
            } catch (storageErr) {}
            if (isPlayerActive()) {
                notifyNavigationProblem(url, err);
                return;
            }
            window.location.href = url.href;
        } finally {
            if (seq === navSeq) {
                currentController = null;
                setLoading(false);
            }
        }
    }

    document.addEventListener('click', function (event) {
        const excludeSelector = '.play-row-btn, .compact-play, .like-btn, .add-next-btn, .add-playlist-btn, .download-song-btn, .metadata-request-btn, .suggest-play-btn, .playlist-option-item, #mobile-hamburger, #sidebar-collapse-toggle, .menu-group-toggle, .playlist-move-btn, .remove-playlist-song-btn, .btn-add-page-next, .btn-add-page-to-queue, [data-admin-card], #admin-workspace-body a, #admin-workspace-body button';
        if (event.target.closest(excludeSelector)) {
            return;
        }

        let link = event.target.closest('a[href]');
        const songCard = event.target.closest('.compact-song-card.song-item');
        if (!link && songCard) {
            const songId = songCard.getAttribute('data-id');
            if (songId) {
                link = document.createElement('a');
                link.setAttribute('href', `song.php?id=${songId}`);
            }
        }

        if (!link || !shouldHandleLink(link, event)) return;
        const url = new URL(link.getAttribute('href'), window.location.href);
        event.preventDefault();
        navigateTo(url, { push: true });
    });

    document.addEventListener('submit', function (event) {
        const form = event.target && event.target.closest ? event.target.closest('form') : null;
        if (form && form.closest('#admin-workspace-body')) return;
        const url = form ? formToUrl(form) : null;
        if (!url) return;
        event.preventDefault();
        setNavigationControls(form);
        if (window.AppPlayer && typeof window.AppPlayer.saveState === 'function') {
            try { window.AppPlayer.saveState(); } catch (err) {}
        }
        navigateTo(url, { push: true });
    });

    document.addEventListener('change', function (event) {
        const control = event.target;
        if (!control || !control.closest) return;
        if (control.closest('#admin-workspace-body')) return;
        const form = control.closest('.filter-sort-form');
        if (!form || !control.matches('select, input[type="checkbox"], input[type="radio"]')) return;
        const url = formToUrl(form);
        if (!url) return;
        setNavigationControls(form);
        if (window.AppPlayer && typeof window.AppPlayer.saveState === 'function') {
            try { window.AppPlayer.saveState(); } catch (err) {}
        }
        navigateTo(url, { push: true });
    });

    document.addEventListener('keydown', function (event) {
        if (event.key !== 'Enter' && event.key !== ' ') return;
        const card = event.target.closest && event.target.closest('.compact-song-card.song-item');
        if (!card || event.target.closest('a, button, input, select, textarea')) return;
        const songId = card.getAttribute('data-id');
        if (!songId) return;
        event.preventDefault();
        navigateTo(new URL(`song.php?id=${encodeURIComponent(songId)}`, window.location.href), { push: true });
    });

    window.addEventListener('popstate', function () {
        const url = new URL(window.location.href);
        if (!isSafeUrl(url)) {
            window.location.reload();
            return;
        }
        navigateTo(url, { push: false });
    });

    window.MelonLiteNavigate = navigateTo;
    document.addEventListener('DOMContentLoaded', initPage);
})();
