(() => {
    const THEME_KEY = 'scrumPoker.ui.theme';
    const MODE_KEY = 'scrumPoker.ui.mode';
    const WINDOW_LAYOUTS_KEY = 'scrumPoker.ui.windowLayouts.v1';
    const DEFAULT_THEME = 'win98';
    const MODE_ICON_LIGHT = '/static/img/Windows Icons - PNG/desk.cpl_14_40-0.png';
    const MODE_ICON_DARK = '/static/img/Windows Icons - PNG/desk.cpl_14_40-6.png';

    let floatingWindowZ = 80;
    let windowLayouts = {};
    let windowDefs = [];
    let accessState = { admin: false };

    function isMobileViewport() {
        return window.matchMedia('(max-width: 899px)').matches;
    }

    function applyTheme(theme) {
        const normalized = theme || DEFAULT_THEME;
        document.documentElement.setAttribute('data-ui-theme', normalized);
    }

    function applyMode(mode) {
        if (mode === 'dark') {
            document.documentElement.setAttribute('data-theme', 'dark');
            return;
        }
        document.documentElement.removeAttribute('data-theme');
    }

    function getCurrentTheme() {
        return document.documentElement.getAttribute('data-ui-theme') || DEFAULT_THEME;
    }

    function getCurrentMode() {
        return document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light';
    }

    function clamp(value, min, max) {
        return Math.min(max, Math.max(min, value));
    }

    function hasOwn(obj, key) {
        return Object.prototype.hasOwnProperty.call(obj, key);
    }

    function parseJSON(value, fallback) {
        if (!value) {
            return fallback;
        }
        try {
            return JSON.parse(value);
        } catch (_err) {
            return fallback;
        }
    }

    function hasWindowAccess(def) {
        const rights = def.rights || 'all';
        if (rights === 'admin') {
            return Boolean(accessState.admin);
        }
        return true;
    }

    function loadWindowLayouts() {
        try {
            const raw = localStorage.getItem(WINDOW_LAYOUTS_KEY);
            if (!raw) {
                return {};
            }
            const parsed = JSON.parse(raw);
            return parsed && typeof parsed === 'object' ? parsed : {};
        } catch (_err) {
            return {};
        }
    }

    function saveWindowLayouts() {
        localStorage.setItem(WINDOW_LAYOUTS_KEY, JSON.stringify(windowLayouts));
    }

    function normalizeLayout(raw, defaults) {
        const fallback = defaults || { left: 16, top: 88, width: 360, height: 220 };
        const minWidth = 260;
        const minHeight = 160;

        const width = Number(raw?.width);
        const height = Number(raw?.height);
        const left = Number(raw?.left);
        const top = Number(raw?.top);

        return {
            width: Number.isFinite(width) ? Math.max(minWidth, width) : fallback.width,
            height: Number.isFinite(height) ? Math.max(minHeight, height) : fallback.height,
            left: Number.isFinite(left) ? left : fallback.left,
            top: Number.isFinite(top) ? top : fallback.top,
        };
    }

    function clampLayoutToViewport(layout) {
        const margin = 8;
        const minWidth = 260;
        const minHeight = 160;
        const maxWidth = Math.max(minWidth, window.innerWidth - margin * 2);
        const maxHeight = Math.max(minHeight, window.innerHeight - margin * 2);

        const width = clamp(layout.width, minWidth, maxWidth);
        const height = clamp(layout.height, minHeight, maxHeight);
        const left = clamp(layout.left, margin, Math.max(margin, window.innerWidth - width - margin));
        const top = clamp(layout.top, margin, Math.max(margin, window.innerHeight - height - margin));

        return { left, top, width, height };
    }

    function applyLayout(windowEl, layout) {
        windowEl.style.left = `${layout.left}px`;
        windowEl.style.top = `${layout.top}px`;
        windowEl.style.width = `${layout.width}px`;
        windowEl.style.height = `${layout.height}px`;
        windowEl.style.right = 'auto';
        windowEl.style.bottom = 'auto';
        windowEl.style.transform = 'none';
    }

    function readLayoutFromDOM(windowEl) {
        const rect = windowEl.getBoundingClientRect();
        return {
            left: rect.left,
            top: rect.top,
            width: rect.width,
            height: rect.height,
        };
    }

    function bringWindowToFront(windowEl) {
        floatingWindowZ += 1;
        windowEl.style.zIndex = String(floatingWindowZ);
    }

    function getDefaultLayout(el, index) {
        const step = 28 * index;
        return normalizeLayout({
            left: Number(el.dataset.windowDefaultLeft) || 16 + step,
            top: Number(el.dataset.windowDefaultTop) || 88 + step,
            width: Number(el.dataset.windowDefaultWidth) || 360,
            height: Number(el.dataset.windowDefaultHeight) || 220,
        });
    }

    function persistWindowLayout(windowEl) {
        const id = windowEl.id;
        if (!id || isMobileViewport()) {
            return;
        }
        windowLayouts[id] = clampLayoutToViewport(readLayoutFromDOM(windowEl));
        saveWindowLayouts();
    }

    function measureLayoutFromContent(def) {
        const windowEl = def.el;
        const fallback = def.defaultLayout;
        const wasHidden = windowEl.classList.contains('hidden');
        const previousStyles = {
            visibility: windowEl.style.visibility,
            left: windowEl.style.left,
            top: windowEl.style.top,
            width: windowEl.style.width,
            height: windowEl.style.height,
            right: windowEl.style.right,
            bottom: windowEl.style.bottom,
            transform: windowEl.style.transform,
        };

        if (wasHidden) {
            windowEl.classList.remove('hidden');
        }

        windowEl.style.visibility = 'hidden';
        windowEl.style.left = '-10000px';
        windowEl.style.top = '-10000px';
        windowEl.style.width = 'max-content';
        windowEl.style.height = 'auto';
        windowEl.style.right = 'auto';
        windowEl.style.bottom = 'auto';
        windowEl.style.transform = 'none';

        const rect = windowEl.getBoundingClientRect();

        windowEl.style.visibility = previousStyles.visibility;
        windowEl.style.left = previousStyles.left;
        windowEl.style.top = previousStyles.top;
        windowEl.style.width = previousStyles.width;
        windowEl.style.height = previousStyles.height;
        windowEl.style.right = previousStyles.right;
        windowEl.style.bottom = previousStyles.bottom;
        windowEl.style.transform = previousStyles.transform;

        if (wasHidden) {
            windowEl.classList.add('hidden');
        }

        return normalizeLayout({
            left: fallback.left,
            top: fallback.top,
            width: Number.isFinite(rect.width) && rect.width > 0 ? Math.ceil(rect.width) : fallback.width,
            height: Number.isFinite(rect.height) && rect.height > 0 ? Math.ceil(rect.height) : fallback.height,
        }, fallback);
    }

    function ensureWindowLayout(def, options = {}) {
        if (isMobileViewport()) {
            def.el.style.right = 'auto';
            def.el.style.bottom = 'auto';
            def.el.style.transform = 'none';
            return;
        }

        const hasSavedLayout = hasOwn(options, 'hasSavedLayout')
            ? options.hasSavedLayout
            : hasOwn(windowLayouts, def.id);
        const normalized = hasSavedLayout
            ? normalizeLayout(windowLayouts[def.id], def.defaultLayout)
            : measureLayoutFromContent(def);
        const clamped = clampLayoutToViewport(normalized);
        applyLayout(def.el, clamped);
        windowLayouts[def.id] = clamped;
    }

    function isWindowOpen(id) {
        const def = windowDefs.find((item) => item.id === id);
        return Boolean(def && !def.el.classList.contains('hidden'));
    }

    function closeWindowById(id) {
        const def = windowDefs.find((item) => item.id === id);
        if (!def) {
            return;
        }
        def.el.classList.add('hidden');
        syncTaskButtons();
    }

    function openWindowById(id) {
        const def = windowDefs.find((item) => item.id === id);
        if (!def || !hasWindowAccess(def)) {
            return;
        }
        ensureWindowLayout(def);
        def.el.classList.remove('hidden');
        bringWindowToFront(def.el);
        syncTaskButtons();
    }

    function resolveWindowIcon(def, theme) {
        return def.icons[theme] || def.icons.default || '/static/img/Windows Icons - PNG/main.cpl_14_109-1.png';
    }

    function renderTaskbarButtons() {
        const theme = getCurrentTheme();
        const visibleDefs = windowDefs
            .filter(hasWindowAccess)
            .sort((a, b) => a.order - b.order);

        const html = visibleDefs.map((def) => {
            const icon = resolveWindowIcon(def, theme);
            const safeTitle = def.title;
            return [
                `<button class="taskbar-program-btn" type="button" data-role="open-window" data-target="${def.id}" aria-label="Open ${safeTitle}">`,
                `<img class="taskbar-icon" src="${icon}" alt="">`,
                `<span>${safeTitle}</span>`,
                '</button>',
            ].join('');
        }).join('');

        document.querySelectorAll('[data-role="taskbar-program-list"]').forEach((container) => {
            container.innerHTML = html;
        });

        syncTaskButtons();
    }

    function syncTaskButtons() {
        document.querySelectorAll('[data-role="open-window"]').forEach((button) => {
            const target = button.dataset.target;
            button.classList.toggle('is-active', isWindowOpen(target));
        });
    }

    function syncControls() {
        const theme = getCurrentTheme();
        const mode = getCurrentMode();
        const modeLabel = mode === 'dark' ? 'Switch to Light Mode' : 'Switch to Dark Mode';
        const modeIcon = mode === 'dark' ? MODE_ICON_DARK : MODE_ICON_LIGHT;

        document.querySelectorAll('[data-role="theme-option"]').forEach((button) => {
            const selected = button.dataset.theme === theme;
            button.classList.toggle('is-selected', selected);
            button.setAttribute('aria-pressed', selected ? 'true' : 'false');
        });

        document.querySelectorAll('[data-role="mode-toggle-label"]').forEach((el) => {
            el.textContent = modeLabel;
        });

        document.querySelectorAll('[data-role="mode-icon"]').forEach((el) => {
            el.src = modeIcon;
        });

        document.querySelectorAll('#mode-status-text').forEach((el) => {
            el.textContent = `Current mode: ${mode === 'dark' ? 'Dark' : 'Light'}`;
        });

        renderTaskbarButtons();
    }

    function collectWindowDefinitions() {
        const windows = Array.from(document.querySelectorAll('[data-ui-window]'));
        windowDefs = windows.map((el, index) => ({
            id: el.id,
            el,
            title: el.dataset.windowTitle || el.id,
            rights: el.dataset.windowRights || 'all',
            order: Number(el.dataset.windowOrder) || (index + 1) * 10,
            icons: parseJSON(el.dataset.windowIcons, {}),
            defaultLayout: getDefaultLayout(el, index),
        })).filter((def) => Boolean(def.id));
    }

    function setWindowAccess(nextAccess) {
        accessState = {
            ...accessState,
            ...(nextAccess || {}),
        };

        windowDefs.forEach((def) => {
            if (!hasWindowAccess(def)) {
                def.el.classList.add('hidden');
            }
        });

        syncControls();
    }

    function initWindowLayouts() {
        windowLayouts = loadWindowLayouts();
        let shouldPersistSeededLayouts = false;

        windowDefs.forEach((def) => {
            const hasSavedLayout = hasOwn(windowLayouts, def.id);
            ensureWindowLayout(def, { hasSavedLayout });
            if (!hasSavedLayout) {
                shouldPersistSeededLayouts = true;
            }
        });

        if (shouldPersistSeededLayouts) {
            saveWindowLayouts();
        }

        window.addEventListener('resize', () => {
            if (isMobileViewport()) {
                return;
            }

            windowDefs.forEach((def) => {
                const normalized = normalizeLayout(windowLayouts[def.id], def.defaultLayout);
                const clamped = clampLayoutToViewport(normalized);
                applyLayout(def.el, clamped);
                windowLayouts[def.id] = clamped;
            });

            saveWindowLayouts();
        });
    }

    function initDraggableWindows() {
        let dragState = null;

        document.addEventListener('pointerdown', (event) => {
            const handle = event.target.closest('[data-role="drag-handle"]');
            if (!handle || event.button !== 0 || event.target.closest('button')) {
                return;
            }
            if (isMobileViewport()) {
                return;
            }

            const windowEl = handle.closest('.ui-tool-window[data-ui-window]');
            if (!windowEl || windowEl.classList.contains('hidden')) {
                return;
            }

            bringWindowToFront(windowEl);
            const rect = windowEl.getBoundingClientRect();
            windowEl.style.left = `${rect.left}px`;
            windowEl.style.top = `${rect.top}px`;
            windowEl.style.right = 'auto';
            windowEl.style.bottom = 'auto';
            windowEl.style.transform = 'none';

            dragState = {
                pointerId: event.pointerId,
                windowEl,
                offsetX: event.clientX - rect.left,
                offsetY: event.clientY - rect.top,
            };

            document.body.classList.add('is-dragging-window');
            handle.setPointerCapture(event.pointerId);
            event.preventDefault();
        });

        window.addEventListener('pointermove', (event) => {
            if (!dragState || dragState.pointerId !== event.pointerId) {
                return;
            }

            const windowEl = dragState.windowEl;
            const maxLeft = Math.max(0, window.innerWidth - windowEl.offsetWidth);
            const maxTop = Math.max(0, window.innerHeight - windowEl.offsetHeight);
            const nextLeft = clamp(event.clientX - dragState.offsetX, 0, maxLeft);
            const nextTop = clamp(event.clientY - dragState.offsetY, 0, maxTop);

            windowEl.style.left = `${nextLeft}px`;
            windowEl.style.top = `${nextTop}px`;
        });

        function finishDrag(event) {
            if (!dragState || dragState.pointerId !== event.pointerId) {
                return;
            }
            persistWindowLayout(dragState.windowEl);
            dragState = null;
            document.body.classList.remove('is-dragging-window');
        }

        window.addEventListener('pointerup', finishDrag);
        window.addEventListener('pointercancel', finishDrag);
    }

    function initResizableWindows() {
        if (typeof ResizeObserver !== 'function') {
            return;
        }

        const observer = new ResizeObserver((entries) => {
            entries.forEach((entry) => {
                const windowEl = entry.target;
                if (windowEl.classList.contains('hidden') || isMobileViewport()) {
                    return;
                }
                persistWindowLayout(windowEl);
            });
        });

        windowDefs.forEach((def) => observer.observe(def.el));
    }

    function initTaskbarAndWindowEvents() {
        document.addEventListener('click', (event) => {
            const openBtn = event.target.closest('[data-role="open-window"]');
            if (openBtn) {
                const target = openBtn.dataset.target;
                if (!target) {
                    return;
                }
                if (isWindowOpen(target)) {
                    closeWindowById(target);
                } else {
                    openWindowById(target);
                }
                return;
            }

            const closeBtn = event.target.closest('[data-role="close-window"]');
            if (!closeBtn) {
                return;
            }

            const target = closeBtn.dataset.target || closeBtn.closest('.ui-tool-window')?.id;
            if (target) {
                closeWindowById(target);
            }
        });

        windowDefs.forEach((def) => {
            def.el.addEventListener('pointerdown', () => {
                if (def.el.classList.contains('hidden')) {
                    return;
                }
                bringWindowToFront(def.el);
            });
        });

        window.addEventListener('keydown', (event) => {
            if (event.key !== 'Escape') {
                return;
            }
            windowDefs.forEach((def) => {
                def.el.classList.add('hidden');
            });
            syncTaskButtons();
        });
    }

    function initThemeAndModeHandlers() {
        document.querySelectorAll('[data-role="theme-option"]').forEach((button) => {
            button.addEventListener('click', () => {
                const value = button.dataset.theme || DEFAULT_THEME;
                localStorage.setItem(THEME_KEY, value);
                applyTheme(value);
                syncControls();
            });
        });

        document.querySelectorAll('[data-role="mode-toggle-action"]').forEach((button) => {
            button.addEventListener('click', () => {
                const next = getCurrentMode() === 'dark' ? 'light' : 'dark';
                localStorage.setItem(MODE_KEY, next);
                applyMode(next);
                syncControls();
            });
        });
    }

    function initUIControls() {
        if (window.__uiControlsInitialized) {
            syncControls();
            return;
        }
        window.__uiControlsInitialized = true;

        const savedTheme = localStorage.getItem(THEME_KEY) || DEFAULT_THEME;
        const savedMode = localStorage.getItem(MODE_KEY) || 'light';
        applyTheme(savedTheme);
        applyMode(savedMode);

        collectWindowDefinitions();
        initWindowLayouts();
        initTaskbarAndWindowEvents();
        initThemeAndModeHandlers();
        initDraggableWindows();
        initResizableWindows();
        syncControls();
    }

    window.initUIControls = initUIControls;
    window.isUIWindowOpen = isWindowOpen;
    window.openUIWindow = openWindowById;
    window.closeUIWindow = closeWindowById;
    window.setUIWindowAccess = setWindowAccess;

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initUIControls, { once: true });
    } else {
        initUIControls();
    }
})();
