'use strict';

function web_push_init(publicKey, registerUrl) {

    // var addToLog = console.log.bind(console);
    var addToLog = function () { };

    var fingerprintToken = null;
    var loaded = false;

    var worker = null;
    var storage = newStorage('webpush');

    waitLoad();
    waitFingerprint();

    function newStorage(id) {
        return {
            keyPrefix: id,
            _key: function (key) {
                return this.keyPrefix + '_' + key;
            },
            get: function (key) {
                key = this._key(key);
                try {
                    return JSON.parse(window.localStorage.getItem(key));
                } catch (e) {
                }
                return null;
            },
            set: function (key, value) {
                key = this._key(key);
                window.localStorage.setItem(key, JSON.stringify(value));
            },
        };
    }

    function urlB64ToUint8Array(base64String) {
        const padding = '='.repeat((4 - base64String.length % 4) % 4);
        const base64 = (base64String + padding)
            .replace(/\-/g, '+')
            .replace(/_/g, '/');

        const rawData = window.atob(base64);
        const outputArray = new Uint8Array(rawData.length);

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

    function waitLoad() {
        loaded = false;
        addToLog('waitLoaded');

        if (document.readyState === 'complete') {
            loaded = true;
            addToLog(`load status (immediate): ${loaded}`);
            checkInitReady();
        } else {
            window.addEventListener('load', function () {
                loaded = true;
                addToLog(`load status (event): ${loaded}`);
                checkInitReady();
            });
        }
    }

    function waitFingerprint() {
        addToLog('waitFingerprint');
        var count = 100;
        var timer = setInterval(function () {
            fingerprintToken = _env && _env.deviceHash || null;

            if (count-- <= 0 || fingerprintToken !== null) {
                clearInterval(timer);
                addToLog(`fingerprintToken: ${fingerprintToken}`);
                checkInitReady();
            }
        }, 100);
    }

    function checkInitReady() {
        addToLog(`checkInitReady: loaded=${loaded}, fingerprintToken=${fingerprintToken}`);
        if (loaded && fingerprintToken !== null) {
            init();
        }
    }


    function init() {

        if ('serviceWorker' in navigator && 'PushManager' in window) {
            addToLog('Service Worker and Push is supported');

            navigator.serviceWorker.register('/worker.js?2.8')
                .then(function (swReg) {
                    addToLog('Service Worker is registered', swReg);
                    worker = swReg;
                    init2();
                })
                .catch(function (error) {
                    addToLog('Service Worker Error', error);
                });
        } else {
            addToLog('Push messaging is not supported');
        }
    }

    function init2() {
        worker.pushManager.getSubscription()
            .then(function (subscription) {
                var isSubscribed = !(subscription === null);
                if (isSubscribed) {
                    addToLog('User is subscribed.');
                    sendSubscriptionToServer(subscription);
                } else {
                    addToLog('User is not subscribed yet.');
                    if (Notification.permission === 'granted') {
                        subscribe();
                    }
                    //user gesture listener
                    //iOS users have to make click on the page before requesting for subscribe
                    document.addEventListener('click', function handleClickOnce() {
                        document.removeEventListener('click', handleClickOnce);
                        trySubscribe();
                    });
                }
            });
    }

    function trySubscribe() {
        if (Notification.permission === 'granted') {
            addToLog('Permission already granted, subscribing...');
            subscribe();
        } else if (Notification.permission === 'default') {
            addToLog('Requesting permission from user gesture...');
            Notification.requestPermission().then(function (permission) {
                if (permission === 'granted') {
                    subscribe();
                } else {
                    addToLog('Permission not granted by user.');
                }
            });
        } else {
            addToLog('Push permission was denied earlier.');
        }
    }


    function subscribe() {
        var applicationServerKey = urlB64ToUint8Array(publicKey);
        addToLog('applicationServerKey: ', applicationServerKey);
        worker.pushManager.subscribe({
            userVisibleOnly: true,
            applicationServerKey: applicationServerKey,
        }).then(function (subscription) {
            sendSubscriptionToServer(subscription);
        }).catch(function (err) {
            addToLog('Failed to subscribe the user: ', err);
        });
    }

    function sendSubscriptionToServer(subscription) {
        addToLog('data: ', JSON.stringify(subscription));

        var user_id = _env.playerUUID;
        if (user_id !== null) {
            user_id = user_id.replace('PLAYER-', '');
        }

        var dataToStore = {
            user_id: user_id,
            fToken: _env.deviceHash,
            data: JSON.stringify(subscription),
        };

        var dataInStorage = storage.get('subscription');

        if (
            dataInStorage && typeof dataInStorage === 'object'
            && (dataInStorage.user_id === dataToStore.user_id || dataToStore.user_id === null)
            && (dataInStorage.fToken === dataToStore.fToken)
            && (dataInStorage.data === dataToStore.data)
        ) {
            addToLog('Dont send subscription');
            return;
        }

        subscription = JSON.parse(JSON.stringify(subscription));

        $.ajax({
            url: registerUrl,
            method: 'post',
            data: {
                user_id: user_id,
                brand: _env.brandId,
                token: null,
                domain: null,
                key: subscription.keys.auth,
                data: subscription,
                tz: -((new Date()).getTimezoneOffset() / 60),
                fToken: _env.deviceHash,
                lang: _env.language,
            },
            success: function () {
                storage.set('subscription', dataToStore);
                addToLog('send success');
            },
            complete: function () {
                addToLog('send complete');
            },
        });
    }

    window.web_push_init = null;
}
