/* global two_factor_auth, jQuery */

// Helper function to restore UI state in case of errors
function restoreUIState() {
    jQuery('#verify-2fa').prop('disabled', false);
    jQuery('#twofa-code').prop('disabled', false);
    jQuery('#generate-qr').prop('disabled', false);
    jQuery('#send-email').prop('disabled', false);
    jQuery('.qr-code .spinner').removeClass('is-active');
}

// Debounce function to prevent rapid clicks
function debounce(func, wait) {
    var timeout;
    return function executedFunction() {
        var later = function() {
            clearTimeout(timeout);
            func.apply(this, arguments);
        };
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
    };
}

// Create debounced versions of functions
var debouncedSendEmail = debounce(sendEmailCode, 1000);
var debouncedGenerateQR = debounce(generateQRCode, 1000);

/**
 * Generates a new QR code with enhanced error handling.
 */
function generateQRCode() {
    try {
        // Check if two_factor_auth object is available
        if (typeof two_factor_auth === 'undefined' || !two_factor_auth.ajaxurl || !two_factor_auth.temp_token) {
            console.error('2FA: Required configuration not available');
            return;
        }
        
        // Use safe element checking
        var $generateBtn = jQuery('#generate-qr');
        var $spinner = jQuery('.qr-code .spinner');
        var $errorContainer = jQuery('#qr-code-img-err');
        
        if (!$generateBtn.length || !$spinner.length || !$errorContainer.length) {
            console.warn('2FA: Required DOM elements not found for QR code generation');
            return;
        }
        
        $generateBtn.prop('disabled', true);
        $spinner.addClass('is-active');
        
        // Clear any previous errors
        $errorContainer.empty();

        jQuery.ajax({
            url: two_factor_auth.ajaxurl,
            type: 'POST',
            data: {
                action: 'secnin_generate_qr_code',
                temp_token: two_factor_auth.temp_token
            },
            timeout: 30000, // 30 second timeout
            success: function (response) {
                try {
                    $generateBtn.prop('disabled', false);
                    $spinner.removeClass('is-active');
                    
                    if (response && response.success && response.data && response.data.qr_code) {
                        $errorContainer.empty();
                        // The QR code is already base64 encoded, use it directly
                        var $qrImg = jQuery('#qr-code-img');
                        if ($qrImg.length) {
                            $qrImg.attr('src', response.data.qr_code);
                        }
                        
                        // Show and populate the secret key if available
                        if (response.data.secret) {
                            var $secretKey = jQuery('#secret-key');
                            var $secretContainer = jQuery('#secret-container');
                            if ($secretKey.length) {
                                $secretKey.val(response.data.secret);
                            }
                            if ($secretContainer.length) {
                                $secretContainer.show();
                            }
                        }
                    } else {
                        var errorMsg = (response && response.data && response.data.message) ? 
                            response.data.message : 
                            (two_factor_auth.messages && two_factor_auth.messages.qr_error) ? 
                            two_factor_auth.messages.qr_error : 
                            'Error generating QR code. Please try again.';
                        $errorContainer.html('<p class="errmsg">' + errorMsg + '</p>');
                    }
                } catch (e) {
                    console.error('2FA: Error processing QR code response:', e);
                    $errorContainer.html('<p class="errmsg">Error processing response. Please try again.</p>');
                }
            },
            error: function (xhr, status, error) {
                console.error('2FA: AJAX error generating QR code:', status, error);
                $generateBtn.prop('disabled', false);
                $spinner.removeClass('is-active');
                var errorMsg = (two_factor_auth.messages && two_factor_auth.messages.network_error) ? 
                    two_factor_auth.messages.network_error : 
                    'Network error. Please check your connection and try again.';
                $errorContainer.html('<p class="errmsg">' + errorMsg + '</p>');
            }
        });
    } catch (e) {
        console.error('2FA: Error in generateQRCode function:', e);
        $errorContainer = jQuery('#qr-code-img-err');
        if ($errorContainer.length) {
            $errorContainer.html('<p class="errmsg">Error generating QR code. Please refresh the page.</p>');
        }
    }
}

