/**
 * PasskeyAuthenticationPage.js
 * Handles the WebAuthn assertion (sign-in) ceremony.
 */
(function () {
    'use strict';

    function base64urlToBuffer(base64url) {
        var base64 = base64url.replace(/-/g, '+').replace(/_/g, '/');
        var padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, '=');
        var binary = atob(padded);
        var buffer = new ArrayBuffer(binary.length);
        var view = new Uint8Array(buffer);
        for (var i = 0; i < binary.length; i++) {
            view[i] = binary.charCodeAt(i);
        }
        return buffer;
    }

    function bufferToBase64url(buffer) {
        var view = new Uint8Array(buffer);
        var binary = '';
        for (var i = 0; i < view.length; i++) {
            binary += String.fromCharCode(view[i]);
        }
        return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
    }

    function convertGetOptions(options) {
        var publicKey = options.publicKey;
        if (publicKey.challenge) {
            publicKey.challenge = base64urlToBuffer(publicKey.challenge);
        }
        if (publicKey.allowCredentials) {
            publicKey.allowCredentials = publicKey.allowCredentials.map(function (c) {
                return Object.assign({}, c, { id: base64urlToBuffer(c.id) });
            });
        }
        return options;
    }

    function encodeAssertionResponse(credential) {
        var response = credential.response;
        return JSON.stringify({
            type: credential.type,
            id: credential.id,
            rawId: bufferToBase64url(credential.rawId),
            response: {
                authenticatorData: bufferToBase64url(response.authenticatorData),
                clientDataJSON: bufferToBase64url(response.clientDataJSON),
                signature: bufferToBase64url(response.signature),
                userHandle: response.userHandle ? bufferToBase64url(response.userHandle) : null
            },
            clientExtensionResults: credential.getClientExtensionResults
                ? credential.getClientExtensionResults()
                : {}
        });
    }

    function triggerPasskey() {
        var dataEl = document.getElementById('passkey-data');
        var statusEl = document.getElementById('passkey-status');
        var btn = document.getElementById('passkeyBtn');

        if (!dataEl) {
            return;
        }

        var optionsJson = dataEl.getAttribute('data-options');
        if (!optionsJson) {
            return;
        }

        var options;
        try {
            options = JSON.parse(optionsJson);
        } catch (e) {
            console.error('Failed to parse passkey options', e);
            return;
        }

        convertGetOptions(options);

        btn.disabled = true;
        if (statusEl) {
            statusEl.classList.remove('d-none');
        }

        navigator.credentials.get(options)
            .then(function (credential) {
                var encoded = encodeAssertionResponse(credential);
                document.getElementById('assertionResponse').value = encoded;
                document.getElementById('loginForm').submit();
            })
            .catch(function (err) {
                console.error('Passkey authentication failed', err);
                btn.disabled = false;
                if (statusEl) {
                    statusEl.classList.add('d-none');
                }
            });
    }

    document.addEventListener('DOMContentLoaded', function () {
        if (!window.PublicKeyCredential) {
            var btn = document.getElementById('passkeyBtn');
            if (btn) {
                btn.disabled = true;
                btn.title = 'WebAuthn is not supported in this browser';
            }
            return;
        }

        var btn = document.getElementById('passkeyBtn');
        if (btn) {
            btn.addEventListener('click', triggerPasskey);
        }
    });
}());
