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

    const MODAL_SELECTOR = [
        '#feedback-modal',
        '#metadata-request-modal',
        '#download-modal',
        '#playlist-modal',
        '#pwa-install-banner',
        '#pwa-guide-modal',
        '#onboarding-modal',
        '#guest-preview-prompt',
        '#queue-save-modal',
        '#expand-player-overlay'
    ].join(',');

    const FOCUSABLE_SELECTOR = [
        'a[href]',
        'button:not([disabled])',
        'input:not([disabled]):not([type="hidden"])',
        'select:not([disabled])',
        'textarea:not([disabled])',
        '[tabindex]:not([tabindex="-1"])'
    ].join(',');

    let lastTrigger = null;
    const openModals = new WeakSet();

    const labelRules = [
        ['#btn-prev', '이전 곡'],
        ['#btn-play-pause', '재생 또는 일시정지'],
        ['#btn-next', '다음 곡'],
        ['#btn-queue', '재생 대기열 열기'],
        ['#btn-expand-player', '전체화면 플레이어 열기'],
        ['#expand-player-close', '전체화면 플레이어 닫기'],
        ['#expand-btn-shuffle', '셔플 켜기 또는 끄기'],
        ['#expand-btn-prev', '이전 곡'],
        ['#expand-btn-play-pause', '재생 또는 일시정지'],
        ['#expand-btn-next', '다음 곡'],
        ['#expand-btn-repeat', '반복 모드 변경'],
        ['#expand-btn-like', '좋아요'],
        ['#expand-btn-add-playlist', '플레이리스트에 추가'],
        ['#expand-btn-lyrics-toggle', '가사 보기 또는 접기'],
        ['#tab-btn-queue', '대기열 탭'],
        ['#tab-btn-lyrics', '가사 탭'],
        ['#pwa-guide-close', 'PWA 안내 닫기'],
        ['#pwa-install-close', 'PWA 설치 안내 닫기'],
        ['#queue-close', '재생 대기열 닫기'],
        ['#btn-clear-queue', '재생 대기열 비우기'],
        ['#modal-close', '플레이리스트 창 닫기'],
        ['#download-modal-close', '다운로드 창 닫기'],
        ['#feedback-modal-close', '피드백 창 닫기'],
        ['#metadata-request-modal-close', '음악 정보 수정 요청 창 닫기'],
        ['#mobile-hamburger', '메뉴 열기'],
        ['#sidebar-collapse-toggle', '사이드바 접기 또는 펼치기'],
        ['#scroll-top-btn', '페이지 상단으로 이동'],
        ['#feedback-open-btn', '피드백 또는 오류 신고 열기']
    ];

    function isVisible(element) {
        return isVisuallyVisible(element) && element.getAttribute('aria-hidden') !== 'true';
    }

    function isVisuallyVisible(element) {
        if (!element || element.hidden) return false;
        const style = window.getComputedStyle(element);
        return style.display !== 'none' && style.visibility !== 'hidden' && Number(style.opacity || 1) !== 0;
    }

    function isTypingTarget(element) {
        if (!element) return false;
        const tag = String(element.tagName || '').toLowerCase();
        return tag === 'input' || tag === 'textarea' || tag === 'select' || element.isContentEditable;
    }

    function setLabel(element, label) {
        if (!element || !label) return;
        if (!element.getAttribute('aria-label')) element.setAttribute('aria-label', label);
        if (!element.getAttribute('title')) element.setAttribute('title', label);
    }

    function setAttributeIfChanged(element, name, value) {
        if (!element || element.getAttribute(name) === value) return;
        element.setAttribute(name, value);
    }

    function ensureButtonLabels(root) {
        const scope = root || document;
        labelRules.forEach(function (rule) {
            scope.querySelectorAll(rule[0]).forEach(function (element) {
                setLabel(element, rule[1]);
            });
        });

        scope.querySelectorAll('button, .btn, .control-btn, .like-btn, .add-next-btn, .add-playlist-btn, .download-song-btn, .metadata-request-btn').forEach(function (button) {
            if (button.tagName === 'BUTTON' && !button.getAttribute('type') && !button.closest('form')) {
                button.setAttribute('type', 'button');
            }
            const text = (button.textContent || '').replace(/\s+/g, ' ').trim();
            const title = button.getAttribute('title') || button.getAttribute('aria-label') || '';
            if (!title && !text) {
                const icon = button.querySelector('i');
                const className = icon ? icon.className : '';
                if (/heart/.test(className)) setLabel(button, '좋아요');
                else if (/plus/.test(className)) setLabel(button, '추가');
                else if (/download/.test(className)) setLabel(button, '다운로드');
                else if (/play/.test(className)) setLabel(button, '재생');
                else if (/pause/.test(className)) setLabel(button, '일시정지');
                else if (/times|xmark/.test(className)) setLabel(button, '닫기');
            }
        });

        scope.querySelectorAll('button i, .btn i, .control-btn i').forEach(function (icon) {
            if (!icon.getAttribute('aria-hidden')) icon.setAttribute('aria-hidden', 'true');
        });
    }

    function ensureModalAttributes(root) {
        const scope = root || document;
        scope.querySelectorAll(MODAL_SELECTOR).forEach(function (modal) {
            setAttributeIfChanged(modal, 'aria-hidden', isVisible(modal) ? 'false' : 'true');
            const dialog = modal.matches('[role="dialog"]') ? modal : modal.querySelector('[role="dialog"], .modal-box, .pwa-install-card, .pwa-guide-card, .onboarding-card, .expand-player-container');
            if (dialog) {
                if (!dialog.getAttribute('role')) dialog.setAttribute('role', 'dialog');
                if (!dialog.getAttribute('aria-modal')) dialog.setAttribute('aria-modal', 'true');
                if (!dialog.hasAttribute('tabindex')) dialog.setAttribute('tabindex', '-1');
            }
        });
    }

    function firstFocusable(modal) {
        const dialog = modal.matches('[role="dialog"]') ? modal : modal.querySelector('[role="dialog"], .modal-box, .pwa-install-card, .pwa-guide-card, .onboarding-card, .expand-player-container') || modal;
        const focusables = Array.from(dialog.querySelectorAll(FOCUSABLE_SELECTOR)).filter(isVisible);
        return focusables[0] || dialog;
    }

    function visibleModal() {
        const modals = Array.from(document.querySelectorAll(MODAL_SELECTOR)).filter(isVisuallyVisible);
        return modals.length ? modals[modals.length - 1] : null;
    }

    function handleModalState() {
        document.querySelectorAll(MODAL_SELECTOR).forEach(function (modal) {
            const visible = isVisuallyVisible(modal);
            setAttributeIfChanged(modal, 'aria-hidden', visible ? 'false' : 'true');
            if (visible && !openModals.has(modal)) {
                openModals.add(modal);
                const target = firstFocusable(modal);
                window.setTimeout(function () {
                    try { target.focus({ preventScroll: true }); } catch (err) {}
                }, 30);
                return;
            }
            if (!visible && openModals.has(modal)) {
                openModals.delete(modal);
                if (lastTrigger && document.contains(lastTrigger) && typeof lastTrigger.focus === 'function') {
                    window.setTimeout(function () {
                        try { lastTrigger.focus({ preventScroll: true }); } catch (err) {}
                    }, 20);
                }
            }
        });
    }

    function clickCloseButton(modal) {
        if (!modal) return false;
        const close = modal.querySelector([
            '.modal-close-btn',
            '.expand-close',
            '.queue-save-close',
            '.onboarding-close',
            '[data-onboarding-close]',
            '#feedback-cancel-btn',
            '#metadata-request-cancel-btn',
            '#download-cancel-btn',
            '#queue-close'
        ].join(','));
        if (close && typeof close.click === 'function') {
            close.click();
            return true;
        }
        return false;
    }

    function trapFocus(event) {
        if (event.key !== 'Tab') return;
        const modal = visibleModal();
        if (!modal) return;
        const dialog = modal.matches('[role="dialog"]') ? modal : modal.querySelector('[role="dialog"], .modal-box, .pwa-install-card, .pwa-guide-card, .onboarding-card, .expand-player-container') || modal;
        const focusables = Array.from(dialog.querySelectorAll(FOCUSABLE_SELECTOR)).filter(isVisible);
        if (!focusables.length) {
            event.preventDefault();
            dialog.focus();
            return;
        }
        const first = focusables[0];
        const last = focusables[focusables.length - 1];
        if (event.shiftKey && document.activeElement === first) {
            event.preventDefault();
            last.focus();
        } else if (!event.shiftKey && document.activeElement === last) {
            event.preventDefault();
            first.focus();
        }
    }

    function bindGlobalEvents() {
        let modalStateFrame = 0;

        function rememberTrigger(event) {
            const trigger = event.target.closest && event.target.closest('button, a, [role="button"], input, select, textarea');
            if (trigger && trigger.closest(MODAL_SELECTOR) && isVisible(trigger.closest(MODAL_SELECTOR))) return;
            if (trigger) lastTrigger = trigger;
        }

        function scheduleModalStateCheck() {
            if (modalStateFrame) return;
            modalStateFrame = window.requestAnimationFrame(function () {
                modalStateFrame = 0;
                handleModalState();
            });
        }

        document.addEventListener('pointerdown', function (event) {
            rememberTrigger(event);
        }, true);
        document.addEventListener('click', rememberTrigger, true);

        document.addEventListener('keydown', function (event) {
            if (event.defaultPrevented) return;
            if (event.key === 'Escape') {
                if (isTypingTarget(event.target) && String(event.target.value || '').length > 0) return;
                const modal = visibleModal();
                if (modal && clickCloseButton(modal)) {
                    event.preventDefault();
                    return;
                }
            }
            trapFocus(event);
        }, true);

        const observer = new MutationObserver(scheduleModalStateCheck);
        observer.observe(document.documentElement, {
            attributes: true,
            childList: true,
            subtree: true,
            attributeFilter: ['hidden', 'style', 'class', 'aria-hidden']
        });
    }

    function enhance(scope) {
        ensureButtonLabels(scope);
        ensureModalAttributes(scope);
        handleModalState();
    }

    function init() {
        enhance(document);
    }

    bindGlobalEvents();
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
    document.addEventListener('melonlite:page-ready', init);
})();
