(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;

    let isPolling = false;
    let pollingTimeout = null;

    const POLLING_INTERVAL = 2000;
    const REQUEST_TIMEOUT = 3000;

    function dispatchLink() {

        document.getElementById("mauth_started").style.display = "block"; // show

    	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: {"dispatchResult":"..."}
                if (o.dispatchResult == 'dispatched') {
                    // example response: {..., "dispatcherInformation":{..., "response":"admin4testing://authenticate?dispatchTokenResponse=ey..."}}
                    var link = o.dispatcherInformation.response;
                    console.log("received link: " + link);
                    var linkElem = document.getElementById("mauth_link");
                    linkElem.href = link; // custom scheme link does not work in Android 13
                    const isMobile = !!/(iPhone|iPad|Android)/.test(window.navigator.userAgent);
                    if (isMobile) {
                        document.getElementById("mauth_link_parent").style.display = "inline"; // show
                    }
                    var url = new URL(link);
                    var dispatchTokenResponse = url.searchParams.get("dispatchTokenResponse");
                    // render QR code
                    var qrCodeElem = document.getElementById("mauth_qrcode");
                    var qrcode = new QRious({
                      element: qrCodeElem,
                      foreground: "#168CA9",
                      level: "M",
                      size: 256,
                      value: link
                    });
                    var sessionId = o.sessionId;
                    console.log("started polling for session ID: " + sessionId);
                    poll(sessionId);
                }
                else {
                    console.log("authentication failed: " + o.dispatchResult);
                    const form = createForm();
                    document.body.appendChild(form);
                    form.submit();
                }
            });
        }).catch((err) => console.error("error: ", err));
    }

    function poll(sessionId) {
        if (isPolling) {
            return; // Exit if a polling request is already ongoing
        }

        isPolling = true;

        const request = { fidoUafSessionId: sessionId };

        const fetchRequest = fetch("", {
            method: "POST",
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(request)
        });

        // Set up the timeout for the fetch request
        const timeoutPromise = new Promise((_, reject) => {
            pollingTimeout = setTimeout(() => {
                reject(new Error('Request timed out'));
            }, REQUEST_TIMEOUT);
        });

        Promise.race([fetchRequest, timeoutPromise])
            .then(res => res.json())
            .then(o => {
                clearTimeout(pollingTimeout);
                var status = o.status;
                console.log("status: " + status);

                if (status == 'clientAuthenticating') {
                    // show process icon
                    document.getElementById("mauth_loading").style.display = 'block';
                    // hide QR-code and information
                    document.getElementById("mauth_qrcode").style.display = 'none';
                    document.getElementById("mauth_qrcode_info").style.display = 'none';
                }
                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();
                    addInput(form, "continue", "true"); // required for custom dispatching in usernameless
                    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);
            })
            .finally(() => {
                isPolling = false;
                // Schedule the next poll if needed
                setTimeout(() => poll(sessionId), POLLING_INTERVAL);
            });
    }

    dispatchLink();
})();