/**
 * Sends a new 2FA email code with enhanced error handling.
 */
function sendEmailCode() {
    try {
        // Check if two_factor_auth object is available
        if (typeof two_factor_auth === 'undefined' || !two_factor_auth.ajaxurl || !two_factor_auth.temp_token) {
            console.error('2FA: Required configuration not available for email sending');
            return;
        }
        
        // Check if required elements exist
        var $sendBtn = jQuery('#send-email');
        var $status = jQuery('#email-status');
        
        if (!$sendBtn.length || !$status.length) {
            console.warn('2FA: Required DOM elements not found for email sending');
            return;
        }
        
        // Check if button is already disabled (prevent rapid clicking)
        if ($sendBtn.prop('disabled')) {
            console.warn('2FA: Email sending already in progress');
            return;
        }
        
        $sendBtn.prop('disabled', true);
        var sendingMsg = (two_factor_auth.messages && two_factor_auth.messages.sending_email) ? 
            two_factor_auth.messages.sending_email : 
            'Sending email...';
        $status.html('<p class="okmsg">' + sendingMsg + '</p>');

        jQuery.ajax({
            url: two_factor_auth.ajaxurl,
            type: 'POST',
            data: {
                action: 'secnin_send_2fa_email',
                temp_token: two_factor_auth.temp_token
            },
            timeout: 30000, // 30 second timeout
            success: function (response) {
                try {
                    $sendBtn.prop('disabled', false);
                    
                    if (response && response.success) {
                        var successMsg = (response.data && response.data.message) ? 
                            response.data.message : 
                            'Email sent successfully.';
                        $status.html('<p class="okmsg">' + successMsg + '</p>');
                        // Mark that an email has been sent to prevent auto-sending
                        window.sn2faEmailSent = true;
                    } else {
                        var errorMsg = (response && response.data && response.data.message) ? 
                            response.data.message : 
                            (two_factor_auth.messages && two_factor_auth.messages.email_error) ? 
                            two_factor_auth.messages.email_error : 
                            'Error sending email. Please try again.';
                        $status.html('<p class="errmsg">' + errorMsg + '</p>');
                    }
                } catch (e) {
                    console.error('2FA: Error processing email response:', e);
                    $status.html('<p class="errmsg">Error processing response. Please try again.</p>');
                }
            },
            error: function (xhr, status, error) {
                console.error('2FA: AJAX error sending email:', status, error);
                $sendBtn.prop('disabled', false);
                var errorMsg = (two_factor_auth.messages && two_factor_auth.messages.network_error) ? 
                    two_factor_auth.messages.network_error : 
                    'Network error. Please check your connection and try again.';
                $status.html('<p class="errmsg">' + errorMsg + '</p>');
            }
        });
    } catch (e) {
        console.error('2FA: Error in sendEmailCode function:', e);
        $status = jQuery('#email-status');
        if ($status.length) {
            $status.html('<p class="errmsg">Error sending email. Please refresh the page.</p>');
        }
    }
}

