(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', 'stats.php', 'listening_notes.php',
        'tags.php', 'tag.php',
        'recommend.php', 'auto_playlists.php', 'auto_playlist.php'
    ]);
    const UNSAFE_PREFIXES = ['/admin/'];
    let currentController = null;
    let navSeq = 0;

    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);
        return SAFE_FILES.has(file);
    }

    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 setLoading(isLoading) {
        document.body.classList.toggle('pjax-loading', isLoading);
        const root = contentRoot();
        if (root) root.setAttribute('aria-busy', isLoading ? 'true' : 'false');
    }

    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 initPage() {
        try {
            if (window.MelonLiteRebindPlayerPage) window.MelonLiteRebindPlayerPage();
        } catch (err) {
            console.error('Player page init failed:', err);
        }
        try {
            if (window.MelonLiteInitPlaylistPage) window.MelonLiteInitPlaylistPage();
        } catch (err) {
            console.error('Playlist page init failed:', err);
        }
        try {
            if (window.MelonLiteInitTagsPage) window.MelonLiteInitTagsPage();
        } catch (err) {
            console.error('Tags page init failed:', err);
        }
        try {
            if (window.MelonLiteInitNotesPage) window.MelonLiteInitNotesPage();
        } catch (err) {
            console.error('Notes page init failed:', err);
        }
        try {
            if (window.MelonLiteInitSearchPage) window.MelonLiteInitSearchPage();
        } catch (err) {
            console.error('Search page init failed:', err);
        }
        try {
            if (window.MelonLiteSidebar) window.MelonLiteSidebar.updateActive(window.location.href);
        } catch (err) {
            console.error('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',
            'mobile-sidebar-open',
            'guest-preview-mode',
            'guest-preview-ended',
            'pwa-install-open',
            'is-offline'
        ].forEach(function (className) {
            if (document.body.classList.contains(className)) next.add(className);
        });
        document.body.className = Array.from(next).join(' ');
    }

    function applyContent(payload, url, shouldPush) {
        const root = contentRoot();
        if (!root) throw new Error('current content root not found');
        root.innerHTML = payload.html;
        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 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();
            const response = await fetch(url.href, {
                method: 'GET',
                credentials: 'same-origin',
                signal: currentController.signal,
                headers: {
                    'X-Requested-With': 'XMLHttpRequest',
                    'X-MelonLite-PJAX': '1'
                }
            });
            if (!response.ok) throw new Error(`HTTP ${response.status}`);
            const contentType = response.headers.get('content-type') || '';
            if (!contentType.includes('text/html')) throw new Error('non html response');
            const payload = extractContent(await response.text());
            if (seq !== navSeq) return;
            applyContent(payload, url, options.push !== false);
        } catch (err) {
            if (err.name === 'AbortError') return;
            console.warn('PJAX fallback:', err);
            try {
                localStorage.setItem('melon_lite_last_pjax_error', JSON.stringify({
                    message: err.message || String(err),
                    url: url.href,
                    at: Date.now()
                }));
            } catch (storageErr) {}
            window.location.href = url.href;
        } finally {
            if (seq === navSeq) {
                currentController = null;
                setLoading(false);
            }
        }
    }

    document.addEventListener('click', function (event) {
        const link = event.target.closest('a[href]');
        if (!shouldHandleLink(link, event)) return;
        const url = new URL(link.getAttribute('href'), window.location.href);
        event.preventDefault();
        navigateTo(url, { 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);
})();
