/// <reference path="helpers.js" />

//showDemoAlert();

//let pageUri = window.location.origin + '/WebServices/MachPanelService.asmx';

//document.getElementById('btn-passworless-auth').addEventListener('click', handleSignInSubmit);

async function handleSignInSubmit(event) {
    event.preventDefault();

    $('.page-loader-wrapper').show();

    if (this && this.username)
        username = this.username.value;
    else {
        username = $('input[type="hidden"][id$="hf_passworless_username"]').val()
    }
    if (!username)
        return false;

    //console.log(username);
    // possible values: preferred, required, discouraged
    let user_verification = "preferred";
    // prepare post data
    let data = {
        'username': username,
        'userVerification': user_verification
    };

    // send to server for registering
    let makeAssertionOptions;
    try {
        var res = await fetch(pageUri + '/assertionOptions', {
            method: 'POST', // or 'PUT'
            body: JSON.stringify(data), // data can be `string` or {object}!
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json; charset=UTF-8'
            }
        });

        makeAssertionOptions = await res.json();
        makeAssertionOptions = JSON.parse(makeAssertionOptions.d)
    } catch (e) {
        $('.page-loader-wrapper').hide();
        showErrorAlert(MSG_CONST.serverRequestError, e, () => { window.location.href = window.location.href; });
    }

    //console.log("Assertion Options Object", makeAssertionOptions);

    // show options error to user
    if (makeAssertionOptions.status !== "ok") {
        //console.log("Error creating assertion options");
        //console.log(makeAssertionOptions.errorMessage);
        $('.page-loader-wrapper').hide();
        showErrorAlert(makeAssertionOptions.errorMessage, null, () => { window.location.href = window.location.href; });
        return;
    }

    // todo: switch this to coercebase64
    const challenge = makeAssertionOptions.challenge.replace(/-/g, "+").replace(/_/g, "/");
    makeAssertionOptions.challenge = Uint8Array.from(atob(challenge), c => c.charCodeAt(0));

    // fix escaping. Change this to coerce
    makeAssertionOptions.allowCredentials.forEach(function (listItem) {
        var fixedId = listItem.id.replace(/\_/g, "/").replace(/\-/g, "+");
        listItem.id = Uint8Array.from(atob(fixedId), c => c.charCodeAt(0));
    });

    //console.log("Assertion options", makeAssertionOptions);

    Swal.fire({
        title: MSG_CONST.loggingIn,
        text: MSG_CONST.pleaseWait,
        /*imageUrl: "/images/securitykey.min.svg",*/
        showCancelButton: false,
        showConfirmButton: false,
        focusConfirm: false,
        focusCancel: false
    });

    // ask browser for credentials (browser will ask connected authenticators)
    let credential;
    try {
        credential = await navigator.credentials.get({ publicKey: makeAssertionOptions })
    } catch (err) {
        $('.page-loader-wrapper').hide();
        showErrorAlert(err.message ? err.message : err, null, () => { window.location.href = window.location.href; });
    }

    if (credential && credential.response && credential.response.authenticatorData) {
        try {
            await verifyAssertionWithServer(credential).then(() => {
                $('.page-loader-wrapper').hide();
            });
        } catch (e) {
            $('.page-loader-wrapper').hide();
            showErrorAlert(MSG_CONST.credVerifyFaild, e, () => { window.location.href = window.location.href; });
        }
    }
}

/**
 * Sends the credential to the the FIDO2 server for assertion
 * @param {any} assertedCredential
 */
async function verifyAssertionWithServer(assertedCredential) {

    // Move data into Arrays incase it is super long
    let authData = new Uint8Array(assertedCredential.response.authenticatorData);
    let clientDataJSON = new Uint8Array(assertedCredential.response.clientDataJSON);
    let rawId = new Uint8Array(assertedCredential.rawId);
    let sig = new Uint8Array(assertedCredential.response.signature);
    const data = {
        id: assertedCredential.id,
        rawId: coerceToBase64Url(rawId),
        type: assertedCredential.type,
        extensions: assertedCredential.getClientExtensionResults(),
        response: {
            authenticatorData: coerceToBase64Url(authData),
            clientDataJson: coerceToBase64Url(clientDataJSON),
            signature: coerceToBase64Url(sig)
        }
    };
    //console.log('makeAssertion:data:', data);
    let postData = { 'clientResponse': data };
    let response;
    try {
        let res = await fetch(pageUri + "/makeAssertion", {
            method: 'POST', // or 'PUT'
            body: JSON.stringify(postData), // data can be `string` or {object}!
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json; charset=utf-8'
            }
        });
        //console.log('response:', res);
        response = await res.json();
        response = JSON.parse(response.d)
    } catch (e) {
        $('.page-loader-wrapper').hide();
        showErrorAlert(MSG_CONST.serverRequestError, e, () => { window.location.href = window.location.href; });
        throw e;
    }

    //console.log("Assertion response", response);

    // show error
    if (response.status !== "ok") {
        //console.log("Error doing assertion");
        //console.log(response.errorMessage);
        $('.page-loader-wrapper').hide();
        showErrorAlert(response.errorMessage, null, () => { window.location.href = window.location.href; });
        return;
    }

    $('.page-loader-wrapper').hide();

    //show success message
    /*await Swal.fire({
        title: MSG_CONST.loginSuccessTitle,
        text: MSG_CONST.loginSuccessText,
        type: 'success'
    });*/


    //console.log('response.secLogin', response.secLogin);

    //console.log('response.secLoginToken', response.secLoginToken);

    let newUrl = window.location.href.toString()
    if (window.location.href.includes("SecLogin=")) {
        let startIndex = window.location.href.toString().indexOf("SecLogin=");
        let endIndex = window.location.href.toString().indexOf("state=98088");
        let toRemove = window.location.href.toString().substring(startIndex - 1, endIndex);
        newUrl = window.location.href.toString().replace(toRemove, "").replace("state=980888", "").replace("state=980887", "");;
    }

    if (newUrl.includes("?"))
        newUrl = newUrl + `&SecLogin=${encodeURIComponent(response.secLogin + ":" + response.secLoginToken)}&state=980887`;
    else
        newUrl = newUrl + `?SecLogin=${encodeURIComponent(response.secLogin + ":" + response.secLoginToken)}&state=980888`;
    //alert(newUrl);
    window.location.href = newUrl;
}
