(function () {
    'use strict';

    var settings = window.PlusCashPushConfig || {};
    var promptDelay = Number(settings.promptDelay || 1400);
    var dismissStorageKey = 'pluscash_push_prompt_dismissed_until';
    var registration = null;
    var serverConfig = null;

    function isSupported() {
        return window.isSecureContext &&
            'serviceWorker' in navigator &&
            'PushManager' in window &&
            'Notification' in window;
    }

    function requestJson(url, options) {
        var requestOptions = options || {};
        requestOptions.credentials = 'same-origin';
        requestOptions.headers = Object.assign({
            'Accept': 'application/json'
        }, requestOptions.headers || {});

        return fetch(url, requestOptions).then(function (response) {
            return response.json().catch(function () {
                return { success: false, message: 'Invalid server response.' };
            }).then(function (payload) {
                if (!response.ok || payload.success === false) {
                    throw new Error(payload.message || 'Request failed.');
                }
                return payload;
            });
        });
    }

    function urlBase64ToUint8Array(base64String) {
        var padding = '='.repeat((4 - base64String.length % 4) % 4);
        var base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/');
        var rawData = window.atob(base64);
        var outputArray = new Uint8Array(rawData.length);

        for (var i = 0; i < rawData.length; ++i) {
            outputArray[i] = rawData.charCodeAt(i);
        }
        return outputArray;
    }

    function subscriptionPayload(subscription) {
        var json = subscription.toJSON();
        json.contentEncoding = (window.PushManager && PushManager.supportedContentEncodings && PushManager.supportedContentEncodings[0])
            ? PushManager.supportedContentEncodings[0]
            : 'aes128gcm';
        return json;
    }

    function saveSubscription(subscription) {
        return requestJson(settings.subscribeUrl, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ subscription: subscriptionPayload(subscription) })
        }).then(function (response) {
            if (settings.userId) {
                sessionStorage.setItem('pluscash_push_synced_user', String(settings.userId));
            }
            return response;
        });
    }

    function ensureSubscription() {
        return registration.pushManager.getSubscription().then(function (subscription) {
            if (subscription) {
                return saveSubscription(subscription).then(function () { return subscription; });
            }

            if (Notification.permission !== 'granted') {
                return null;
            }

            return registration.pushManager.subscribe({
                userVisibleOnly: true,
                applicationServerKey: urlBase64ToUint8Array(serverConfig.publicKey)
            }).then(function (newSubscription) {
                return saveSubscription(newSubscription).then(function () { return newSubscription; });
            });
        });
    }

    function shouldShowPrompt() {
        if (Notification.permission !== 'default') {
            return false;
        }

        var dismissedUntil = Number(localStorage.getItem(dismissStorageKey) || 0);
        return Date.now() >= dismissedUntil;
    }

    function removePrompt() {
        var prompt = document.getElementById('pluscash-push-prompt');
        if (prompt && prompt.parentNode) {
            prompt.parentNode.removeChild(prompt);
        }
    }

    function showPrompt() {
        if (!shouldShowPrompt() || document.getElementById('pluscash-push-prompt')) {
            return;
        }

        var wrapper = document.createElement('div');
        wrapper.id = 'pluscash-push-prompt';
        wrapper.setAttribute('role', 'dialog');
        wrapper.setAttribute('aria-live', 'polite');
        wrapper.setAttribute('aria-label', 'Enable browser notifications');
        wrapper.innerHTML = '' +
            '<div class="pc-push-card">' +
                '<div class="pc-push-icon" aria-hidden="true">&#128276;</div>' +
                '<div class="pc-push-copy">' +
                    '<strong>Turn on notifications</strong>' +
                    '<span>Get an instant alert when offer points are credited or a withdrawal is paid.</span>' +
                '</div>' +
                '<div class="pc-push-actions">' +
                    '<button type="button" class="pc-push-later">Not now</button>' +
                    '<button type="button" class="pc-push-enable">Enable</button>' +
                '</div>' +
            '</div>';

        var style = document.createElement('style');
        style.id = 'pluscash-push-prompt-style';
        style.textContent = '' +
            '#pluscash-push-prompt{position:fixed;left:16px;right:16px;bottom:92px;z-index:2147482500;display:flex;justify-content:center;font-family:Inter,Arial,sans-serif}' +
            '.pc-push-card{width:min(100%,520px);display:grid;grid-template-columns:46px 1fr;gap:12px;padding:15px;background:#131A2E;color:#F3F5FC;border:1px solid rgba(255,255,255,.12);border-radius:18px;box-shadow:0 24px 60px rgba(0,0,0,.45)}' +
            '.pc-push-icon{width:44px;height:44px;display:flex;align-items:center;justify-content:center;border-radius:14px;background:linear-gradient(135deg,#7C3AED,#F53D8B);font-size:21px}' +
            '.pc-push-copy{display:flex;flex-direction:column;gap:4px;line-height:1.35}.pc-push-copy strong{font-size:14px}.pc-push-copy span{font-size:12px;color:#AAB1C8}' +
            '.pc-push-actions{grid-column:1/-1;display:flex;justify-content:flex-end;gap:8px}.pc-push-actions button{border:0;border-radius:10px;padding:8px 14px;font-weight:700;font-size:12px;cursor:pointer}' +
            '.pc-push-later{background:#232E52;color:#D7DCF0}.pc-push-enable{background:linear-gradient(135deg,#7C3AED,#F53D8B);color:#fff}' +
            '@media(min-width:700px){#pluscash-push-prompt{left:auto;right:22px;bottom:22px;justify-content:flex-end}.pc-push-card{width:430px}}';

        document.head.appendChild(style);
        document.body.appendChild(wrapper);

        wrapper.querySelector('.pc-push-later').addEventListener('click', function () {
            localStorage.setItem(dismissStorageKey, String(Date.now() + 7 * 24 * 60 * 60 * 1000));
            removePrompt();
        });

        wrapper.querySelector('.pc-push-enable').addEventListener('click', function (event) {
            var button = event.currentTarget;
            button.disabled = true;
            button.textContent = 'Enabling...';

            Notification.requestPermission().then(function (permission) {
                if (permission !== 'granted') {
                    removePrompt();
                    return null;
                }
                return ensureSubscription().then(function () {
                    removePrompt();
                });
            }).catch(function (error) {
                console.warn('PlusCash push permission failed:', error);
                button.disabled = false;
                button.textContent = 'Enable';
            });
        });
    }

    function initialize() {
        if (!isSupported() || !settings.workerUrl || !settings.configUrl || !settings.subscribeUrl) {
            return;
        }

        Promise.all([
            navigator.serviceWorker.register(settings.workerUrl, { scope: settings.workerScope || '/push-notifications/' }),
            requestJson(settings.configUrl)
        ]).then(function (values) {
            registration = values[0];
            serverConfig = values[1];

            if (!serverConfig.enabled || !serverConfig.publicKey) {
                return null;
            }

            return registration.pushManager.getSubscription().then(function (subscription) {
                var syncedUser = sessionStorage.getItem('pluscash_push_synced_user');
                if (subscription && syncedUser !== String(settings.userId || '')) {
                    return saveSubscription(subscription);
                }
                if (!subscription && Notification.permission === 'granted') {
                    return ensureSubscription();
                }
                return null;
            }).then(function () {
                window.setTimeout(showPrompt, promptDelay);
            });
        }).catch(function (error) {
            console.warn('PlusCash browser notifications are unavailable:', error);
        });
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initialize);
    } else {
        initialize();
    }
}());
