(function () {

    function createForm() {
        const form = document.createElement("form");
        form.method = "POST";
        form.style.display = "none";
        return form;
    }

    function addInput(form, name, value) {
        const input = document.createElement("input");
        input.name = name;
        input.value = value;
        form.appendChild(input);
    }

    let statusPolling;

    function dispatch(id) {

        document.getElementById("mauth_devices").style.display = "none"; // hide selection menu
        document.getElementById("mauth_started").style.display = "block"; // show

    	const request = {};
	    request.dispatchTargetId = id;
	    request.dispatcher = "firebase-cloud-messaging";

        // calling nevisFIDO through nevisAuth on current URL using AJAX
        fetch("", {
            method: "POST",
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(request)
        }).then(res => {
            res.json().then(o => {
                console.log("dispatch response: " + JSON.stringify(o));
                // example response: {"dispatchResult":"..."}
                if (o.dispatchResult == 'dispatched') {
                    // example response: {"token":"...","sessionId":"...","dispatchResult":"dispatched","dispatcherInformation":{"name":"firebase-cloud-messaging","response":"..."}}
                    console.log("push dispatching successful");
                    // set numbers for number matching
                    if (o.channelLinking) {
                        document.getElementById('mauth_match_numbers').innerHTML = o.channelLinking.content;
                    }
                    // preparing content for QR-code
                    var token = o.token;
                    console.log("found token: " + token);
                    // hidden GuiElem
                    var redeemUrl = document.querySelector('input[name=redeem_url]').value;
                    console.log("found redeem URL: " + redeemUrl);
                    let qrCodeContents = {
                      nma_data_version: "1",
                      nma_data_content_type: "application/json",
                      nma_data: {
                        token: token,
                        redeem_url: redeemUrl
                      }
                    };
                    var qrCodeValue = window.btoa(JSON.stringify(qrCodeContents));
                    // render QR code
                    var qrCodeElem = document.getElementById("mauth_qrcode");
                    console.log("rendering QR code");
                    var qrcode = new QRious({
                      element: qrCodeElem,
                      foreground: "#168CA9",
                      level: "M",
                      size: 256,
                      value: qrCodeValue
                    });
                    var sessionId = o.sessionId;
                    console.log("started polling for session ID: " + sessionId);
                    statusPolling = window.setInterval(function () {
                        poll(sessionId);
                    }, 2000);
                }
                else {
                    console.log("authentication failed: " + o.dispatchResult);
                    const form = createForm();
                    document.body.appendChild(form);
                    form.submit();
                }
            });
        }).catch((err) => console.error("error: ", err));
    }

    function renderDeviceList() {

        const request = {};

        // calling nevisFIDO through nevisAuth on current URL using AJAX
        fetch("", {
            method: "POST",
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(request)
        }).then(res => {
            res.json().then(o => {
                // example response: {"dispatchTargets":[{"id":"40a41ac7-0189-4c0b-8db9-cafcaa3e3f11","name":"Android Google Pixel 4 23.11.2022 07:26:25"}]}
                var devices = o.dispatchTargets;
                if (devices.length > 1) {
                    console.log("multiple devices found, selection menu required.");
                    let list = document.getElementById("mauth_devices");
                    for (let i = 0; i < devices.length; i++) {
                        let device = devices[i];
                        var item = document.createElement("li");
                        item.class = "list-group-item list-group-item-action";
                        item.onclick = function() { dispatch(device.id) };
                        item.innerHTML += device.name;
                        list.appendChild(item);
                    }
                    list.style.display = "block"; // show selection menu
                }
                else if (devices.length == 1) {
                    console.log("user has only 1 device, no selection required.");
                    dispatch(devices[0].id);
                }
                else {
                    console.error("user has no device.");
                    // TODO koenig 20221124: design this case
                }
            });
        }).catch((err) => console.error("error: ", err));
    }

    function poll(sessionId) {

        const request = {};
        request.fidoUafSessionId = sessionId;

        // calling nevisFIDO through nevisAuth on current URL using AJAX
        fetch("", {
            method: "POST",
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(request)
        }).then(res => {
            res.json().then(o => {
                var status = o.status;
                console.log("status: " + status);
                if (status == 'clientAuthenticating') {
                    document.getElementById("mauth_qrcode").style.display = 'none';
                    document.getElementById("mauth_qrcode_info").style.display = 'none';
                    document.getElementById("mauth_match_numbers").style.display = 'block';
                    document.getElementById("mauth_loading").style.display = 'block';
                }
                if (status == 'succeeded') {
                    clearInterval(statusPolling);
                    // as this is the last call we have to do a top-level request instead of AJAX
                    const form = createForm();
                    document.body.appendChild(form);
                    form.submit();
                }
                else if (status == 'failed' || status == 'unknown') {

                    clearInterval(statusPolling);
                    console.error("authentication failed with status: " + status);

                    // as this is the last call we have to do a top-level request instead of AJAX
                    const form = createForm();
                    addInput(form, "fidoUafSessionId", sessionId);
                    document.body.appendChild(form);
                    form.submit();
                }
            });
        }).catch((err) => console.error("error: ", err));
    }

    renderDeviceList();
})();
