console.debug('credupdate: loaded');

// Makes the password form interactive (e.g. shows when passwords don't match)
function setupInteractivePwdFormListeners() {
    const new_pwd = document.getElementById("new-password");
    const new_pwd_check = document.getElementById("new-password-check");
    const pwd_submit = document.getElementById("password-submit");

    function markPwdCheckValid() {
        new_pwd_check.classList.remove("is-invalid");
        new_pwd_check.classList.add("is-valid");
        pwd_submit.disabled = false;
    }

    function markPwdCheckInvalid() {
        new_pwd_check.classList.add("is-invalid");
        new_pwd_check.classList.remove("is-valid");
        pwd_submit.disabled = true;
    }

    new_pwd.addEventListener("input", (_) => {
        // Don't mark invalid if user didn't fill in the confirmation box yet
        // Also my password manager (keepassxc with autocomplete)
        //   likes to fire off input events when both inputs were empty.
        if (new_pwd_check.value !== "") {
            if (new_pwd.value === new_pwd_check.value) {
                markPwdCheckValid();
            } else {
                markPwdCheckInvalid();
            }
        }
        new_pwd.classList.remove("is-invalid");
    });

    new_pwd_check.addEventListener("input", (_) => {
        // No point in updating the status if confirmation box is empty
        if (new_pwd_check.value === "") return;
        if (new_pwd_check.value === new_pwd.value) {
            markPwdCheckValid();
        } else {
            markPwdCheckInvalid();
        }
    });
}

window.stillSwapFailureResponse = function(event) {
    if (event.detail.xhr.status === 422 || event.detail.xhr.status === 500) {
        console.log("Still swapping failure response")
        event.detail.shouldSwap = true;
        event.detail.isError = false;
    }
}

function onPasskeyCreated(assertion) {
    try {
        console.log(assertion)
        let creationData = {};

        creationData.id = assertion.id;
        creationData.rawId = Base64.fromUint8Array(new Uint8Array(assertion.rawId))
        creationData.response = {};
        creationData.response.attestationObject = Base64.fromUint8Array(new Uint8Array(assertion.response.attestationObject))
        creationData.response.clientDataJSON = Base64.fromUint8Array(new Uint8Array(assertion.response.clientDataJSON))
        creationData.type = assertion.type
        creationData.extensions = assertion.getClientExtensionResults()
        creationData.extensions.uvm = undefined

        // Put the passkey creation data into the form for submission
        document.getElementById("passkey-create-data").value = JSON.stringify(creationData)

        // Make the name input visible and hide the "Begin Passkey Enrollment" button
        document.getElementById("passkeyNamingSafariPre").classList.add("d-none")
        document.getElementById("passkeyNamingForm").classList.remove("d-none")
        document.getElementById("passkeyNamingSubmitBtn").classList.remove("d-none")
    } catch (e) {
        console.log(e)
        if (confirm("Failed to encode your new passkey's data for transmission, confirm to reload this page.\nReport this issue if it keeps occurring.")) {
            window.location.reload();
        }
    }
}

function startPasskeyEnrollment() {
    try {
        const data_elem = document.getElementById('data');
        const credentialRequestOptions = JSON.parse(data_elem.textContent);
        credentialRequestOptions.publicKey.challenge = Base64.toUint8Array(credentialRequestOptions.publicKey.challenge);
        credentialRequestOptions.publicKey.user.id = Base64.toUint8Array(credentialRequestOptions.publicKey.user.id);

        console.log(credentialRequestOptions)
        navigator.credentials
            .create({publicKey: credentialRequestOptions.publicKey})
            .then((assertion) => {
                onPasskeyCreated(assertion);
            }, (reason) => {
                alert("Passkey creation failed " +  reason.toString())
                console.log("Passkey creation failed: " + reason.toString())
            });
    } catch (e) {
        console.log(e)
        if (confirm("Failed to initialize passkey creation, confirm to reload this page.\nReport this issue if it keeps occurring.")) {
            window.location.reload();
        }
    }
}

function setupPasskeyNamingSafariButton() {
    document.getElementById("passkeyNamingSafariBtn")
        .addEventListener("click", startPasskeyEnrollment)
}

function setupSubmitBtnVisibility() {
    document.getElementById("passkey-label")
        ?.addEventListener("input", updateSubmitButtonVisibility)
}

function updateSubmitButtonVisibility(event) {
    const submitButton = document.getElementById("passkeyNamingSubmitBtn");
    submitButton.disabled = event.value === "";
}

(function() {
    console.debug('credupdate: init');
    document.body.addEventListener("addPasswordSwapped", () => { setupInteractivePwdFormListeners() });
    document.body.addEventListener("addPasskeySwapped", () => {
        setupPasskeyNamingSafariButton();
        startPasskeyEnrollment();
        setupSubmitBtnVisibility();
    });
})()
