let baseURL; // base URL
let statusToken; // used to check progress
let dispatcherElement; // to display link or QR code
let infoElement; // to display info text
let errorElement; // to display error text

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

function submitStatus(status) {
  // we have to do a form POST instead of AJAX
  const form = document.createElement("form");
  form.method = "POST";
  form.style.display = "none";
  addInput(form, "status", status);
  document.body.appendChild(form);
  form.submit();
}

const Status = {
    _pollInterval: 2 * 1000, // Check every 2 seconds
    latest: null,

    startPolling: function (token, uiCallback) {
        let interval = setInterval(async () => {
            await this._check(token).then(function (resp) {
                console.log("Polling status: %o", resp);
                uiCallback && uiCallback(resp, false);
                return Status.latest = resp;
            })
            .catch(function (err) {
                console.error("Error during polling: %o", err);
                return false;
            });
            if (Status.latest && (Status.latest.status === 'succeeded' || Status.latest.status === 'failed' || Status.latest.status === 'unknown')) {
                // Done!
                console.log('Latest status is: %o', this.latest);
                uiCallback && uiCallback(this.latest, true);
                clearInterval(interval);
            }
        }, this._pollInterval);
    },

    _check: async function (token) {
        const payload = { statusToken: token };
        const response = await fetch(baseURL + 'api/v1/status', {
            method: 'POST',
            mode: 'cors',
            cache: 'no-cache',
            credentials: 'omit',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json;charset=utf-8'
            },
            body: JSON.stringify(payload),
            redirect: 'follow',
            referrerPolicy: 'no-referrer'
        });

        return await response.json();
    }
};

function setDeepLinkLabel(button) {
    const text = document.getElementsByName('info.deeplink')[0].value;
    button.innerHTML = text;
}

function messageScanQR() {
    const text = document.getElementsByName('info.qrcode')[0].value;
    infoElement.innerHTML = text;
}

function messageCheckPhone() {
    const text = document.getElementsByName('info.check.phone')[0].value;
    infoElement.innerHTML = text;
}

const Element = {

    _elem: null, // QR code or deep link depending on device

    show: function (appLink) {
        const userAgent = navigator.userAgent || navigator.vendor || window.opera;
        const isIphone = 'iPhone' === navigator.platform;
        const isAndroid = /android/i.test(userAgent) && /mobile/i.test(userAgent);
        if (isAndroid || isIphone) {
            this._elem = document.createElement('a');
            this._elem.setAttribute('href', appLink);
            this._elem.setAttribute('class', 'btn btn-primary');
            this._elem.setAttribute('target', '_blank');
            dispatcherElement.appendChild(this._elem);
            setDeepLinkLabel(this._elem);
        }
        else {
            const authenticationType = document.getElementsByName('authenticationType')[0].value;
            if (authenticationType == 'push') {
                messageCheckPhone();
            }
            else {
                messageScanQR();
                this._elem = document.createElement('canvas');
                dispatcherElement.appendChild(this._elem);
                var qrcode = new QRious({
                  element: this._elem,
                  foreground: "#168CA9",
                  level: "M",
                  size: 280,
                  value: appLink
                });
            }
        }
    },

    hide: function() {
        // hide the element which was shown
        if (this._elem != null) {
            this._elem.style.display = "none";
        }
    }
};

function authenticateUser(appLink) {
    Element.show(appLink);
    console.log('Starting Authentication Cloud status polling...');
    Status.startPolling(statusToken, (st, done) => {
        if (st.status === 'succeeded') {
            console.log('Authentication Cloud login done.');
            submitStatus('succeeded')
        }
        else if (st.status === 'failed') {
            // failed: The transaction failed, either by timeout or because the user did not accept.
            console.warn('Authentication Cloud login failed. User abort or timeout.');
            submitStatus('failed')
        }
        else if (st.status === 'unknown') {
            console.error('Authentication Cloud login failed. Unknown status.');
            submitStatus('unknown')
        }
    });
}

function init() {

    const form = document.getElementById('authcloud_login');

    baseURL = form.url.value;
    statusToken = form.statusToken.value;

    infoElement = document.getElementById('authcloud_info');
    errorElement = document.getElementById('authcloud_error');

    dispatcherElement = document.getElementById('authcloud_dispatch');

    const appLink = form.appLink.value;
    authenticateUser(appLink);
}

window.onload = function() {
  init();
};
