'use strict';

const ssoDomain = 'https://sso.onetz.de/';
const connectorDomain = '//piano-connector.onetz.de';
const debug = 1 === parseInt('1');
const clientId = 'piano_connector';
const redirectUri = 'https://piano-connector.onetz.de/';
const reqClientId = '';

let SSO_Log = {
    doLog: function () {
        if (!debug) {
            return;
        }

        try {
            let p = [];
            for (let i = 0; i < arguments.length; i++) {
                p.push('arguments[' + i + ']');
            }
            eval('console.log(' + p.join(',') + ');');
        } catch (e) {
        }
    }
};

let SSO_Ajax = {
    doGET: function (uri, params, cbOk, cbErr) {
        SSO_Ajax.doAjax('GET', uri, params, cbOk, cbErr)
    },

    doPOST: function (uri, params, cbOk, cbErr) {
        SSO_Ajax.doAjax('POST', uri, params, cbOk, cbErr)
    },

    doAjax: function (method, uri, params, cbOk, cbErr) {
        params = params || {};

        // provide clientId if avail. and not already set
        if (typeof params.client_id === 'undefined' && reqClientId && reqClientId.length) {
            params.client_id = reqClientId;
        }

        let loadCb = function () {
            // SSO_Log.doLog('loaded', this.responseText);
            if (typeof cbOk === 'function') {
                cbOk(this.responseText ? JSON.parse(this.responseText) : '', this);
            }
        };

        let errorCb = function (e) {
            if (typeof cbErr === 'function') {
                cbErr();
            }
            SSO_Log.doLog('AJAX error', e);
        };

        let cancelCb = function (e) {
            SSO_Log.doLog('AJAX cancel', e);
        };

        let formData = new FormData(), name;

        for (name in params) {
            if (params.hasOwnProperty(name)) {
                formData.append(name, params[name]);
            }
        }

        SSO_Log.doLog('doAjax-' + method + ': ' + uri);
        const xhr = new XMLHttpRequest();
        xhr.addEventListener("load", loadCb);
        xhr.addEventListener("error", errorCb);
        xhr.addEventListener("abort", cancelCb);
        xhr.open(method, uri, true);
        // pass cookies along
        xhr.withCredentials = true;
        xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");

        xhr.send(formData);
    }
};

(function () {
    let tp_propagate_retry = 10;

    function retrieveUuid() {
        let cb = function (axRslt) {
            let uuidParam = {};
            if (typeof axRslt['uuid'] === 'string') {
                uuidParam.uuid = axRslt['uuid'];
                SSO_Log.doLog('uuid is ', axRslt['uuid']);
                triggerPiano(axRslt['uuid']);
            } else {
                SSO_Log.doLog('no uuid found', (axRslt.code === 2100 ? '(' + axRslt.message + ')' : ''), axRslt);
                initExperience();
            }
            SSO_Ajax.doPOST(connectorDomain + '/api/uuid', uuidParam);
        };

        SSO_Ajax.doGET(ssoDomain + '/auth/logonstatus', null, cb);
    }

    function loadActiveCampaigns(uuid) {
        let cbOk = function (axRslt) {
            if(typeof axRslt['status'] === 'string' && axRslt['status'] === 'success'){
                SSO_Log.doLog('active campaigns loaded:', axRslt['data']);
                if(typeof axRslt.data === 'object'){
                    let tp = window.tp || [];
                    for (let cpgIdx = 0; cpgIdx < axRslt.data.length; cpgIdx++) {
                        let cpgKey = axRslt.data[cpgIdx];
                        SSO_Log.doLog('tp.push([\'setCustomVariable\', \'NL_subscriptions_' + cpgKey + ', \'1\'])');
                        tp.push(['setCustomVariable', 'NL_subscriptions_' + cpgKey, '1']);
                    }
                }
            } else {
                SSO_Log.doLog('something went wrong when loading active campaigns', axRslt);
            }
            initExperience();
        };
        let cbErr = function(){
            initExperience();
        };

        SSO_Ajax.doGET(connectorDomain + '/api/loadActiveCampaigns/' + uuid, null, cbOk, cbErr);
    }

    function syncEpaperRights(uuid) {
        let cb = function (axRslt) {
            if(typeof axRslt['status'] === 'string' && axRslt['status'] === 'success'){
                SSO_Log.doLog('epaper access synchronized:', axRslt['message']);
            } else {
                SSO_Log.doLog('something went wrong when synchronizing epaper access', axRslt);
            }
        };

        SSO_Ajax.doPOST(connectorDomain + '/api/syncEpaperAccessPerSession/' + uuid, null, cb);
    }

    function syncInAppPurchases(uuid) {
        let cbOk = function (axRslt) {
            SSO_Log.doLog('In-App-Purchases synchronization result:', axRslt);
            syncEpaperRights(uuid);
        };
        let cbErr = function () {
            SSO_Log.doLog('In-App-Purchases synchronize failed');
            syncEpaperRights(uuid);
        };

        SSO_Ajax.doPOST(ssoDomain + '/user/synchronize-store-data', {'user_id': uuid, 'client_id': clientId}, cbOk, cbErr);
    }

    function triggerPiano(uuid) {
        let cb = function (axRslt) {
            if (typeof axRslt['user_ref'] === 'string') {
                SSO_Log.doLog('userRef is ', axRslt['user_ref']);
                propagateUserRefId(axRslt['user_ref']);
                syncInAppPurchases(uuid);
                loadActiveCampaigns(uuid);
            } else {
                SSO_Log.doLog('no userRefId', axRslt);
                initExperience();
            }
        };

        SSO_Ajax.doGET(connectorDomain + '/api/getUserRefID/' + uuid, null, cb);
    }

    function propagateUserRefId(userRefId) {
        if (typeof window.tp !== 'object') {
            SSO_Log.doLog(tp_propagate_retry, 'tinypass is not accessible');
            if (tp_propagate_retry--) {
                setTimeout(function () {
                    propagateUserRefId(userRefId)
                }, 1e3);
            }
        } else {
            let tp = window.tp || [];
            tp.push(["setUserRef", userRefId]);
            window.dispatchEvent(new CustomEvent('tpUserRefSynched'));
            SSO_Log.doLog('userRefId synched');
            // initExperience();
        }
    }

    function initExperience() {
        let tp = window.tp || [];
        tp.push(["init", function () {
            tp.experience.init();
        }]);
        SSO_Log.doLog('experience has been initialized');
    }

    function ssoAuthStateChangedHandler(evt) {
        SSO_Log.doLog('ssoAuthStateChanged event caught:', evt);
        retrieveUuid();
    }

    function init() {
        SSO_Log.doLog('init');
        window.addEventListener('ssoAuthStateChanged', ssoAuthStateChangedHandler);
        retrieveUuid();
    }

    init();
})();