// Consolidated initialization system to prevent duplicate event handlers
(function() {
    'use strict';

    if (window.sn2faInitialized) {
        return;
    }

    function getSelectedMethod() {
        if (typeof two_factor_auth === 'undefined') {
            return 'app';
        }
        if (two_factor_auth.selected_method) {
            return two_factor_auth.selected_method;
        }
        if (two_factor_auth.allowed_methods && two_factor_auth.allowed_methods.length) {
            return two_factor_auth.allowed_methods[0];
        }
        return 'app';
    }

    window.sn2faGetSelectedMethod = getSelectedMethod;

    function setSelectedMethod(method) {
        if (typeof two_factor_auth !== 'undefined') {
            two_factor_auth.selected_method = method;
        }
    }

    function updateMethodPanels(method) {
        var $appPanel = jQuery('#sn-2fa-app-panel');
        var $emailPanel = jQuery('#sn-2fa-email-panel');
        var $label = jQuery('#twofa-code-label');

        jQuery('.sn-2fa-method-btn').removeClass('is-active');
        jQuery('.sn-2fa-method-btn[data-method="' + method + '"]').addClass('is-active');

        if ($appPanel.length) {
            $appPanel.toggle(method === 'app');
        }
        if ($emailPanel.length) {
            $emailPanel.toggle(method === 'email');
        }
        if ($label.length && typeof two_factor_auth !== 'undefined' && two_factor_auth.messages) {
            $label.text(method === 'email' ? two_factor_auth.messages.code_label_email : two_factor_auth.messages.code_label_app);
        }

        if (method === 'email' && $emailPanel.length && !window.sn2faEmailSent) {
            sendEmailCode();
        }
        if (method === 'app' && $appPanel.length && !two_factor_auth.has_app_secret) {
            generateQRCode();
        }
    }

    window.sn2faSetMethod = function(method) {
        setSelectedMethod(method);
        updateMethodPanels(method);
    };

    function attachEventHandlers() {
        try {
            var $form = jQuery('#twofa-form-verify');
            var $input = jQuery('#twofa-code');
            var $button = jQuery('#verify-2fa');

            // Input validation handler
            $input.on('input', function () {
                var inputValue = jQuery(this).val();

                // Remove any non-digit characters
                inputValue = inputValue.replace(/\D/g, '');

                // Limit to 6 digits
                inputValue = inputValue.slice(0, 6);

                // Update input value
                jQuery(this).val(inputValue);

                // Enable/disable submit button based on input validity
                $button.prop('disabled', inputValue.length !== 6);
            });

            // Form submission handler
            $form.on('submit', function (e) {
                e.preventDefault();

                try {
                    var twofacode = $input.val();
                    var $verifyMsg = jQuery('#twofa-verify-msg');

                    // Validate input
                    if (!twofacode || twofacode.length !== 6) {
                        if ($verifyMsg.length) {
                            $verifyMsg.html('<p class="errmsg">Please enter a valid 6-digit code.</p>');
                        }
                        return;
                    }

                    // Check if two_factor_auth object is available
                    if (typeof two_factor_auth === 'undefined' || !two_factor_auth.ajaxurl) {
                        console.error('2FA: Configuration not available for verification');
                        if ($verifyMsg.length) {
                            $verifyMsg.html('<p class="errmsg">Configuration error. Please refresh the page.</p>');
                        }
                        return;
                    }

                    var verifyingMsg = (two_factor_auth.messages && two_factor_auth.messages.verifying) ?
                        two_factor_auth.messages.verifying :
                        'Checking code...';
                    $verifyMsg.html('<p class="okmsg">' + verifyingMsg + '</p>');

                    $button.prop('disabled', true);
                    $input.prop('disabled', true);

                    jQuery.ajax({
                        url: two_factor_auth.ajaxurl,
                        type: 'POST',
                        data: {
                            action: 'secnin_verify_2fa_code',
                            code: twofacode,
                            nonce: two_factor_auth.verify_nonce || '',
                            temp_token: two_factor_auth.temp_token,
                            user_id: two_factor_auth.user_id || '',
                            user_ip: two_factor_auth.user_ip || '',
                            user_agent: two_factor_auth.user_agent || '',
                            method: getSelectedMethod()
                        },
                        timeout: 30000, // 30 second timeout
                        success: function (response) {
                            try {
                                if (response && response.success) {
                                    var successMsg = (response.data && response.data.message) ?
                                        response.data.message :
                                        'Code verified successfully.';
                                    $verifyMsg.html('<p class="okmsg">' + successMsg + '</p>');

                                    // Perform redirection after a short delay (admin_url fallback matches PHP JSON guard)
                                    var verifyTarget = (response.data && response.data.redir_to) || (typeof two_factor_auth !== 'undefined' && two_factor_auth.fallback_admin_url);
                                    if (verifyTarget) {
                                        setTimeout(function() {
                                            window.location.href = verifyTarget;
                                        }, 1000); // 1 second delay
                                    } else {
                                        setTimeout(function() {
                                            window.location.reload();
                                        }, 1000);
                                    }
                                } else {
                                    restoreUIState();
                                    var errorMsg = (response && response.data && response.data.message) ?
                                        response.data.message :
                                        'Invalid code. Please try again.';
                                    $verifyMsg.html('<p class="errmsg">' + errorMsg + '</p>');
                                }
                            } catch (e) {
                                console.error('2FA: Error processing verification response:', e);
                                restoreUIState();
                                $verifyMsg.html('<p class="errmsg">Error processing response. Please try again.</p>');
                            }
                        },
                        error: function (xhr, status, error) {
                            console.error('2FA: AJAX error verifying code:', status, error);
                            restoreUIState();
                            var errorMsg = (two_factor_auth.messages && two_factor_auth.messages.network_error) ?
                                two_factor_auth.messages.network_error :
                                'Network error. Please check your connection and try again.';
                            $verifyMsg.html('<p class="errmsg">' + errorMsg + '</p>');
                        }
                    });
                } catch (e) {
                    console.error('2FA: Error in form submission:', e);
                    restoreUIState();
                    $verifyMsg = jQuery('#twofa-verify-msg');
                    if ($verifyMsg.length) {
                        $verifyMsg.html('<p class="errmsg">Error processing request. Please try again.</p>');
                    }
                }
            });

            // Skip 2FA handler
            jQuery('.skip-2fa-link').on('click', function(e) {
                e.preventDefault();

                try {
                    // Check if two_factor_auth object is available
                    if (typeof two_factor_auth === 'undefined' || !two_factor_auth.ajaxurl || !two_factor_auth.temp_token) {
                        SnDialog.alert({ message: 'Configuration error. Please refresh the page.' });
                        return;
                    }

                    // Disable all interactive elements
                    var $skipLink = jQuery('.skip-2fa-link');
                    var $verifyButton = jQuery('#verify-2fa');
                    var $generateQrButton = jQuery('#generate-qr');
                    var $sendEmailButton = jQuery('#send-email');
                    var $twofaInput = jQuery('#twofa-code');

                    $skipLink.css('opacity', '0.5').css('pointer-events', 'none');
                    $verifyButton.prop('disabled', true);
                    $generateQrButton.prop('disabled', true);
                    $sendEmailButton.prop('disabled', true);
                    $twofaInput.prop('disabled', true);

                    jQuery.ajax({
                        url: two_factor_auth.ajaxurl,
                        type: 'POST',
                        data: {
                            action: 'secnin_skip_2fa',
                            temp_token: two_factor_auth.temp_token
                        },
                        timeout: 30000, // 30 second timeout
                        success: function(response) {
                            try {
                                if (response && response.success) {
                                    var skipTarget = (response.data && response.data.redirect_url) || (two_factor_auth && two_factor_auth.fallback_admin_url);
                                    if (skipTarget) {
                                        window.location.href = skipTarget;
                                    } else {
                                        window.location.reload();
                                    }
                                } else {
                                    // Re-enable all interactive elements
                                    restoreUIState();
                                    $skipLink.css('opacity', '').css('pointer-events', '');
                                    var errorMsg = (response && response.data && response.data.message) ?
                                        response.data.message :
                                        (two_factor_auth.messages && two_factor_auth.messages.unknown_error) ?
                                        two_factor_auth.messages.unknown_error :
                                        'An error occurred. Please try again.';
                                    SnDialog.alert({ message: errorMsg });
                                }
                            } catch (e) {
                                console.error('2FA: Error processing skip response:', e);
                                // Re-enable all interactive elements
                                restoreUIState();
                                $skipLink.css('opacity', '').css('pointer-events', '');
                                SnDialog.alert({ message: 'Error processing response. Please try again.' });
                            }
                        },
                        error: function(xhr, status, error) {
                            console.error('2FA: AJAX error skipping 2FA:', status, error);
                            // Re-enable all interactive elements
                            restoreUIState();
                            $skipLink.css('opacity', '').css('pointer-events', '');
                            var errorMsg = (two_factor_auth.messages && two_factor_auth.messages.network_error) ?
                                two_factor_auth.messages.network_error :
                                'Network error. Please check your connection and try again.';
                            SnDialog.alert({ message: errorMsg });
                        }
                    });
                    } catch (e) {
                        console.error('2FA: Error in skip 2FA handler:', e);
                        SnDialog.alert({ message: 'Error processing request. Please try again.' });
                    }
                });

            // Generate QR button handler (with debouncing)
            jQuery('#generate-qr').on('click', function(e) {
                e.preventDefault();
                try {
                    debouncedGenerateQR();
                } catch (err) {
                    console.error('2FA: Error in generate QR click handler:', err);
                }
            });

            // Send Email button handler (with debouncing)
            jQuery('#send-email').on('click', function(e) {
                e.preventDefault();
                try {
                    window.sn2faEmailSent = true;
                    debouncedSendEmail();
                } catch (err) {
                    console.error('2FA: Error in send email click handler:', err);
                }
            });

            // Method switcher buttons
            jQuery('.sn-2fa-method-btn').on('click', function(e) {
                e.preventDefault();
                var method = jQuery(this).data('method');
                if (method && typeof window.sn2faSetMethod === 'function') {
                    window.sn2faSetMethod(method);
                }
            });

            // Copy Secret button handler (with modern clipboard API)
            jQuery('#copy-secret').on('click', function(e) {
                e.preventDefault();
                try {
                    var secretInput = document.getElementById('secret-key');
                    if (!secretInput) {
                        console.warn('2FA: Secret input element not found');
                        return;
                    }

                    // Use modern clipboard API first
                    if (navigator.clipboard && navigator.clipboard.writeText) {
                        navigator.clipboard.writeText(secretInput.value).then(function() {
                            showCopySuccess(jQuery(this));
                        }).catch(function() {
                            // Fallback to deprecated method
                            fallbackCopy(secretInput, jQuery(this));
                        });
                    } else {
                        // Fallback for older browsers
                        fallbackCopy(secretInput, jQuery(this));
                    }
                } catch (err) {
                    console.error('2FA: Error in copy secret handler:', err);
                    SnDialog.alert({ message: 'Error copying secret. Please select and copy manually.' });
                }
            });

        } catch (e) {
            console.error('2FA: Error in attachEventHandlers:', e);
            restoreUIState();
        }
    }

    function init2FA() {
        try {
            // Check if jQuery is available
            if (typeof jQuery === 'undefined') {
                console.error('2FA: jQuery not available');
                return;
            }
            
            // Check if two_factor_auth object is available
            if (typeof two_factor_auth === 'undefined') {
                console.error('2FA: Configuration object not available');
                return;
            }
            
            // Check if required elements exist
            var $form = jQuery('#twofa-form-verify');
            var $input = jQuery('#twofa-code');
            var $button = jQuery('#verify-2fa');

            if (!$form.length || !$input.length || !$button.length) {
                console.warn('2FA: Required form elements not found');
                return;
            }
            
            // Mark as initialized immediately to prevent duplicates
            window.sn2faInitialized = true;

            var initialMethod = getSelectedMethod();
            setSelectedMethod(initialMethod);
            updateMethodPanels(initialMethod);

            if (!jQuery('.sn-2fa-method-switcher').length) {
                if (jQuery('.qr-code').length && initialMethod === 'app' && !two_factor_auth.has_app_secret) {
                    setTimeout(function() {
                        generateQRCode();
                    }, 100);
                }

                if (jQuery('.email-2fa').length && initialMethod === 'email') {
                    setTimeout(function() {
                        if (!window.sn2faEmailSent) {
                            sendEmailCode();
                        }
                    }, 1000);
                }
            }

            attachEventHandlers();
            
        } catch (e) {
            console.error('2FA: Error in initialization:', e);
            restoreUIState();
        }
    }
    
    // Single DOM ready handler
    jQuery(document).ready(function() {
        init2FA();
    });
    
})();

// Helper functions for copy functionality
function fallbackCopy(input, $button) {
    try {
        input.select();
        input.setSelectionRange(0, 99999);
        document.execCommand('copy');
        showCopySuccess($button);
    } catch (err) {
        SnDialog.alert({ message: 'Copy not supported. Please select and copy manually.' });
    }
}

function showCopySuccess($button) {
    var originalText = $button.text();
    $button.text('Copied!');
    setTimeout(function() {
        $button.text(originalText);
    }, 2000);
}
