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

    const settings = Object.assign({
        groupsDefaultOpen: true,
        mobileAutoClose: true
    }, window.APP_SIDEBAR_SETTINGS || {});

    const groupStorageKey = 'melon_lite_sidebar_groups';
    const scrollStorageKey = 'melon_lite_sidebar_scroll_top';
    const collapsedStorageKey = 'melon_lite_sidebar_collapsed';
    const desktopQuery = window.matchMedia('(min-width: 768px)');
    const mobileQuery = window.matchMedia('(max-width: 767px)');

    function sidebar() {
        return document.getElementById('app-sidebar');
    }

    function overlay() {
        return document.getElementById('sidebar-overlay');
    }

    function sidebarScroll() {
        const el = sidebar();
        return el ? el.querySelector('.sidebar-scroll') : null;
    }

    function readJson(key, fallback) {
        try {
            const raw = localStorage.getItem(key);
            if (!raw) return fallback;
            const parsed = JSON.parse(raw);
            return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : fallback;
        } catch (err) {
            try { localStorage.removeItem(key); } catch (storageErr) {}
            return fallback;
        }
    }

    function writeJson(key, value) {
        try { localStorage.setItem(key, JSON.stringify(value)); } catch (err) {}
    }

    function readCollapsed() {
        try { return localStorage.getItem(collapsedStorageKey) === '1'; } catch (err) { return false; }
    }

    function writeCollapsed(value) {
        try { localStorage.setItem(collapsedStorageKey, value ? '1' : '0'); } catch (err) {}
    }

    function readStoredScrollTop() {
        try {
            const value = sessionStorage.getItem(scrollStorageKey) || localStorage.getItem(scrollStorageKey);
            const parsed = parseInt(value, 10);
            return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0;
        } catch (err) {
            return 0;
        }
    }

    function writeStoredScrollTop() {
        const scroll = sidebarScroll();
        if (!scroll) return;
        try {
            const value = String(scroll.scrollTop || 0);
            sessionStorage.setItem(scrollStorageKey, value);
            localStorage.setItem(scrollStorageKey, value);
        } catch (err) {}
    }

    function isDesktopLayout() {
        return desktopQuery.matches;
    }

    function isElementVisibleInSidebar(element) {
        const scroll = sidebarScroll();
        if (!scroll || !element) return true;
        const containerRect = scroll.getBoundingClientRect();
        const elementRect = element.getBoundingClientRect();
        return elementRect.top >= containerRect.top && elementRect.bottom <= containerRect.bottom;
    }

    function revealActiveMenuIfNeeded() {
        const scroll = sidebarScroll();
        if (!scroll || document.body.classList.contains('sidebar-collapsed')) return;
        const active = scroll.querySelector('.nav-item.active');
        if (!active || isElementVisibleInSidebar(active)) return;
        try {
            active.scrollIntoView({ block: 'nearest', inline: 'nearest' });
            writeStoredScrollTop();
        } catch (err) {
            const offset = active.offsetTop - scroll.clientHeight / 2;
            scroll.scrollTop = Math.max(0, offset);
            writeStoredScrollTop();
        }
    }

    function menuKeyFromUrl(url) {
        let path = '';
        let urlObj;
        try {
            urlObj = new URL(url, window.location.href);
            path = urlObj.pathname.split('/').pop() || 'index.php';
        } catch (err) {
            path = 'index.php';
            urlObj = new URL(window.location.href);
        }
        const map = {
            'index.php': 'home',
            'search.php': 'search',
            'stats.php': 'stats',
            'listening_notes.php': 'listening_notes',
            'tags.php': 'tags',
            'tag.php': 'tags',
            'new.php': 'new',
            'liked.php': 'liked',
            'recent.php': 'recent',
            'popular.php': 'popular',
            'folders.php': 'folders',
            'folder.php': 'folders',
            'artists.php': 'artists',
            'artist.php': 'artists',
            'albums.php': 'albums',
            'album.php': 'albums',
            'genres.php': 'genres',
            'genre.php': 'genres',
            'recommend.php': 'recommend',
            'auto_playlists.php': 'auto_playlists',
            'auto_playlist.php': 'auto_playlists',
            'playlists.php': 'playlists',
            'playlist_view.php': 'playlists',
            'playlist_create.php': 'playlist_create',
            'playlist_edit.php': 'playlists',
            'login.php': 'login',
            'users.php': 'admin_users',
            'audit_logs.php': 'audit_logs',
            'backup_center.php': 'backup',
            'backup.php': 'backup',
            'restore.php': 'backup',
            'import.php': 'backup',
            'export.php': 'backup',
            'logs.php': 'logs',
            'song.php': 'all'
        };
        if (path === 'index.php' && urlObj.searchParams.get('view') === 'all') return 'all';
        return map[path] || null;
    }

    function updateActiveMenu(url) {
        const side = sidebar();
        const scroll = sidebarScroll();
        if (!side) return;
        const key = menuKeyFromUrl(url || window.location.href);
        if (!key) return;
        const previousScrollTop = scroll ? scroll.scrollTop : 0;
        side.querySelectorAll('.nav-item.active').forEach(item => item.classList.remove('active'));
        side.querySelectorAll('.menu-group.has-active').forEach(group => group.classList.remove('has-active'));
        const safeKey = window.CSS && CSS.escape ? CSS.escape(key) : key.replace(/"/g, '\\"');
        const active = side.querySelector(`.nav-item[data-menu-key="${safeKey}"]`);
        if (active) {
            active.classList.add('active');
            const group = active.closest('.menu-group');
            if (group && !document.body.classList.contains('sidebar-collapsed')) {
                group.classList.add('has-active', 'open');
                group.classList.remove('collapsed');
                const toggle = group.querySelector('.menu-group-toggle');
                if (toggle) toggle.setAttribute('aria-expanded', 'true');
            } else if (group) {
                group.classList.add('has-active');
            }
        }
        if (scroll) scroll.scrollTop = previousScrollTop;
        window.setTimeout(revealActiveMenuIfNeeded, 40);
    }

    function closeMobileSidebar() {
        const side = sidebar();
        const over = overlay();
        if (!side || !over) return;
        side.classList.remove('open');
        over.classList.remove('open');
        document.body.classList.remove('mobile-sidebar-open');
        const hamburger = document.getElementById('mobile-hamburger');
        if (hamburger) hamburger.setAttribute('aria-expanded', 'false');
    }

    function openMobileSidebar() {
        const side = sidebar();
        const over = overlay();
        if (!side || !over) return;
        side.classList.add('open');
        over.classList.add('open');
        document.body.classList.add('mobile-sidebar-open');
        const hamburger = document.getElementById('mobile-hamburger');
        if (hamburger) hamburger.setAttribute('aria-expanded', 'true');
    }

    function toggleMobileSidebar() {
        const side = sidebar();
        if (!side) return;
        if (side.classList.contains('open')) closeMobileSidebar();
        else openMobileSidebar();
    }

    function applyCollapsedState() {
        const collapsed = isDesktopLayout() && readCollapsed();
        document.body.classList.toggle('sidebar-collapsed', collapsed);
        const button = document.getElementById('sidebar-collapse-toggle');
        if (button) {
            button.setAttribute('aria-expanded', collapsed ? 'false' : 'true');
            button.setAttribute('aria-label', collapsed ? '사이드메뉴 펼치기' : '사이드메뉴 접기');
            button.setAttribute('title', collapsed ? '사이드메뉴 펼치기' : '사이드메뉴 접기');
            button.classList.toggle('is-collapsed', collapsed);
            const icon = button.querySelector('i');
            if (icon) icon.className = collapsed ? 'fa-solid fa-angles-right' : 'fa-solid fa-angles-left';
        }
        if (!isDesktopLayout()) document.body.classList.remove('sidebar-collapsed');
    }

    function toggleDesktopCollapse() {
        if (!isDesktopLayout()) return;
        const next = !document.body.classList.contains('sidebar-collapsed');
        writeStoredScrollTop();
        writeCollapsed(next);
        applyCollapsedState();
    }

    function initGroups() {
        const stored = readJson(groupStorageKey, {});
        document.querySelectorAll('.menu-group').forEach(function (group) {
            if (group.dataset.sidebarGroupBound === '1') return;
            group.dataset.sidebarGroupBound = '1';

            const key = group.getAttribute('data-group-key');
            const toggle = group.querySelector('.menu-group-toggle');
            const hasActive = group.classList.contains('has-active');

            if (Object.prototype.hasOwnProperty.call(stored, key) && !hasActive) {
                group.classList.toggle('open', stored[key] === true);
                group.classList.toggle('collapsed', stored[key] !== true);
            }
            if (hasActive) {
                group.classList.add('open');
                group.classList.remove('collapsed');
            }
            if (toggle) {
                toggle.setAttribute('aria-expanded', group.classList.contains('open') ? 'true' : 'false');
                toggle.addEventListener('click', function () {
                    if (document.body.classList.contains('sidebar-collapsed')) {
                        writeCollapsed(false);
                        applyCollapsedState();
                        return;
                    }
                    const nextOpen = !group.classList.contains('open');
                    group.classList.toggle('open', nextOpen);
                    group.classList.toggle('collapsed', !nextOpen);
                    toggle.setAttribute('aria-expanded', nextOpen ? 'true' : 'false');
                    const nextState = readJson(groupStorageKey, {});
                    nextState[key] = nextOpen;
                    writeJson(groupStorageKey, nextState);
                    window.setTimeout(writeStoredScrollTop, 0);
                });
            }
        });
    }

    function bindSearchForms() {
        document.querySelectorAll('.sidebar-search-form, .quick-search-form').forEach(function (form) {
            if (form.dataset.sidebarSearchBound === '1') return;
            form.dataset.sidebarSearchBound = '1';
            form.addEventListener('submit', function (event) {
                const input = form.querySelector('input[name="q"]');
                const value = input ? input.value.trim() : '';
                if (!value) {
                    event.preventDefault();
                    if (input) input.focus();
                    return;
                }
                if (input) input.value = value;
            });
        });
    }

    function bindSidebarLinks() {
        const side = sidebar();
        if (!side) return;
        side.querySelectorAll('.nav-item, .sidebar-quick-actions a').forEach(function (link) {
            if (link.dataset.sidebarLinkBound === '1') return;
            link.dataset.sidebarLinkBound = '1';
            link.addEventListener('click', function () {
                writeStoredScrollTop();
                if (settings.mobileAutoClose && mobileQuery.matches) closeMobileSidebar();
            });
        });
    }

    function bindShellControls() {
        const hamburger = document.getElementById('mobile-hamburger');
        if (hamburger && hamburger.dataset.sidebarBound !== '1') {
            hamburger.dataset.sidebarBound = '1';
            hamburger.setAttribute('aria-expanded', sidebar()?.classList.contains('open') ? 'true' : 'false');
            hamburger.addEventListener('click', function (event) {
                event.preventDefault();
                toggleMobileSidebar();
            });
        }

        const over = overlay();
        if (over && over.dataset.sidebarBound !== '1') {
            over.dataset.sidebarBound = '1';
            over.addEventListener('click', closeMobileSidebar);
        }

        const collapse = document.getElementById('sidebar-collapse-toggle');
        if (collapse && collapse.dataset.sidebarBound !== '1') {
            collapse.dataset.sidebarBound = '1';
            collapse.addEventListener('click', function (event) {
                event.preventDefault();
                toggleDesktopCollapse();
            });
        }
    }

    function initScrollMemory() {
        const scroll = sidebarScroll();
        if (!scroll || scroll.dataset.sidebarScrollBound === '1') return;
        scroll.dataset.sidebarScrollBound = '1';
        window.requestAnimationFrame(function () {
            scroll.scrollTop = readStoredScrollTop();
            window.setTimeout(revealActiveMenuIfNeeded, 80);
        });
        scroll.addEventListener('scroll', function () {
            window.clearTimeout(scroll.__melonLiteScrollTimer);
            scroll.__melonLiteScrollTimer = window.setTimeout(writeStoredScrollTop, 120);
        }, { passive: true });
        window.addEventListener('beforeunload', writeStoredScrollTop);
        document.addEventListener('visibilitychange', function () {
            if (document.visibilityState === 'hidden') writeStoredScrollTop();
        });
    }

    function handleViewportChange() {
        if (isDesktopLayout()) {
            closeMobileSidebar();
        } else {
            document.body.classList.remove('sidebar-collapsed');
        }
        applyCollapsedState();
    }

    function initSidebar() {
        bindShellControls();
        initGroups();
        bindSearchForms();
        bindSidebarLinks();
        initScrollMemory();
        applyCollapsedState();
        updateActiveMenu(window.location.href);
    }

    document.addEventListener('keydown', function (event) {
        if (event.key === 'Escape') closeMobileSidebar();
    });

    if (desktopQuery.addEventListener) desktopQuery.addEventListener('change', handleViewportChange);
    else if (desktopQuery.addListener) desktopQuery.addListener(handleViewportChange);

    document.addEventListener('melonlite:page-ready', initSidebar);
    document.addEventListener('DOMContentLoaded', initSidebar);
    if (document.readyState !== 'loading') initSidebar();

    window.MelonLiteSidebar = {
        saveScroll: writeStoredScrollTop,
        updateActive: updateActiveMenu,
        closeMobile: closeMobileSidebar,
        toggleCollapsed: toggleDesktopCollapse,
        init: initSidebar,
        applyCollapsed: applyCollapsedState
    };
})();
