'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 = '';

var jwt;

window.addEventListener('jwtAvailable', (p) => {console.log('jwtAvailable', p);});

(function () {
	let tp_propagate_retry = 10;

	function doGET(uri, params, cbOk, cbErr) {
		doAjax('GET', uri, params, cbOk, cbErr)
	}

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

    function doAjax(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 () {
            // doLog('loaded', this.responseText);
            cbOk(JSON.parse(this.responseText));
        };

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

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

        let urlEncodedDataPairs = [], name;
        for( name in params ) {
            if(params.hasOwnProperty(name)){
                urlEncodedDataPairs.push(encodeURIComponent(name)+'='+encodeURIComponent(params[name]));
            }
        }

        if (urlEncodedDataPairs.length && method.toUpperCase() === 'GET'){
            uri += (uri.indexOf('?') === -1 ? '?' : '&') + urlEncodedDataPairs.join('&');
        }

        // uri += '?_=' + (new Date()).getTime();

		doLog('doAjax-' + method + ': ' + uri);
		const xhr = new XMLHttpRequest();
		// pass cookies along
		xhr.withCredentials = true;
		xhr.addEventListener("load", loadCb);
		xhr.addEventListener("error", errorCb);
		xhr.addEventListener("abort", cancelCb);
        xhr.open(method, uri, true);
		xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
        if (method.toUpperCase() === 'POST') {
            xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        }
		// xhr.setRequestHeader("XDEBUG_SESSION", "XDEBUG_ECLIPSE");

        xhr.send(urlEncodedDataPairs.join('&'));
    }

	function doLog() {
		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) {
		}
	}

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

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

	function loadActiveCampaigns(uuid) {
		let cbOk = function (axRslt) {
			if(typeof axRslt['status'] === 'string' && axRslt['status'] === 'success'){
				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];
                        doLog('tp.push([\'setCustomVariable\', \'NL_subscriptions_' + cpgKey + ', \'1\'])');
                        tp.push(['setCustomVariable', 'NL_subscriptions_' + cpgKey, '1']);
                    }
                }
			} else {
				doLog('something went wrong when loading active campaigns', axRslt);
			}
			initExperience();
		};
		let cbErr = function(){
		    initExperience();
        };

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

	function syncEpaperRights(uuid) {
		let cb = function (axRslt) {
			if(typeof axRslt['status'] === 'string' && axRslt['status'] === 'success'){
				doLog('epaper access synchronized:', axRslt['message']);
				if (typeof axRslt['jwt'] === 'string' && axRslt['jwt'].length){
				    jwt = axRslt['jwt'];
                    window.dispatchEvent(new CustomEvent('jwtAvailable', {detail:{jwt:jwt}}));
                    doLog('jwt is available and has been propagated', jwt.substr(0, 6) + '..' + jwt.substr(jwt.length - 6));
                }
			} else {
				doLog('something went wrong when synchronizing epaper access', axRslt);
			}
		};

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

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

        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') {
				doLog('userRef is ', axRslt['user_ref']);
				propagateUserRefId(axRslt['user_ref']);
                syncInAppPurchases(uuid);
                loadActiveCampaigns(uuid);
			} else {
				doLog('no userRefId', axRslt);
				initExperience();
			}
		};

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

	function propagateUserRefId(userRefId) {
		if (typeof window.tp !== 'object') {
			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'));
            doLog('userRefId synched');
            // initExperience();
        }
	}

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

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

	function init() {
		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 () {
        let formData = new FormData();
        formData.append('client_id', SSO.clientId);
        formData.append('ajaxMode', '1');

        let oReq = new XMLHttpRequest();
        oReq.open('POST', ssoDomain + '/auth/logout', true);
        oReq.withCredentials = true;
        oReq.send(formData);
    },

    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 formData = new FormData();
            formData.append('username', u);
            formData.append('password', p);
            formData.append('noRedirectOnResponse', '1');
            formData.append('client_id', SSO.clientId);
            formData.append('redirect_uri', SSO.returnUri);

            let oReq = new XMLHttpRequest();
            oReq.open('POST', ssoDomain + '/auth/authorize', true);
            oReq.withCredentials = true;
            oReq.onload = function (oEvent) {
                if (oReq.status === 200) {
                    try {
                        let ssoRslt = JSON.parse(oReq.responseText);
                        if (typeof ssoRslt.message === 'string') {
                            rslt.msg = ssoRslt.message;
                        }
                        if (typeof ssoRslt.code === 'string') {
                            rslt.code = ssoRslt.code;
                        }
                        if (typeof ssoRslt.status === 'string') {
                            if (ssoRslt.status === 'success') {
                                rslt.loggedIn = true;
                                rslt.msg = 'successfully logged in';
                            }
                        }
                    } catch (e) {
                    }
                } else {
                    rslt.msg = 'error: http status was ' + oReq.status;
                }

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