(function () {
    'use strict';

    const PREF_KEY = 'melon_lite_user_preferences_v1';
    const LEGACY_PREF_KEY = 'melonlite:userPreferences:v1';
    const VALID_THEME = ['system', 'light', 'dark'];
    const VALID_REPEAT = ['none', 'all', 'one'];
    const VALID_DENSITY = ['comfortable', 'compact', 'card'];
    const VALID_LIBRARY_VIEW = ['list', 'card', 'compact'];
    const VALID_LIBRARY_DENSITY = ['normal', 'dense', 'large'];
    const VALID_LIBRARY_SORT = ['recent', 'title', 'artist', 'album', 'recent_played', 'popular', 'liked', 'year_desc', 'year_asc'];
    const LIBRARY_VIEW_KEY = 'melon_lite_library_view_mode';
    const LIBRARY_DENSITY_KEY = 'melon_lite_library_density';
    const LIBRARY_SORT_KEY = 'melon_lite_library_sort';
    const DEFAULTS = {
        themeMode: 'system',
        playerBarVisible: '1',
        preferredExpandedPlayer: '0',
        resumePlayback: '1',
        defaultShuffle: '0',
        defaultRepeat: 'none',
        defaultVolume: '80',
        showAnnouncements: '1',
        showUpdateNotices: '1',
        showFeedbackButton: '1',
        sidebarCollapsed: '0',
        listDensity: 'comfortable'
    };

    function storageGet(key) {
        try {
            return window.localStorage.getItem(key);
        } catch (err) {
            return null;
        }
    }

    function storageSet(key, value) {
        try {
            window.localStorage.setItem(key, value);
            return true;
        } catch (err) {
            return false;
        }
    }

    function storageRemove(key) {
        try {
            window.localStorage.removeItem(key);
        } catch (err) {
        }
    }

    function parseJson(raw) {
        if (!raw) return {};
        try {
            const parsed = JSON.parse(raw);
            return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : {};
        } catch (err) {
            storageRemove(PREF_KEY);
            return {};
        }
    }

    function hasStoredPrefs() {
        return Boolean(storageGet(PREF_KEY) || storageGet(LEGACY_PREF_KEY));
    }

    function existingPreferenceDefaults() {
        const defaults = Object.assign({}, DEFAULTS);
        const storedThemeMode = storageGet('melon_lite_theme_mode');
        const storedTheme = storageGet('melon_lite_theme');
        if (VALID_THEME.includes(storedThemeMode)) {
            defaults.themeMode = storedThemeMode;
        } else if (storedTheme === 'light' || storedTheme === 'dark') {
            defaults.themeMode = storedTheme;
        }

        const collapsed = storageGet('melon_lite_sidebar_collapsed');
        if (collapsed === '1' || collapsed === '0') defaults.sidebarCollapsed = collapsed;

        const shuffle = storageGet('melon_lite_player_default_shuffle');
        if (shuffle === '1' || shuffle === '0') defaults.defaultShuffle = shuffle;

        const repeat = storageGet('melon_lite_player_default_repeat');
        if (VALID_REPEAT.includes(repeat)) defaults.defaultRepeat = repeat;

        const volume = storageGet('melon_lite_player_default_volume');
        if (volume !== null) defaults.defaultVolume = clampVolume(volume);

        const resume = storageGet('melon_lite_player_resume_enabled');
        if (resume === '1' || resume === '0') defaults.resumePlayback = resume;

        return defaults;
    }

    function normalizeBool(value, fallback) {
        if (value === true || value === '1' || value === 1) return '1';
        if (value === false || value === '0' || value === 0) return '0';
        return fallback;
    }

    function clampVolume(value) {
        const parsed = parseInt(value, 10);
        if (!Number.isFinite(parsed)) return DEFAULTS.defaultVolume;
        return String(Math.max(0, Math.min(100, parsed)));
    }

    function sanitizePrefs(input) {
        const prefs = Object.assign({}, DEFAULTS, input || {});
        prefs.themeMode = VALID_THEME.includes(prefs.themeMode) ? prefs.themeMode : DEFAULTS.themeMode;
        prefs.playerBarVisible = normalizeBool(prefs.playerBarVisible, DEFAULTS.playerBarVisible);
        prefs.preferredExpandedPlayer = normalizeBool(prefs.preferredExpandedPlayer, DEFAULTS.preferredExpandedPlayer);
        prefs.resumePlayback = normalizeBool(prefs.resumePlayback, DEFAULTS.resumePlayback);
        prefs.defaultShuffle = normalizeBool(prefs.defaultShuffle, DEFAULTS.defaultShuffle);
        prefs.defaultRepeat = VALID_REPEAT.includes(prefs.defaultRepeat) ? prefs.defaultRepeat : DEFAULTS.defaultRepeat;
        prefs.defaultVolume = clampVolume(prefs.defaultVolume);
        prefs.showAnnouncements = normalizeBool(prefs.showAnnouncements, DEFAULTS.showAnnouncements);
        prefs.showUpdateNotices = normalizeBool(prefs.showUpdateNotices, DEFAULTS.showUpdateNotices);
        prefs.showFeedbackButton = normalizeBool(prefs.showFeedbackButton, DEFAULTS.showFeedbackButton);
        prefs.sidebarCollapsed = normalizeBool(prefs.sidebarCollapsed, DEFAULTS.sidebarCollapsed);
        prefs.listDensity = VALID_DENSITY.includes(prefs.listDensity) ? prefs.listDensity : DEFAULTS.listDensity;
        return prefs;
    }

    function readPrefs(createIfMissing) {
        const primaryRaw = storageGet(PREF_KEY);
        const legacyRaw = primaryRaw ? null : storageGet(LEGACY_PREF_KEY);
        if (!primaryRaw && !legacyRaw && !createIfMissing) return null;
        const primary = parseJson(primaryRaw);
        const legacy = primaryRaw ? {} : parseJson(legacyRaw);
        const prefs = sanitizePrefs(Object.assign({}, existingPreferenceDefaults(), legacy, primary));
        if (!primaryRaw && legacyRaw) savePrefs(prefs);
        return prefs;
    }

    function savePrefs(prefs) {
        return storageSet(PREF_KEY, JSON.stringify(sanitizePrefs(prefs)));
    }

    function resolvedTheme(mode) {
        if (mode === 'light' || mode === 'dark') return mode;
        try {
            return window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
        } catch (err) {
            return 'dark';
        }
    }

    function applyTheme(mode) {
        const resolved = resolvedTheme(mode);
        storageSet('melon_lite_theme_mode', mode);
        storageSet('melon_lite_theme', resolved);
        if (document.documentElement) {
            document.documentElement.setAttribute('data-user-theme-mode', mode);
        }
        if (!document.body) return;
        Array.from(document.body.classList).forEach(function (className) {
            if (className.indexOf('theme-') === 0) document.body.classList.remove(className);
        });
        document.body.classList.add('theme-' + resolved);
        document.body.setAttribute('data-user-theme-mode', mode);
    }

    function applyBodyFlags(prefs) {
        if (!document.body) return;
        document.body.classList.toggle('user-pref-hide-player', prefs.playerBarVisible !== '1');
        document.body.classList.toggle('user-pref-prefer-expanded-player', prefs.preferredExpandedPlayer === '1');
        document.body.classList.toggle('user-pref-hide-announcements', prefs.showAnnouncements !== '1');
        document.body.classList.toggle('user-pref-hide-update-notices', prefs.showUpdateNotices !== '1');
        document.body.classList.toggle('user-pref-hide-feedback', prefs.showFeedbackButton !== '1');
        document.body.classList.toggle('user-pref-density-compact', prefs.listDensity === 'compact');
        document.body.classList.toggle('user-pref-density-card', prefs.listDensity === 'card');
    }

    function applyPlayerDefaults(prefs) {
        storageSet('melon_lite_player_resume_enabled', prefs.resumePlayback);
        storageSet('melon_lite_player_default_shuffle', prefs.defaultShuffle);
        storageSet('melon_lite_player_default_repeat', prefs.defaultRepeat);
        storageSet('melon_lite_player_default_volume', prefs.defaultVolume);

        const audio = document.getElementById('audio-player');
        const volume = parseInt(prefs.defaultVolume, 10) / 100;
        if (audio && Number.isFinite(volume)) {
            audio.volume = Math.max(0, Math.min(1, volume));
        }
        if (window.AppPlayer && typeof window.AppPlayer.saveState === 'function') {
            try { window.AppPlayer.saveState(); } catch (err) {}
        }
    }

    function applySidebarDefaults(prefs) {
        storageSet('melon_lite_sidebar_collapsed', prefs.sidebarCollapsed === '1' ? '1' : '0');
    }

    function applyPrefs(prefs) {
        const clean = sanitizePrefs(prefs);
        applyTheme(clean.themeMode);
        applyBodyFlags(clean);
        applyPlayerDefaults(clean);
        applySidebarDefaults(clean);
        window.dispatchEvent(new CustomEvent('melonlite:preferences-changed', { detail: clean }));
        return clean;
    }

    function updateStatus(message) {
        const status = document.getElementById('user-settings-status');
        if (!status) return;
        status.textContent = message;
        status.classList.add('is-visible');
        window.clearTimeout(updateStatus.timer);
        updateStatus.timer = window.setTimeout(function () {
            status.classList.remove('is-visible');
        }, 2200);
    }

    function syncControls() {
        const page = document.querySelector('[data-user-settings-page]');
        if (!page) return;
        const prefs = readPrefs(true);
        page.querySelectorAll('[data-pref-key]').forEach(function (control) {
            const key = control.getAttribute('data-pref-key');
            if (!Object.prototype.hasOwnProperty.call(prefs, key)) return;
            if (control.type === 'checkbox') {
                control.checked = prefs[key] === '1';
            } else if (control.type === 'radio') {
                control.checked = String(control.value) === String(prefs[key]);
            } else {
                control.value = prefs[key];
            }
        });
        const volumeLabel = document.getElementById('default-volume-label');
        if (volumeLabel) volumeLabel.textContent = prefs.defaultVolume + '%';
        updateStatus('설정이 적용되었습니다.');
    }

    function updatePreference(key, value) {
        const prefs = readPrefs(true);
        prefs[key] = value;
        const clean = sanitizePrefs(prefs);
        savePrefs(clean);
        applyPrefs(clean);
        syncControls();
        updateStatus('설정을 저장했습니다.');
    }

    function resetPwaGuide() {
        if (typeof window.resetMelonLitePwaInstallGuide === 'function') {
            try {
                window.resetMelonLitePwaInstallGuide();
                updateStatus('PWA 설치 안내를 다시 표시했습니다.');
                return;
            } catch (err) {
            }
        }
        [
            'melon_lite_pwa_install_dismissed_at',
            'melon_lite_pwa_install_never',
            'melon_lite_pwa_banner_closed',
            'melon_lite_pwa_install_last_shown_at',
            'melon_lite_pwa_install_guide_seen',
            'melon_lite_pwa_install_modal_open',
            'pwaInstallDismissedAt',
            'pwaInstallNeverShow'
        ].forEach(storageRemove);
        updateStatus('PWA 설치 안내 상태를 초기화했습니다.');
    }

    function resetSettings() {
        storageRemove(PREF_KEY);
        storageRemove(LEGACY_PREF_KEY);
        const prefs = sanitizePrefs(DEFAULTS);
        savePrefs(prefs);
        applyPrefs(prefs);
        syncControls();
        updateStatus('기본값으로 복원했습니다.');
    }

    function normalizeLibraryValue(value, allowed, fallback) {
        value = String(value || '');
        return allowed.includes(value) ? value : fallback;
    }

    function writeCookie(name, value, days) {
        try {
            const maxAge = Math.max(1, parseInt(days, 10) || 180) * 86400;
            document.cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value) + '; path=/; max-age=' + maxAge + '; samesite=lax';
        } catch (err) {
        }
    }

    function setLibraryPressed(page, selector, activeValue) {
        page.querySelectorAll(selector).forEach(function (button) {
            const value = button.getAttribute(selector.indexOf('density') >= 0 ? 'data-library-density' : 'data-library-view');
            const active = value === activeValue;
            button.classList.toggle('active', active);
            button.setAttribute('aria-pressed', active ? 'true' : 'false');
        });
    }

    function shouldForceCardLibraryView() {
        try {
            return window.matchMedia('(max-width: 1199px)').matches;
        } catch (err) {
            return window.innerWidth <= 1199;
        }
    }

    function applyLibraryDisplay() {
        const page = document.querySelector('[data-library-page="all"]');
        if (!page) return;
        const forceCard = shouldForceCardLibraryView();
        const viewMode = forceCard ? 'card' : normalizeLibraryValue(storageGet(LIBRARY_VIEW_KEY), VALID_LIBRARY_VIEW, 'list');
        const density = forceCard ? 'normal' : normalizeLibraryValue(storageGet(LIBRARY_DENSITY_KEY), VALID_LIBRARY_DENSITY, 'normal');
        const sortSelect = page.querySelector('select[name="sort"]');
        if (sortSelect) {
            const sortValue = normalizeLibraryValue(sortSelect.value, VALID_LIBRARY_SORT, 'recent');
            storageSet(LIBRARY_SORT_KEY, sortValue);
            writeCookie(LIBRARY_SORT_KEY, sortValue, 180);
        }

        VALID_LIBRARY_VIEW.forEach(function (mode) {
            page.classList.remove('library-view-mode-' + mode);
        });
        VALID_LIBRARY_DENSITY.forEach(function (mode) {
            page.classList.remove('library-density-' + mode);
        });
        page.classList.add('library-view-mode-' + viewMode);
        page.classList.add('library-density-' + density);
        page.setAttribute('data-current-library-view', viewMode);
        page.setAttribute('data-current-library-density', density);
        page.setAttribute('data-library-view-locked', forceCard ? 'card' : '0');
        setLibraryPressed(page, '[data-library-view]', viewMode);
        setLibraryPressed(page, '[data-library-density]', density);
    }

    function bindOnce() {
        if (window.__MELON_LITE_USER_SETTINGS_BOUND) return;
        window.__MELON_LITE_USER_SETTINGS_BOUND = true;

        document.addEventListener('change', function (event) {
            const control = event.target.closest('[data-pref-key]');
            if (!control) return;
            const key = control.getAttribute('data-pref-key');
            let value;
            if (control.type === 'checkbox') {
                value = control.checked ? '1' : '0';
            } else {
                value = String(control.value || '');
            }
            updatePreference(key, value);
        });

        document.addEventListener('change', function (event) {
            const sortSelect = event.target.closest('[data-library-page="all"] select[name="sort"], .music-list-page select[name="sort"]');
            if (!sortSelect) return;
            const value = normalizeLibraryValue(sortSelect.value, VALID_LIBRARY_SORT, 'recent');
            storageSet(LIBRARY_SORT_KEY, value);
            writeCookie(LIBRARY_SORT_KEY, value, 180);
        });

        document.addEventListener('input', function (event) {
            const control = event.target.closest('input[type="range"][data-pref-key="defaultVolume"]');
            if (!control) return;
            const label = document.getElementById('default-volume-label');
            if (label) label.textContent = clampVolume(control.value) + '%';
        });

        document.addEventListener('click', function (event) {
            const viewButton = event.target.closest('[data-library-view]');
            if (viewButton) {
                const value = normalizeLibraryValue(viewButton.getAttribute('data-library-view'), VALID_LIBRARY_VIEW, 'list');
                storageSet(LIBRARY_VIEW_KEY, value);
                applyLibraryDisplay();
                return;
            }
            const densityButton = event.target.closest('[data-library-density]');
            if (densityButton) {
                const value = normalizeLibraryValue(densityButton.getAttribute('data-library-density'), VALID_LIBRARY_DENSITY, 'normal');
                storageSet(LIBRARY_DENSITY_KEY, value);
                applyLibraryDisplay();
                return;
            }
            if (event.target.closest('[data-reset-pwa-guide]')) {
                resetPwaGuide();
                return;
            }
            if (event.target.closest('[data-reset-user-settings]')) {
                resetSettings();
            }
        });

        try {
            const media = window.matchMedia('(prefers-color-scheme: light)');
            const handler = function () {
                const prefs = readPrefs(false);
                if (prefs && prefs.themeMode === 'system') applyPrefs(prefs);
            };
            if (typeof media.addEventListener === 'function') media.addEventListener('change', handler);
            else if (typeof media.addListener === 'function') media.addListener(handler);
        } catch (err) {
        }

        let libraryResizeTimer = null;
        const refreshLibraryDisplay = function () {
            window.clearTimeout(libraryResizeTimer);
            libraryResizeTimer = window.setTimeout(applyLibraryDisplay, 120);
        };
        window.addEventListener('resize', refreshLibraryDisplay, { passive: true });
        window.addEventListener('orientationchange', refreshLibraryDisplay, { passive: true });
    }

    function init() {
        bindOnce();
        const page = document.querySelector('[data-user-settings-page]');
        const stored = hasStoredPrefs();
        const prefs = readPrefs(Boolean(page));
        if (prefs && stored) applyPrefs(prefs);
        if (page) syncControls();
        applyLibraryDisplay();
    }

    document.addEventListener('DOMContentLoaded', init);
    document.addEventListener('melonlite:pjax-complete', init);
    document.addEventListener('melonlite:page-ready', init);
    init();

    window.MelonLiteUserSettings = {
        read: function () { return readPrefs(true); },
        apply: function () {
            const prefs = readPrefs(false);
            return prefs ? applyPrefs(prefs) : null;
        },
        reset: resetSettings
    };
})();
