(function (window, $) {
    'use strict';

    var nsVars = window.noesia_admin_vars || {};
    var i18n = nsVars.i18n || {};
    var localizedOptions = nsVars.options || {};
    var modules = window.noesiaSwaAdminModules || (window.noesiaSwaAdminModules = {});
    var noesiaSwaScreenSaverTimer = null;
    var noesiaSwaScreenTick = null;
    var noesiaSwaOverlayVisible = false;
    var noesiaSwaOverlayMode = '';
    var suppressInteractionUntil = 0;
    var lastUserActivityAt = Date.now();
    var noesiaSwaIdleWatchdog = null;
    var nativeActivityBound = false;
    var lastActivitySignalAt = 0;
    var ACTIVITY_THROTTLE_MS = 250;
    var state = {
        booted: false,
        overlayReady: false
    };

    function text(key, fallback) {
        return String(i18n[key] || fallback);
    }

    function getOptionValue(name, fallback) {
        if (Object.prototype.hasOwnProperty.call(localizedOptions, name)) {
            return localizedOptions[name];
        }

        return fallback;
    }

    function normalizeYesNo(value, fallback) {
        value = String(typeof value === 'undefined' ? fallback : value).toLowerCase();

        return $.inArray(value, ['yes', '1', 'true', 'on']) !== -1 ? 'yes' : 'no';
    }

    function getFieldValue(selector, optionName, fallback) {
        var $field = $(selector).first();

        if ($field.length) {
            return $field.val();
        }

        return getOptionValue(optionName, fallback);
    }

    function getScreenSaverSettings() {
        var enabled = normalizeYesNo(getFieldValue('select[name="noesia_swa_options[screensaver_enabled]"]', 'screensaver_enabled', 'no'), 'no');
        var idleValue = parseInt(getFieldValue('input[name="noesia_swa_options[screensaver_idle_minutes]"]', 'screensaver_idle_minutes', 5), 10);
        var showClock = normalizeYesNo(getFieldValue('select[name="noesia_swa_options[screensaver_show_clock]"]', 'screensaver_show_clock', 'yes'), 'yes');
        var showUpdates = normalizeYesNo(getFieldValue('select[name="noesia_swa_options[screensaver_show_updates]"]', 'screensaver_show_updates', 'yes'), 'yes');
        var showCenterBox = normalizeYesNo(getFieldValue('select[name="noesia_swa_options[screensaver_show_center_box]"]', 'screensaver_show_center_box', 'yes'), 'yes');

        if (isNaN(idleValue) || idleValue < 1) {
            idleValue = 5;
        } else if (idleValue > 120) {
            idleValue = 120;
        }

        return {
            enabled: enabled === 'yes',
            idleMinutes: idleValue,
            idleMs: idleValue * 60 * 1000,
            showClock: showClock !== 'no',
            showUpdates: showUpdates !== 'no',
            showCenterBox: showCenterBox !== 'no'
        };
    }

    function getScreenOverlayActiveCount() {
        var $wrapper = $('#noesia-swa-wrapper');
        var raw = parseInt($wrapper.attr('data-noesia-swa-active-count') || '0', 10);

        if (isNaN(raw) || raw < 0) {
            raw = 0;
        }

        return raw;
    }

    function getScreenOverlayTimeLabel() {
        var now = new Date();

        return now.toLocaleTimeString([], {
            hour: '2-digit',
            minute: '2-digit'
        });
    }

    function getOverlayDetail(extra) {
        var $overlay = $('#noesia-swa-screen-overlay');
        var detail = $.extend({
            mode: noesiaSwaOverlayMode,
            overlay: $overlay.length ? $overlay.get(0) : null,
            visible: noesiaSwaOverlayVisible,
            settings: getScreenSaverSettings()
        }, extra || {});

        return detail;
    }

    function triggerOverlayEvent(name, detail) {
        $(document).trigger(name, [detail || getOverlayDetail()]);
    }

    function ensureScreenOverlay() {
        var $overlay = $('#noesia-swa-screen-overlay');

        if (!$overlay.length) {
            $overlay = $(
                '<div id="noesia-swa-screen-overlay" class="noesia-swa-screen-overlay" hidden>' +
                    '<div class="noesia-swa-screen-overlay__backdrop"></div>' +
                    '<div class="noesia-swa-screen-overlay__dialog" role="dialog" aria-modal="true" aria-label="' + text('overlay_dialog_label', 'Screen Overlay') + '">' +
                        '<div class="noesia-swa-screen-overlay__title"></div>' +
                        '<div class="noesia-swa-screen-overlay__clock"></div>' +
                        '<div class="noesia-swa-screen-overlay__updates"></div>' +
                        '<div class="noesia-swa-screen-overlay__message"></div>' +
                    '</div>' +
                '</div>'
            );

            $('body').append($overlay);

            $overlay.on('click', function (event) {
                if (
                    $(event.target).is('#noesia-swa-screen-overlay') ||
                    $(event.target).hasClass('noesia-swa-screen-overlay__backdrop')
                ) {
                    hideScreenOverlay();
                    resetScreenSaverTimer(Date.now());
                }
            });
        }

        if (!state.overlayReady) {
            state.overlayReady = true;
            triggerOverlayEvent('noesiaSwaScreenOverlayReady', {
                overlay: $overlay.get(0),
                api: modules.screenLock || modules['screen-lock'] || null
            });
        }

        return $overlay;
    }

    function updateScreenOverlayContent(mode) {
        var settings = getScreenSaverSettings();
        var $overlay = ensureScreenOverlay();
        var $dialog = $overlay.find('.noesia-swa-screen-overlay__dialog');
        var $title = $overlay.find('.noesia-swa-screen-overlay__title');
        var $clock = $overlay.find('.noesia-swa-screen-overlay__clock');
        var $updates = $overlay.find('.noesia-swa-screen-overlay__updates');
        var $message = $overlay.find('.noesia-swa-screen-overlay__message');
        var count;
        var updatesText;

        $overlay.attr('data-noesia-swa-dialog-visibility', settings.showCenterBox ? 'shown' : 'hidden');
        $dialog.attr('aria-hidden', settings.showCenterBox ? 'false' : 'true');

        if (mode === 'lock') {
            $title.text(text('overlay_lock_title', 'Screen is locked (blurred).')).removeAttr('hidden');
            $message.text(text('overlay_lock_message', 'Click outside this box or press ESC to unlock.')).removeAttr('hidden');
            $clock.text('').attr('hidden', true);
            $updates.text('').attr('hidden', true);
            return;
        }

        $title.text(text('overlay_saver_title', 'Screen Saver')).removeAttr('hidden');
        $message.text(text('overlay_saver_message', 'Move the pointer, tap, click, or press ESC to return.')).removeAttr('hidden');

        if (settings.showClock) {
            $clock.text(getScreenOverlayTimeLabel()).removeAttr('hidden');
        } else {
            $clock.text('').attr('hidden', true);
        }

        if (settings.showUpdates) {
            count = getScreenOverlayActiveCount();
            updatesText = count === 1
                ? text('screen_saver_one_update', '1 active update')
                : text('screen_saver_many_updates', '%d active updates').replace('%d', String(count));

            $updates.text(updatesText).removeAttr('hidden');
        } else {
            $updates.text('').attr('hidden', true);
        }
    }

    function setInteractionSuppression(milliseconds) {
        suppressInteractionUntil = Date.now() + Math.max(0, parseInt(milliseconds || 0, 10));
    }

    function showScreenOverlay(mode, args) {
        var settings = getScreenSaverSettings();
        var options = $.extend({ force: false, source: '' }, args || {});
        var $overlay = ensureScreenOverlay();

        if (mode === 'screensaver' && !options.force && !settings.enabled) {
            return false;
        }

        noesiaSwaOverlayVisible = true;
        noesiaSwaOverlayMode = mode;
        $overlay.attr('data-noesia-swa-mode', mode).removeAttr('hidden');
        $('body').addClass('noesia-swa-screen-overlay-active');

        updateScreenOverlayContent(mode);

        if (noesiaSwaScreenTick) {
            window.clearInterval(noesiaSwaScreenTick);
            noesiaSwaScreenTick = null;
        }

        if (mode === 'screensaver') {
            noesiaSwaScreenTick = window.setInterval(function () {
                updateScreenOverlayContent('screensaver');
                triggerOverlayEvent('noesiaSwaScreenOverlayTick', getOverlayDetail({ source: options.source || 'timer-tick' }));
            }, 1000);
        }

        triggerOverlayEvent('noesiaSwaScreenOverlayShow', getOverlayDetail({ source: options.source || '' }));

        return true;
    }

    function hideScreenOverlay() {
        var $overlay = $('#noesia-swa-screen-overlay');
        var detail = getOverlayDetail();

        noesiaSwaOverlayVisible = false;
        noesiaSwaOverlayMode = '';

        if ($overlay.length) {
            $overlay.attr('hidden', true).removeAttr('data-noesia-swa-mode');
        }

        $('body').removeClass('noesia-swa-screen-overlay-active');

        if (noesiaSwaScreenTick) {
            window.clearInterval(noesiaSwaScreenTick);
            noesiaSwaScreenTick = null;
        }

        triggerOverlayEvent('noesiaSwaScreenOverlayHide', detail);
    }

    function showScreenLock() {
        setInteractionSuppression(250);
        return showScreenOverlay('lock', {
            force: true,
            source: 'manual-lock'
        });
    }

    function showScreenSaver(force) {
        setInteractionSuppression(350);
        return showScreenOverlay('screensaver', {
            force: !!force,
            source: force ? 'preview' : 'manual-screensaver'
        });
    }

    function armScreenSaverTimer(delayMs, source) {
        var waitMs = Math.max(250, parseInt(delayMs || 0, 10) || 0);

        if (noesiaSwaScreenSaverTimer) {
            window.clearTimeout(noesiaSwaScreenSaverTimer);
            noesiaSwaScreenSaverTimer = null;
        }

        noesiaSwaScreenSaverTimer = window.setTimeout(function () {
            var settings = getScreenSaverSettings();
            var elapsed = Date.now() - lastUserActivityAt;
            var remaining;

            if (!settings.enabled) {
                if (noesiaSwaOverlayMode === 'screensaver') {
                    hideScreenOverlay();
                }
                return;
            }

            if (elapsed + 120 < settings.idleMs) {
                remaining = settings.idleMs - elapsed;
                armScreenSaverTimer(remaining, 'idle-resync');
                return;
            }

            showScreenOverlay('screensaver', {
                force: false,
                source: source || 'idle-timeout'
            });
        }, waitMs);
    }

    function resetScreenSaverTimer(activityAt) {
        var settings = getScreenSaverSettings();
        var nextActivityAt = parseInt(activityAt, 10);

        if (noesiaSwaScreenSaverTimer) {
            window.clearTimeout(noesiaSwaScreenSaverTimer);
            noesiaSwaScreenSaverTimer = null;
        }

        if (isNaN(nextActivityAt) || nextActivityAt < 1) {
            nextActivityAt = Date.now();
        }

        lastUserActivityAt = nextActivityAt;

        if (!settings.enabled) {
            if (noesiaSwaOverlayMode === 'screensaver') {
                hideScreenOverlay();
            }
            return;
        }

        armScreenSaverTimer(settings.idleMs, 'idle-timeout');
    }

    function noteUserActivity(force) {
        var now = Date.now();

        if (now < suppressInteractionUntil) {
            return;
        }

        if (!force && (now - lastActivitySignalAt) < ACTIVITY_THROTTLE_MS) {
            return;
        }

        lastActivitySignalAt = now;

        if (noesiaSwaOverlayVisible && noesiaSwaOverlayMode === 'screensaver') {
            hideScreenOverlay();
        }

        resetScreenSaverTimer(now);
    }

    function handleUserActivity() {
        noteUserActivity(false);
    }

    function handleVisibilityChange() {
        if (document.hidden) {
            return;
        }

        if (noesiaSwaOverlayVisible && noesiaSwaOverlayMode === 'screensaver') {
            hideScreenOverlay();
        }

        resetScreenSaverTimer(Date.now());
    }

    function bindNativeActivityListeners() {
        var events;

        if (nativeActivityBound) {
            return;
        }

        events = [
            'mousemove',
            'mousedown',
            'click',
            'touchstart',
            'touchmove',
            'scroll',
            'wheel',
            'pointermove',
            'pointerdown',
            'focusin',
            'keydown'
        ];

        $.each(events, function (index, eventName) {
            window.addEventListener(eventName, handleUserActivity, true);
            document.addEventListener(eventName, handleUserActivity, true);
        });

        nativeActivityBound = true;
    }

    function ensureIdleWatchdog() {
        if (noesiaSwaIdleWatchdog) {
            return;
        }

        noesiaSwaIdleWatchdog = window.setInterval(function () {
            var settings = getScreenSaverSettings();
            var idleElapsed;

            if (!settings.enabled) {
                if (noesiaSwaOverlayMode === 'screensaver') {
                    hideScreenOverlay();
                }
                return;
            }

            if (noesiaSwaOverlayVisible) {
                return;
            }

            idleElapsed = Date.now() - lastUserActivityAt;

            if (idleElapsed >= settings.idleMs) {
                showScreenOverlay('screensaver', {
                    force: false,
                    source: 'idle-watchdog'
                });
            }
        }, 1000);
    }

    function bindManualTriggers() {
        $(document)
            .off('click.noesiaSwaManualScreenLock', '[data-noesia-swa-screen-lock-trigger]')
            .on('click.noesiaSwaManualScreenLock', '[data-noesia-swa-screen-lock-trigger]', function (event) {
                event.preventDefault();
                event.stopPropagation();
                showScreenLock();
            })
            .off('noesiaSwaScreenLockRequest.noesiaSwaScreenLock')
            .on('noesiaSwaScreenLockRequest.noesiaSwaScreenLock', function () {
                showScreenLock();
            })
            .off('noesiaSwaScreenSaverRequest.noesiaSwaScreenLock')
            .on('noesiaSwaScreenSaverRequest.noesiaSwaScreenLock', function (event, detail) {
                detail = detail || {};
                showScreenOverlay('screensaver', {
                    force: !!detail.force,
                    source: String(detail.source || 'external-request')
                });
            });
    }

    function init() {
        if (state.booted) {
            return;
        }

        ensureScreenOverlay();
        resetScreenSaverTimer(Date.now());
        bindManualTriggers();
        bindNativeActivityListeners();
        ensureIdleWatchdog();

        $(document)
            .off('.noesiaSwaScreenState')
            .on('keydown.noesiaSwaScreenState', function (event) {
                if (event.key === 'Escape' && noesiaSwaOverlayVisible) {
                    hideScreenOverlay();
                    resetScreenSaverTimer(Date.now());
                    return;
                }

                noteUserActivity(true);
            })
            .on('mousemove.noesiaSwaScreenState mousedown.noesiaSwaScreenState click.noesiaSwaScreenState touchstart.noesiaSwaScreenState touchmove.noesiaSwaScreenState scroll.noesiaSwaScreenState wheel.noesiaSwaScreenState pointermove.noesiaSwaScreenState pointerdown.noesiaSwaScreenState focusin.noesiaSwaScreenState', function () {
                noteUserActivity(true);
            });

        $(window)
            .off('.noesiaSwaScreenStateWindow')
            .on('focus.noesiaSwaScreenStateWindow pageshow.noesiaSwaScreenStateWindow', function () {
                handleVisibilityChange();
            });

        $(document)
            .off('visibilitychange.noesiaSwaScreenStateWindow')
            .on('visibilitychange.noesiaSwaScreenStateWindow', function () {
                handleVisibilityChange();
            });

        $(document).on(
            'change.noesiaSwaScreenState input.noesiaSwaScreenState',
            'select[name="noesia_swa_options[screensaver_enabled]"], input[name="noesia_swa_options[screensaver_idle_minutes]"], select[name="noesia_swa_options[screensaver_show_clock]"], select[name="noesia_swa_options[screensaver_show_updates]"], select[name="noesia_swa_options[screensaver_show_center_box]"]',
            function () {
                if (noesiaSwaOverlayMode === 'screensaver') {
                    hideScreenOverlay();
                }

                resetScreenSaverTimer(Date.now());
            }
        );

        window.setInterval(function () {
            if (noesiaSwaOverlayVisible && noesiaSwaOverlayMode === 'screensaver') {
                updateScreenOverlayContent('screensaver');
            }
        }, 30000);

        state.booted = true;
    }

    var api = $.extend({}, modules.screenLock || modules['screen-lock'] || {}, {
        init: init,
        triggerLock: showScreenLock,
        triggerScreenSaver: function (force) {
            return showScreenSaver(force !== false);
        },
        isOverlayVisible: function () {
            return noesiaSwaOverlayVisible;
        },
        getOverlayMode: function () {
            return noesiaSwaOverlayMode;
        },
        onSectionOpen: function () {
            return true;
        }
    });

    modules.screenLock = api;
    modules['screen-lock'] = api;

    $(init);
}(window, jQuery));
