/**
 * Guard Dog 2FA Setup Interstitial
 *
 * Handles the 2FA setup flow during login when enforcement requires setup.
 *
 * @package GuardDog
 * @since 1.9.1
 */

(function($) {
    'use strict';

    // Configuration from localized script
    var config = window.guardDog2FASetup || {};
    var i18n = config.i18n || {};

    /**
     * Initialize the setup interstitial functionality.
     */
    function init() {
        bindMethodSelection();
        bindBackButtons();
        bindTOTPSetup();
        bindEmailSetup();
        bindPasskeySetup();
        bindCopyButtons();
    }

    /**
     * Bind method selection card clicks.
     */
    function bindMethodSelection() {
        $('.guard-dog-setup-method-btn').on('click', function(e) {
            e.preventDefault();
            var method = $(this).data('method');
            showSetupSection(method);
        });
    }

    /**
     * Show the setup section for a specific method.
     */
    function showSetupSection(method) {
        // Hide method list
        $('#guard-dog-method-list').hide();

        // Hide all setup sections
        $('.guard-dog-setup-section').hide();

        // Show the selected section
        var sectionId = '#guard-dog-' + method + '-setup-section';
        $(sectionId).show();

        // Initialize the section if needed
        if (method === 'totp') {
            initTOTPSection();
        }
    }

    /**
     * Bind back button clicks.
     */
    function bindBackButtons() {
        $('.guard-dog-back-btn').on('click', function(e) {
            e.preventDefault();
            showMethodList();
        });
    }

    /**
     * Show the method list and hide all setup sections.
     */
    function showMethodList() {
        $('.guard-dog-setup-section').hide();
        $('#guard-dog-method-list').show();
    }

    /**
     * Initialize the TOTP setup section.
     */
    function initTOTPSection() {
        var $qrContainer = $('#guard-dog-totp-qr-code');
        var $secretKey = $('#guard-dog-totp-secret-key');

        // Show loading state
        $qrContainer.html('<div class="guard-dog-qr-loading"><span class="spinner is-active"></span> ' + i18n.loading + '</div>');

        // Generate 2FA secret via AJAX (secret is stored server-side in transient)
        $.ajax({
            url: config.ajaxUrl,
            type: 'POST',
            data: {
                action: 'guard_dog_setup_generate_secret',
                user_id: $('#guard-dog-setup-user-id').val(),
                security: config.nonce
            },
            success: function(response) {
                if (response.success && response.data) {
                    // Display secret for manual entry (stored server-side for security)
                    $secretKey.text(response.data.secret);

                    // Display QR code when local generation succeeds, otherwise fall back to manual entry.
                    if (response.data.qr_code) {
                        $qrContainer.html('<img src="' + response.data.qr_code + '" alt="QR Code" />');
                    } else {
                        $qrContainer.html('<p class="description">' + (i18n.qrUnavailable || i18n.manualEntry || i18n.error) + '</p>');
                    }
                } else {
                    $qrContainer.html('<p class="error">' + (response.data || i18n.error) + '</p>');
                }
            },
            error: function() {
                $qrContainer.html('<p class="error">' + i18n.error + '</p>');
            }
        });
    }

    /**
     * Bind TOTP setup form submission.
     */
    function bindTOTPSetup() {
        $('#guard-dog-totp-verify-form').on('submit', function(e) {
            var $form = $(this);
            var $submitBtn = $form.find('button[type="submit"]');
            var $codeInput = $('#guard-dog-totp-verify-code');

            // Validate code
            var code = $codeInput.val().trim();
            if (!/^\d{6}$/.test(code)) {
                showFormError($form, i18n.invalidCode);
                e.preventDefault();
                return false;
            }

            // Show loading state
            $submitBtn.prop('disabled', true).text(i18n.verifying);

            // Form will submit normally - server handles the rest
            return true;
        });
    }

    /**
     * Bind Email 2FA setup interactions.
     */
    function bindEmailSetup() {
        var $sendBtn = $('#guard-dog-send-email-code-btn');
        var $resendBtn = $('#guard-dog-resend-email-code');
        var $status = $('#guard-dog-email-status');
        var $verifyForm = $('#guard-dog-email-verify-form');

        // Send code button
        $sendBtn.on('click', function(e) {
            e.preventDefault();
            sendEmailCode($sendBtn, $status, $verifyForm);
        });

        // Resend code button
        $resendBtn.on('click', function(e) {
            e.preventDefault();
            sendEmailCode($resendBtn, $status, $verifyForm);
        });

        // Form submission
        $verifyForm.on('submit', function(e) {
            var $form = $(this);
            var $submitBtn = $form.find('button[type="submit"]');
            var $codeInput = $('#guard-dog-email-verify-code');

            // Validate code
            var code = $codeInput.val().trim();
            if (!/^\d{6}$/.test(code)) {
                showFormError($form, i18n.invalidCode);
                e.preventDefault();
                return false;
            }

            // Show loading state
            $submitBtn.prop('disabled', true).text(i18n.verifying);

            // Form will submit normally
            return true;
        });
    }

    /**
     * Send email verification code via AJAX.
     */
    function sendEmailCode($btn, $status, $verifyForm) {
        var originalText = $btn.text();
        $btn.prop('disabled', true).text(i18n.loading);
        $status.text('').removeClass('success error');

        $.ajax({
            url: config.ajaxUrl,
            type: 'POST',
            data: {
                action: 'guard_dog_setup_send_email_code',
                user_id: $('#guard-dog-setup-user-id').val(),
                security: config.nonce
            },
            success: function(response) {
                $btn.prop('disabled', false).text(originalText);

                if (response.success) {
                    $status.text(i18n.codeSent).addClass('success');
                    $verifyForm.show();
                    $('#guard-dog-email-verify-code').focus();
                } else {
                    $status.text(response.data || i18n.error).addClass('error');
                }
            },
            error: function() {
                $btn.prop('disabled', false).text(originalText);
                $status.text(i18n.error).addClass('error');
            }
        });
    }

    /**
     * Bind Passkey registration interactions.
     */
    function bindPasskeySetup() {
        var $registerBtn = $('#guard-dog-register-passkey-btn');
        var $status = $('#guard-dog-passkey-status');
        var $nameSection = $('.guard-dog-passkey-name-section');

        $registerBtn.on('click', function(e) {
            e.preventDefault();
            registerPasskey($registerBtn, $status, $nameSection);
        });
    }

    /**
     * Register a passkey using WebAuthn.
     */
    function registerPasskey($btn, $status, $nameSection) {
        // Check for WebAuthn support
        if (!window.PublicKeyCredential) {
            $status.text('Your browser does not support passkeys.').addClass('error');
            return;
        }

        var originalText = $btn.html();
        $btn.prop('disabled', true).html('<span class="spinner is-active"></span> ' + i18n.loading);
        $status.text(i18n.passkeyPrompt).removeClass('success error');

        var userId = $('#guard-dog-setup-user-id').val();
        var friendlyName = $('#guard-dog-passkey-name').val() || 'Setup Interstitial';

        // Step 1: Get registration options from server
        $.ajax({
            url: config.ajaxUrl,
            type: 'POST',
            data: {
                action: 'guard_dog_setup_register_passkey_options',
                user_id: userId,
                security: config.nonce
            },
            success: function(response) {
                if (!response.success) {
                    $btn.prop('disabled', false).html(originalText);
                    $status.text(response.data || i18n.passkeyError).addClass('error');
                    return;
                }

                // Convert options for WebAuthn API
                var options = prepareRegistrationOptions(response.data);

                // Step 2: Create credential with browser
                navigator.credentials.create({ publicKey: options })
                    .then(function(credential) {
                        // Step 3: Send credential to server for verification
                        return verifyPasskeyRegistration(credential, userId, friendlyName);
                    })
                    .then(function(result) {
                        $btn.prop('disabled', false).html(originalText);

                        if (result.success) {
                            $status.text(i18n.passkeySuccess).addClass('success');

                            // Redirect after short delay
                            setTimeout(function() {
                                $status.text(i18n.setupComplete);
                                window.location.href = $('#guard-dog-setup-redirect').val();
                            }, 1000);
                        } else {
                            $status.text(result.message || i18n.passkeyError).addClass('error');
                        }
                    })
                    .catch(function(error) {
                        $btn.prop('disabled', false).html(originalText);
                        if (window.guardDogDebug) {
                            console.error('Passkey registration error:', error);
                        }

                        var errorMessage = i18n.passkeyError;
                        if (error.name === 'NotAllowedError') {
                            errorMessage = (i18n && i18n.passkeyNotAllowed) ? i18n.passkeyNotAllowed : 'Registration was cancelled or not allowed.';
                        } else if (error.name === 'InvalidStateError') {
                            errorMessage = (i18n && i18n.passkeyExists) ? i18n.passkeyExists : 'A passkey for this account already exists on this device.';
                        }

                        $status.text(errorMessage).addClass('error');
                    });
            },
            error: function() {
                $btn.prop('disabled', false).html(originalText);
                $status.text(i18n.error).addClass('error');
            }
        });
    }

    /**
     * Prepare registration options for WebAuthn API.
     */
    function prepareRegistrationOptions(options) {
        // Decode base64url encoded values
        options.challenge = base64UrlDecode(options.challenge);

        if (options.user && options.user.id) {
            options.user.id = base64UrlDecode(options.user.id);
        }

        if (options.excludeCredentials) {
            options.excludeCredentials = options.excludeCredentials.map(function(cred) {
                return {
                    id: base64UrlDecode(cred.id),
                    type: cred.type,
                    transports: cred.transports
                };
            });
        }

        return options;
    }

    /**
     * Verify passkey registration with server.
     */
    function verifyPasskeyRegistration(credential, userId, friendlyName) {
        return new Promise(function(resolve, reject) {
            var attestationResponse = {
                id: credential.id,
                rawId: base64UrlEncode(credential.rawId),
                type: credential.type,
                response: {
                    clientDataJSON: base64UrlEncode(credential.response.clientDataJSON),
                    attestationObject: base64UrlEncode(credential.response.attestationObject)
                }
            };

            if (credential.response.getTransports) {
                attestationResponse.response.transports = credential.response.getTransports();
            }

            $.ajax({
                url: config.ajaxUrl,
                type: 'POST',
                data: {
                    action: 'guard_dog_setup_register_passkey_verify',
                    user_id: userId,
                    credential: JSON.stringify(attestationResponse),
                    friendly_name: friendlyName,
                    security: config.nonce
                },
                success: function(response) {
                    resolve({
                        success: response.success,
                        message: response.data
                    });
                },
                error: function() {
                    reject(new Error('Network error'));
                }
            });
        });
    }

    /**
     * Bind copy button functionality.
     */
    function bindCopyButtons() {
        $('#guard-dog-copy-totp-secret').on('click', function(e) {
            e.preventDefault();
            var secret = $('#guard-dog-totp-secret-key').text();
            copyToClipboard(secret, $(this));
        });
    }

    /**
     * Copy text to clipboard.
     */
    function copyToClipboard(text, $btn) {
        if (navigator.clipboard && navigator.clipboard.writeText) {
            navigator.clipboard.writeText(text).then(function() {
                showCopySuccess($btn);
            }).catch(function() {
                fallbackCopy(text, $btn);
            });
        } else {
            fallbackCopy(text, $btn);
        }
    }

    /**
     * Fallback copy method for older browsers.
     */
    function fallbackCopy(text, $btn) {
        var $temp = $('<input>');
        $('body').append($temp);
        $temp.val(text).select();
        document.execCommand('copy');
        $temp.remove();
        showCopySuccess($btn);
    }

    /**
     * Show copy success feedback.
     */
    function showCopySuccess($btn) {
        var originalText = $btn.text();
        $btn.text('Copied!').addClass('copied');
        setTimeout(function() {
            $btn.text(originalText).removeClass('copied');
        }, 2000);
    }

    /**
     * Show form error message.
     */
    function showFormError($form, message) {
        var $error = $form.find('.guard-dog-form-error');
        if (!$error.length) {
            $error = $('<div class="guard-dog-form-error"></div>');
            $form.prepend($error);
        }
        $error.text(message).show();
    }

    /**
     * Base64URL encode ArrayBuffer.
     */
    function base64UrlEncode(buffer) {
        var bytes = new Uint8Array(buffer);
        var binary = '';
        for (var i = 0; i < bytes.byteLength; i++) {
            binary += String.fromCharCode(bytes[i]);
        }
        return btoa(binary)
            .replace(/\+/g, '-')
            .replace(/\//g, '_')
            .replace(/=/g, '');
    }

    /**
     * Base64URL decode to ArrayBuffer.
     */
    function base64UrlDecode(str) {
        // Add padding if needed
        var padding = 4 - (str.length % 4);
        if (padding !== 4) {
            str += '='.repeat(padding);
        }

        // Convert base64url to base64
        str = str.replace(/-/g, '+').replace(/_/g, '/');

        // Decode
        var binary = atob(str);
        var bytes = new Uint8Array(binary.length);
        for (var i = 0; i < binary.length; i++) {
            bytes[i] = binary.charCodeAt(i);
        }
        return bytes.buffer;
    }

    // Initialize when DOM is ready
    $(document).ready(init);

})(jQuery);