/**
 *  synchronization can be triggered by firing CustomEvent "ssoAuthStateChanged" like this:
 *
 *  window.dispatchEvent(new CustomEvent('ssoAuthStateChanged'));
 **/

let SSO = {
    clientId: clientId,
    returnUri: redirectUri,

    setClientId: function(customClientId){
        SSO.clientId = customClientId || '';
    },

    setReturnUri: function(customReturnUri){
        SSO.returnUri = customReturnUri || '';
    },

    jumpToLogout: function () {
        SSO_Ajax.doPOST(ssoDomain + '/auth/logout', {
            client_id: SSO.clientId
        }, function(rslt){
            window.dispatchEvent(new CustomEvent('ssoLogoutAttempt', {detail: rslt}));
            SSO_Ajax.doPOST(connectorDomain + '/api/uuid');
        });
    },

    loginByCredentials: function (u, p) {
        u = u || '';
        p = p || '';

        let rslt = {loggedIn: false, code: 0, msg: 'unknown error'};
        if( !u.length || !p.length ){
            rslt.msg = 'username or password missing';
            window.dispatchEvent(new CustomEvent('ssoLoginAttempt', {detail: rslt}));
        } else {
            let cb = function (axRslt, xhr) {
                if (xhr.status === 200) {
                    try {
                        if (typeof axRslt.message === 'string') {
                            rslt.msg = axRslt.message;
                        }
                        if (typeof axRslt.code === 'string') {
                            rslt.code = axRslt.code;
                        }
                        if (typeof axRslt.status === 'string' && axRslt.status === 'success') {
                            rslt.loggedIn = true;
                            rslt.msg = 'successfully logged in';
                        }
                    } catch (e) {
                    }
                } else {
                    rslt.msg = 'error: http status was ' + xhr.status;
                }

                window.dispatchEvent(new CustomEvent('ssoLoginAttempt', {detail: rslt}));
            };

            SSO_Ajax.doPOST(ssoDomain + '/auth/authorize', {
                username: u,
                password: p,
                noRedirectOnResponse: '1',
                client_id: SSO.clientId,
                redirect_uri: SSO.returnUri
            }, cb);
        }
    }
};

window.addEventListener('ssoLoginAttempt', (p) => {
    SSO_Ajax.doGET(ssoDomain + '/auth/logonstatus', null, function (axRslt){
        if (axRslt.hasOwnProperty('uuid')){
            SSO_Ajax.doPOST(connectorDomain + '/api/uuid', {uuid: axRslt.uuid});
        }
    });
});
