/**
 * NMI Wallets JavaScript
 * Handles Apple Pay and Google Pay integration for WooCommerce
 */

(function($) {
    'use strict';

    // Global variables
    var nmi_info = {
        cart_total: 0
    };
    var nmi_configured = false; // Flag to prevent multiple configurations

    /**
     * Initialize NMI Wallets functionality
     */
    function initNMIWallets() {
        console.log('[nmi-wallets.js] initNMIWallets(): Starting initialization');
        
        // Check if we're on cart or checkout page
        if (typeof woocommerce_params === 'undefined') {
            console.log('[nmi-wallets.js] initNMIWallets(): woocommerce_params not available');
            return;
        }

        // Initialize checkout page functionality
        if ($('body').hasClass('woocommerce-checkout')) {
            console.log('[nmi-wallets.js] initNMIWallets(): Initializing checkout functionality');
            initCheckoutFunctionality();
        }

        // Initialize cart page functionality (only if on cart page)
        if ($('body').hasClass('woocommerce-cart')) {
            console.log('[nmi-wallets.js] initNMIWallets(): Initializing cart functionality');
            initCartFunctionality();
        }

        // Initialize wallet button functionality
        console.log('[nmi-wallets.js] initNMIWallets(): Initializing wallet buttons');
        initWalletButtons();
    }

    /**
     * Initialize checkout page functionality
     */
    function initCheckoutFunctionality() {
        console.log('[nmi-wallets.js] initCheckoutFunctionality(): Starting checkout initialization');
        
        // Get data from PHP data attributes
        var checkoutData = $('.nmi-checkout-data');
        if (checkoutData.length) {
            var price = parseFloat(checkoutData.data('price')) || 0;
            var shipping = checkoutData.data('shipping') || '{}';
            var page = checkoutData.data('page') || 'checkout';
            
            nmi_info.cart_total = price;
            console.log('[nmi-wallets.js] initCheckoutFunctionality(): Checkout data found:', { price: price, shipping: shipping, page: page });
        } else {
            // Fallback to WooCommerce data attributes or DOM parsing
            var price = getWooCommercePrice();
            nmi_info.cart_total = price;
            console.log('[nmi-wallets.js] initCheckoutFunctionality(): Using fallback price:', nmi_info.cart_total);
        }
        
        // Initialize CollectJS for checkout page
        if (nmi_info.cart_total > 0) {
            console.log('[nmi-wallets.js] initCheckoutFunctionality(): Triggering NMI Wallets with price:', nmi_info.cart_total);
            triggerNMIWallets(nmi_info.cart_total);
        }

        // Trigger when WooCommerce updates totals or shipping
        $(document.body).on("updated_cart_totals updated_checkout updated_shipping_method", function() {
            console.log('[nmi-wallets.js] initCheckoutFunctionality(): WooCommerce update event triggered');
            updateFormFields('checkout');
            updateShippingDataInForm();
        });

        // Additional shipping method change listeners for normal checkout
        $(document.body).on("change", "input[name='shipping_method[0]'], select[name='shipping_method[0]']", function() {
            console.log('[nmi-wallets.js] initCheckoutFunctionality(): Shipping method changed in normal checkout');
            
            // Wait for WooCommerce to update the shipping data before trying to extract it
            waitForWooCommerceShippingUpdate(function() {
                console.log('[nmi-wallets.js] initCheckoutFunctionality(): WooCommerce shipping update detected, now updating form fields');
                
                // Function to retry shipping data update
                function retryShippingUpdate(attempts) {
                    if (attempts <= 0) {
                        console.log('[nmi-wallets.js] initCheckoutFunctionality(): Max retry attempts reached for shipping update');
                        return;
                    }
                    
                        console.log('[nmi-wallets.js] initCheckoutFunctionality(): Retrying shipping data update, attempt:', 4 - attempts);
                        
                        // Try to update shipping data
                        updateFormFields('checkout');
                        updateShippingDataInForm();
                        
                        // Check if shipping data was successfully extracted
                        var form = $("#nmi_wallets_form");
                        if (form.length) {
                            var shippingInput = form.find('input[name="nmi_shipping"]');
                            if (shippingInput.length) {
                                var shippingValue = shippingInput.val();
                                try {
                                    var shippingData = JSON.parse(shippingValue);
                                    if (shippingData && shippingData.cost && shippingData.cost > 0) {
                                        console.log('[nmi-wallets.js] initCheckoutFunctionality(): Shipping data successfully updated:', shippingData);
                                        return; // Success, stop retrying
                                    }
                                } catch (e) {
                                    console.log('[nmi-wallets.js] initCheckoutFunctionality(): Error parsing shipping data:', e);
                                }
                            }
                        }
                        
                        // If we still don't have shipping data, retry
                        if (attempts > 1) {
                            retryShippingUpdate(attempts - 1);
                        }
                }
                
                // Start with 3 retry attempts
                retryShippingUpdate(3);
            });
        });
        
        // Manual field changes (cart only)
        $("#calc_shipping_country, #calc_shipping_state, #calc_shipping_city, #calc_shipping_postcode").on("change", function() {
            console.log('[nmi-wallets.js] initCheckoutFunctionality(): Manual field change detected');
            updateFormFields('checkout');
        });

        // Initial load
        console.log('[nmi-wallets.js] initCheckoutFunctionality(): Initial form fields update');
        updateFormFields('checkout');
    }

    /**
     * Initialize cart page functionality
     */
    function initCartFunctionality() {
        console.log('[nmi-wallets.js] initCartFunctionality(): Starting cart initialization');
        
        // Get data from PHP data attributes
        var cartData = $('.nmi-cart-data');
        var price = 0;
        
        if (cartData.length) {
            price = parseFloat(cartData.data('price')) || 0;
            var shipping = cartData.data('shipping') || '{}';
            var page = cartData.data('page') || 'cart';
            console.log('[nmi-wallets.js] initCartFunctionality(): Cart data found:', { price: price, shipping: shipping, page: page });
        } else {
            // Fallback to WooCommerce data attributes or DOM parsing
            price = getWooCommercePrice();
            console.log('[nmi-wallets.js] initCartFunctionality(): Using fallback price:', price);
        }

        // Trigger when WooCommerce updates totals or shipping
        $(document.body).on("updated_cart_totals updated_checkout updated_shipping_method", function() {
            console.log('[nmi-wallets.js] initCartFunctionality(): WooCommerce update event triggered');
            updateFormFields('cart');
        });

        // Manual field changes (cart only)
        $("#calc_shipping_country, #calc_shipping_state, #calc_shipping_city, #calc_shipping_postcode").on("change", function() {
            console.log('[nmi-wallets.js] initCartFunctionality(): Manual field change detected');
            updateFormFields('cart');
        });
        
        // Initial load
        console.log('[nmi-wallets.js] initCartFunctionality(): Initial form fields update');
        updateFormFields('cart');

        // Initialize CollectJS configuration
        document.addEventListener("DOMContentLoaded", function () {
            console.log('[nmi-wallets.js] initCartFunctionality(): DOMContentLoaded triggered, calling triggerNMIWallets with price:', price);
            triggerNMIWallets(price);
        });
    }

    /**
     * Trigger NMI Wallets configuration
     */
    function triggerNMIWallets(price) {
        console.log('[nmi-wallets.js] triggerNMIWallets(): Starting with price:', price);

        // Check if CollectJS is available
        if (typeof CollectJS === 'undefined') {
            console.log('[nmi-wallets.js] triggerNMIWallets(): CollectJS not available');
            return;
        }
        
        // Check if CollectJS is properly loaded and has the configure method
        if (typeof CollectJS.configure !== 'function') {
            console.log('[nmi-wallets.js] triggerNMIWallets(): CollectJS.configure method not available');
            return;
        }

        // Validate price
        if (!price || price <= 0) {
            console.log('[nmi-wallets.js] triggerNMIWallets(): Invalid price:', price);
            return;
        }
                
        // Get configuration from global variables with better validation
        var currency = 'USD';
        var country = 'US';
        var appleButtonType = 'plain';
        
        // Check if nmi_wallets_params exists and has the required values
        if (typeof window.nmi_wallets_params !== 'undefined' && window.nmi_wallets_params) {
            if (window.nmi_wallets_params.currency && window.nmi_wallets_params.currency !== '') {
                currency = window.nmi_wallets_params.currency;
            }
            if (window.nmi_wallets_params.country && window.nmi_wallets_params.country !== '') {
                country = window.nmi_wallets_params.country;
            }
            if (window.nmi_wallets_params.apple_button_type && window.nmi_wallets_params.apple_button_type !== '') {
                appleButtonType = window.nmi_wallets_params.apple_button_type;
            }
        }
        
        // If we're on block checkout, try to get currency and country from the page
        if (window.isBlockCheckout) {
            var blockCurrency = getBlockCheckoutCurrency();
            var blockCountry = getBlockCheckoutCountry();
            
            if (blockCurrency && blockCurrency !== 'USD') {
                currency = blockCurrency;
            }
            
            if (blockCountry && blockCountry !== 'US') {
                country = blockCountry;
            }
        }
        
        // Ensure price is a string for Google Pay compatibility
        var priceString = price.toString();
        
        // Validate required parameters with more detailed logging
        if (!currency || currency === '') {
            console.error('[nmi-wallets.js] triggerNMIWallets(): Currency is required for Collect.js. Current value:', currency);
            return;
        }
        
        if (!country || country === '') {
            console.error('[nmi-wallets.js] triggerNMIWallets(): Country is required for Collect.js. Current value:', country);
            return;
        }
        
        if (!priceString || priceString === '0' || priceString === '0.00') {
            console.error('[nmi-wallets.js] triggerNMIWallets(): Valid price is required for Collect.js. Current value:', priceString);
            return;
        }
        
        console.log('[nmi-wallets.js] triggerNMIWallets(): CollectJS Configuration:', {
            price: priceString,
            currency: currency,
            country: country,
            appleButtonType: appleButtonType
        });
        
        // Debug nmi_wallets_params
        console.log('[nmi-wallets.js] triggerNMIWallets(): nmi_wallets_params debug:', {
            exists: typeof window.nmi_wallets_params !== 'undefined',
            currency: window.nmi_wallets_params ? window.nmi_wallets_params.currency : 'undefined',
            country: window.nmi_wallets_params ? window.nmi_wallets_params.country : 'undefined',
            apple_button_type: window.nmi_wallets_params ? window.nmi_wallets_params.apple_button_type : 'undefined'
        });
        
        // Check for wallet buttons and log their presence
        var googlePayButton = $('#googlepaybutton');
        var applePayButton = $('#applepaybutton');
        
        if (googlePayButton.length) {
            console.log('[nmi-wallets.js] triggerNMIWallets(): Google Pay button found');
        } else {
            console.log('[nmi-wallets.js] triggerNMIWallets(): Google Pay button not found');
        }
        
        if (applePayButton.length) {
            console.log('[nmi-wallets.js] triggerNMIWallets(): Apple Pay button found');
        } else {
            console.log('[nmi-wallets.js] triggerNMIWallets(): Apple Pay button not found');
        }

        // Prevent multiple configurations
        if (nmi_configured) {
            console.log('[nmi-wallets.js] triggerNMIWallets(): CollectJS already configured, updating');
            //return;
        }
        
        // Add a small delay to ensure DOM is fully loaded
        setTimeout(function() {
            // Re-check if buttons exist after delay
            var googlePayButton = $('#googlepaybutton');
            var applePayButton = $('#applepaybutton');
            
            if (!googlePayButton.length && !applePayButton.length) {
                console.log('[nmi-wallets.js] triggerNMIWallets(): No wallet buttons found after delay, skipping configuration');
                return;
            }
            
            // Update fields object with current button state
            var fields = {};
            if (googlePayButton.length) {
                fields.googlePay = {
                    "selector": "#googlepaybutton",
                    "shippingAddressRequired": true,
                    "shippingAddressParameters": {
                        "phoneNumberRequired": true,
                    },
                    "billingAddressRequired": true,
                    "billingAddressParameters": {
                        "phoneNumberRequired": true,
                        "format": "FULL"
                    },
                    "emailRequired": true,
                    "buttonType": "checkout",
                };

            }
            
            if (applePayButton.length) {
                fields.applePay = {
                    "selector": "#applepaybutton",
                    "requiredBillingContactFields": [
                        "postalAddress",
                        "name"
                    ],
                    "requiredShippingContactFields": [
                        "postalAddress",
                        "name"
                    ],
                    "contactFields": [
                        "phone",
                        "email"
                    ],
                    "contactFieldsMappedTo": "billing",
                    "type": appleButtonType,
                    "style": {
                        "height": "40px"
                    },
                };

            }
            
            // Proceed with configuration
            configureCollectJS(fields, priceString, currency, country);
        }, 100);
        
        return;

    /**
     * Configure CollectJS with the given parameters
     */
    function configureCollectJS(fields, priceString, currency, country) {
        console.log('[nmi-wallets.js] configureCollectJS(): Starting configuration with fields:', Object.keys(fields));
        
        try {
            // Create configuration object with explicit parameter validation
            var config = {
                "variant": "inline",
                "fields": fields,
                "price": priceString,
                "currency": currency,
                "country": country,
                
                "timeoutDuration": 30000,
                "timeoutCallback": function () {
                    logError("Timed out");
                    console.log("[nmi-wallets.js] configureCollectJS(): Timed out");
                },
                "fieldsAvailableCallback": function () {
                    logError("fieldsAvailableCallback");
                    console.log("[nmi-wallets.js] configureCollectJS(): fieldsAvailableCallback");
                },
                "callback": function(response) {
                    handlePaymentResponse(response);
                }
            };
            
            // Log the final configuration before calling CollectJS
            console.log('[nmi-wallets.js] configureCollectJS(): Final CollectJS configuration:', config);
            
            CollectJS.configure(config);
            
            nmi_configured = true;
            console.log('[nmi-wallets.js] configureCollectJS(): CollectJS configured successfully');

            
        } catch (error) {
            // Handle PaymentRequestAbstraction errors specifically
            if (error.message && (error.message.includes('PaymentRequestAbstraction') || 
                error.message.includes('Could not create PaymentRequestAbstraction'))) {
                console.warn('[nmi-wallets.js] configureCollectJS(): NMI Wallets: PaymentRequestAbstraction error caught and handled:', error.message);
                logError('NMI Wallets: PaymentRequestAbstraction error - ' + error.message);
            } else {
                console.error('[nmi-wallets.js] configureCollectJS(): Error configuring CollectJS:', error);
                logError('CollectJS configuration error: ' + error.message);
            }
        }
    }
    }

    /**
     * Handle payment response from CollectJS
     */
    function handlePaymentResponse(response) {
        console.log('[nmi-wallets.js] handlePaymentResponse(): Processing payment response');
        
        // Show loading overlay
        showLoadingOverlay();

        // Log response
        logError(JSON.stringify(response));

        // Validate and sanitize the response object
        var sanitizedResponse = sanitizePaymentResponse(response);

        // Check if the form exists
        if ($("#nmi_wallets_form").length) {
            console.log('[nmi-wallets.js] handlePaymentResponse(): Form found, submitting payment token');
            // Create a new hidden text field and append it to the form
            $("<input>").attr({
                type: "hidden",
                name: "nmipay_payment_token",
                value: JSON.stringify(sanitizedResponse)
            }).appendTo("#nmi_wallets_form");
            
            // Submit the form
            $("#nmi_wallets_form").submit();
        } else {
            console.log("[nmi-wallets.js] handlePaymentResponse(): Form with id nmi_wallets_form not found");
            hideLoadingOverlay();
        }
    }

    /**
     * Sanitize payment response to prevent XSS
     * 
     * @param {Object} response The payment response object
     * @return {Object} Sanitized response object
     */
    function sanitizePaymentResponse(response) {
        // Whitelist of allowed fields
        var allowedFields = {
            'token': true,
            'wallet': {
                'billingInfo': {
                    'firstName': true,
                    'lastName': true,
                    'address1': true,
                    'address2': true,
                    'city': true,
                    'state': true,
                    'postalCode': true,
                    'country': true,
                    'phone': true
                },
                'shippingInfo': {
                    'firstName': true,
                    'lastName': true,
                    'address1': true,
                    'address2': true,
                    'city': true,
                    'state': true,
                    'postalCode': true,
                    'country': true,
                    'phone': true
                },
                'email': true
            }
        };

        // Create a sanitized copy with only allowed fields
        var sanitized = {};
        
        if (response && typeof response === 'object') {
            // Copy token if present
            if (response.token && typeof response.token === 'string') {
                sanitized.token = response.token;
            }
            
            // Copy wallet info if present
            if (response.wallet && typeof response.wallet === 'object') {
                sanitized.wallet = {};
                
                // Copy email if present
                if (response.wallet.email && typeof response.wallet.email === 'string') {
                    sanitized.wallet.email = response.wallet.email;
                }
                
                // Copy billing info if present
                if (response.wallet.billingInfo && typeof response.wallet.billingInfo === 'object') {
                    sanitized.wallet.billingInfo = {};
                    var billingFields = ['firstName', 'lastName', 'address1', 'address2', 'city', 'state', 'postalCode', 'country', 'phone'];
                    billingFields.forEach(function(field) {
                        if (response.wallet.billingInfo[field] && typeof response.wallet.billingInfo[field] === 'string') {
                            sanitized.wallet.billingInfo[field] = response.wallet.billingInfo[field];
                        }
                    });
                }
                
                // Copy shipping info if present
                if (response.wallet.shippingInfo && typeof response.wallet.shippingInfo === 'object') {
                    sanitized.wallet.shippingInfo = {};
                    var shippingFields = ['firstName', 'lastName', 'address1', 'address2', 'city', 'state', 'postalCode', 'country', 'phone'];
                    shippingFields.forEach(function(field) {
                        if (response.wallet.shippingInfo[field] && typeof response.wallet.shippingInfo[field] === 'string') {
                            sanitized.wallet.shippingInfo[field] = response.wallet.shippingInfo[field];
                        }
                    });
                }
            }
        }
        
        return sanitized;
    }

    /**
     * Get WooCommerce price using robust methods
     * 
     * @return {number} The current price
     */
    function getWooCommercePrice() {
        console.log('[nmi-wallets.js] getWooCommercePrice(): Starting price extraction');
        
        // First try to get price from WooCommerce data attributes
        var price = 0;
        
        // Try to get from WooCommerce cart total data attribute
        var cartTotalElement = $('[data-cart-total]');
        if (cartTotalElement.length) {
            price = parseFloat(cartTotalElement.data('cart-total')) || 0;
            if (price > 0) {
                console.log('[nmi-wallets.js] getWooCommercePrice(): Found price from cart-total data attribute:', price);
                return price;
            }
        }
        
        // Try to get from WooCommerce order total data attribute
        var orderTotalElement = $('[data-order-total]');
        if (orderTotalElement.length) {
            price = parseFloat(orderTotalElement.data('order-total')) || 0;
            if (price > 0) {
                console.log('[nmi-wallets.js] getWooCommercePrice(): Found price from order-total data attribute:', price);
                return price;
            }
        }
        
        // Try to get price from block checkout
        if (window.isBlockCheckout) {
            price = getBlockCheckoutPrice();
            if (price > 0) {
                console.log('[nmi-wallets.js] getWooCommercePrice(): Found price from block checkout:', price);
                return price;
            }
        }
        
        // Fallback to DOM parsing with better regex
        var priceElement = $(".order-total .woocommerce-Price-amount, .cart_totals .order-total .amount").first();
        if (priceElement.length) {
            var priceText = priceElement.text().trim();
            // Use a more robust regex that handles various currency formats
            var priceMatch = priceText.match(/[\d,]+\.?\d*/);
            if (priceMatch) {
                price = parseFloat(priceMatch[0].replace(/,/g, '')) || 0;
                console.log('[nmi-wallets.js] getWooCommercePrice(): Found price from DOM parsing:', price);
            }
        }
        
        // If we're on cart page, also check for shipping total and calculate final price
        if ($('body').hasClass('woocommerce-cart')) {
            var shippingTotal = 0;
            var subtotal = 0;
            
            // Get shipping total
            var shippingElement = $(".shipping .woocommerce-Price-amount, .cart_totals .shipping .amount").first();
            if (shippingElement.length) {
                var shippingText = shippingElement.text().trim();
                var shippingMatch = shippingText.match(/[\d,]+\.?\d*/);
                if (shippingMatch) {
                    shippingTotal = parseFloat(shippingMatch[0].replace(/,/g, '')) || 0;
                }
            }
            
            // Get subtotal
            var subtotalElement = $(".cart-subtotal .woocommerce-Price-amount, .cart_totals .cart-subtotal .amount").first();
            if (subtotalElement.length) {
                var subtotalText = subtotalElement.text().trim();
                var subtotalMatch = subtotalText.match(/[\d,]+\.?\d*/);
                if (subtotalMatch) {
                    subtotal = parseFloat(subtotalMatch[0].replace(/,/g, '')) || 0;
                }
            }
            
            // Use the total that includes shipping
            if (price > subtotal) {
                console.log('[nmi-wallets.js] getWooCommercePrice(): Using total with shipping:', price);
            } else if (shippingTotal > 0 && subtotal > 0) {
                price = subtotal + shippingTotal;
                console.log('[nmi-wallets.js] getWooCommercePrice(): Calculated total with shipping:', price);
            }
        }
        
        console.log('[nmi-wallets.js] getWooCommercePrice(): Final price:', price);
        return price;
    }

    /**
     * Check if we're on block checkout page
     */
    function isBlockCheckout() {
        var isBlock = $('.wc-block-components-checkout-form').length > 0 || 
               $('.wp-block-woocommerce-checkout').length > 0 ||
               $('body').hasClass('woocommerce-block-theme') ||
               window.location.href.indexOf('block-checkout') !== -1;
        window.isBlockCheckout = isBlock;
        console.log('[nmi-wallets.js] isBlockCheckout(): Block checkout detected:', window.isBlockCheckout);
        
        return window.isBlockCheckout;
    }

    /**
     * Extract pricing information from block checkout
     */
    function getBlockCheckoutPrice() {
        console.log('[nmi-wallets.js] getBlockCheckoutPrice(): Extracting price from block checkout');
        
        var price = 0;
        
        // First try the most specific selector for the total based on the provided HTML structure
        var totalElement = $('.wc-block-components-totals-footer-item-tax-value').first();
        if (totalElement.length) {
            var priceText = totalElement.text().trim();
            console.log('[nmi-wallets.js] getBlockCheckoutPrice(): Found total element with specific selector:', priceText);
            
            // Extract numeric value from price text
            var priceMatch = priceText.match(/[\d,]+\.?\d*/);
            if (priceMatch) {
                price = parseFloat(priceMatch[0].replace(/,/g, '')) || 0;
                if (price > 0) {
                    console.log('[nmi-wallets.js] getBlockCheckoutPrice(): Extracted price from specific total selector:', price);
                    return price;
                }
            }
        }
        
        // Try multiple selectors for block checkout total as fallback
        var totalSelectors = [
            '.wc-block-components-totals-footer-item-tax-value',
            '.wc-block-components-totals-footer-item .wc-block-components-formatted-money-amount',
            '.wc-block-components-totals-item__value .wc-block-components-formatted-money-amount',
            '.wc-block-components-order-summary-item__total .wc-block-components-order-summary-item__individual-prices',
            '.wc-block-components-order-summary-item__total .wc-block-components-formatted-money-amount',
            '.wc-block-components-order-summary-item__total .wc-block-components-price',
            '.wc-block-components-order-summary-item__total',
            '.wc-block-components-order-summary__total .wc-block-components-formatted-money-amount',
            '.wc-block-components-order-summary__total .wc-block-components-price',
            '.wc-block-components-order-summary__total',
            '[data-testid="order-summary-total"] .wc-block-components-formatted-money-amount',
            '[data-testid="order-summary-total"] .wc-block-components-price',
            '[data-testid="order-summary-total"]'
        ];
        
        for (var i = 0; i < totalSelectors.length; i++) {
            var element = $(totalSelectors[i]);
            if (element.length) {
                var priceText = element.text().trim();
                console.log('[nmi-wallets.js] getBlockCheckoutPrice(): Found price element:', totalSelectors[i], 'Text:', priceText);
                
                // Extract numeric value from price text
                var priceMatch = priceText.match(/[\d,]+\.?\d*/);
                if (priceMatch) {
                    price = parseFloat(priceMatch[0].replace(/,/g, '')) || 0;
                    if (price > 0) {
                        console.log('[nmi-wallets.js] getBlockCheckoutPrice(): Extracted price from block checkout:', price);
                        return price;
                    }
                }
            }
        }
        
        // If direct total not found, try to calculate from components
        if (price === 0) {
            console.log('[nmi-wallets.js] getBlockCheckoutPrice(): No direct total found, calculating from components');
            price = calculateBlockCheckoutTotal();
        }
        
        console.log('[nmi-wallets.js] getBlockCheckoutPrice(): Final price:', price);
        return price;
    }

    /**
     * Calculate total from block checkout components
     */
    function calculateBlockCheckoutTotal() {
        console.log('[nmi-wallets.js] calculateBlockCheckoutTotal(): Calculating total from block checkout components');
        
        var subtotal = 0;
        var shipping = 0;
        var taxes = 0;
        var discounts = 0;
        
        // Get subtotal - try to find the subtotal specifically
        var subtotalElement = $('.wc-block-components-totals-item').filter(function() {
            return $(this).find('.wc-block-components-totals-item__label').text().trim().toLowerCase() === 'subtotal';
        }).find('.wc-block-components-totals-item__value .wc-block-components-formatted-money-amount');
        
        if (subtotalElement.length) {
            var subtotalText = subtotalElement.text().trim();
            var subtotalMatch = subtotalText.match(/[\d,]+\.?\d*/);
            if (subtotalMatch) {
                subtotal = parseFloat(subtotalMatch[0].replace(/,/g, '')) || 0;
                console.log('[nmi-wallets.js] calculateBlockCheckoutTotal(): Found subtotal from specific selector:', subtotal);
            }
        }
        
        // Fallback to general selectors if specific selector didn't work
        if (subtotal === 0) {
            var subtotalSelectors = [
                '.wc-block-components-totals-item__value .wc-block-components-formatted-money-amount',
                '.wc-block-components-order-summary-item__subtotal .wc-block-components-formatted-money-amount',
                '.wc-block-components-order-summary-item__subtotal .wc-block-components-price',
                '.wc-block-components-order-summary-item__subtotal'
            ];
            
            for (var i = 0; i < subtotalSelectors.length; i++) {
                var element = $(subtotalSelectors[i]);
                if (element.length) {
                    var text = element.text().trim();
                    var match = text.match(/[\d,]+\.?\d*/);
                    if (match) {
                        subtotal = parseFloat(match[0].replace(/,/g, '')) || 0;
                        console.log('[nmi-wallets.js] calculateBlockCheckoutTotal(): Found subtotal from fallback selector:', subtotal);
                        break;
                    }
                }
            }
        }
        
        // Get shipping - try to find the shipping/delivery specifically
        var shippingElement = $('.wc-block-components-totals-item').filter(function() {
            var label = $(this).find('.wc-block-components-totals-item__label').text().trim().toLowerCase();
            return label === 'delivery' || label === 'shipping';
        }).find('.wc-block-components-totals-item__value .wc-block-components-formatted-money-amount');
        
        if (shippingElement.length) {
            var shippingText = shippingElement.text().trim();
            var shippingMatch = shippingText.match(/[\d,]+\.?\d*/);
            if (shippingMatch) {
                shipping = parseFloat(shippingMatch[0].replace(/,/g, '')) || 0;
                console.log('[nmi-wallets.js] calculateBlockCheckoutTotal(): Found shipping from specific selector:', shipping);
            }
        }
        
        // Fallback to general selectors if specific selector didn't work
        if (shipping === 0) {
            var shippingSelectors = [
                '.wc-block-components-totals-item__value .wc-block-components-formatted-money-amount',
                '.wc-block-components-order-summary-item__shipping .wc-block-components-formatted-money-amount',
                '.wc-block-components-order-summary-item__shipping .wc-block-components-price',
                '.wc-block-components-order-summary-item__shipping',
                '.wc-block-components-order-summary-item__delivery .wc-block-components-formatted-money-amount',
                '.wc-block-components-order-summary-item__delivery .wc-block-components-price',
                '.wc-block-components-order-summary-item__delivery'
            ];
            
            for (var i = 0; i < shippingSelectors.length; i++) {
                var element = $(shippingSelectors[i]);
                if (element.length) {
                    var text = element.text().trim();
                    var match = text.match(/[\d,]+\.?\d*/);
                    if (match) {
                        shipping = parseFloat(match[0].replace(/,/g, '')) || 0;
                        console.log('[nmi-wallets.js] calculateBlockCheckoutTotal(): Found shipping from fallback selector:', shipping);
                        break;
                    }
                }
            }
        }
        
        // Get taxes
        var taxSelectors = [
            '.wc-block-components-order-summary-item__tax .wc-block-components-formatted-money-amount',
            '.wc-block-components-order-summary-item__tax .wc-block-components-price',
            '.wc-block-components-order-summary-item__tax'
        ];
        
        for (var i = 0; i < taxSelectors.length; i++) {
            var element = $(taxSelectors[i]);
            if (element.length) {
                var text = element.text().trim();
                var match = text.match(/[\d,]+\.?\d*/);
                if (match) {
                    taxes = parseFloat(match[0].replace(/,/g, '')) || 0;
                    break;
                }
            }
        }
        
        // Get discounts
        var discountSelectors = [
            '.wc-block-components-order-summary-item__discount .wc-block-components-formatted-money-amount',
            '.wc-block-components-order-summary-item__discount .wc-block-components-price',
            '.wc-block-components-order-summary-item__discount'
        ];
        
        for (var i = 0; i < discountSelectors.length; i++) {
            var element = $(discountSelectors[i]);
            if (element.length) {
                var text = element.text().trim();
                var match = text.match(/[\d,]+\.?\d*/);
                if (match) {
                    discounts = parseFloat(match[0].replace(/,/g, '')) || 0;
                    break;
                }
            }
        }
        
        var total = subtotal + shipping + taxes - discounts;
        console.log('[nmi-wallets.js] calculateBlockCheckoutTotal(): Calculated block checkout total:', {
            subtotal: subtotal,
            shipping: shipping,
            taxes: taxes,
            discounts: discounts,
            total: total
        });
        
        return total;
    }

    /**
     * Extract country from block checkout
     */
    function getBlockCheckoutCountry() {
        console.log('[nmi-wallets.js] getBlockCheckoutCountry(): Extracting country from block checkout');
        
        var country = '';
        
        // Try to get country from billing address fields
        var countrySelectors = [
            'select[name="billing_country"]',
            'input[name="billing_country"]',
            '[data-testid="billing-country"]',
            '.wc-block-components-address-form__country select',
            '.wc-block-components-address-form__country input'
        ];
        
        for (var i = 0; i < countrySelectors.length; i++) {
            var element = $(countrySelectors[i]);
            if (element.length) {
                country = element.val();
                if (country && country !== '') {
                    console.log('[nmi-wallets.js] getBlockCheckoutCountry(): Found country from block checkout:', country);
                    return country;
                }
            }
        }
        
        // Try to get from shipping address if billing not found
        var shippingCountrySelectors = [
            'select[name="shipping_country"]',
            'input[name="shipping_country"]',
            '[data-testid="shipping-country"]'
        ];
        
        for (var i = 0; i < shippingCountrySelectors.length; i++) {
            var element = $(shippingCountrySelectors[i]);
            if (element.length) {
                country = element.val();
                if (country && country !== '') {
                    console.log('[nmi-wallets.js] getBlockCheckoutCountry(): Found shipping country from block checkout:', country);
                    return country;
                }
            }
        }
        
        // Fallback to default country
        console.log('[nmi-wallets.js] getBlockCheckoutCountry(): No country found in block checkout, using default');
        return 'US';
    }

    /**
     * Extract shipping data from block checkout
     */
    function extractBlockCheckoutShippingData() {
        console.log('Extracting shipping data from block checkout');
        
        var shippingData = {
            method: '',
            cost: 0,
            method_id: '',
            method_title: ''
        };
        
        // Try to find shipping method information
        var shippingElements = $('.wc-block-components-totals-item');
        for (var i = 0; i < shippingElements.length; i++) {
            var element = $(shippingElements[i]);
            var labelElement = element.find('.wc-block-components-totals-item__label');
            
            if (labelElement.length) {
                var label = labelElement.text().trim().toLowerCase();
                if (label === 'delivery' || label === 'shipping') {
                    // Get shipping method name
                    var methodElement = element.find('.wc-block-components-totals-shipping__via');
                    if (methodElement.length) {
                        shippingData.method_title = methodElement.text().trim();
                        shippingData.method = methodElement.text().trim();
                    }
                    
                    // Get shipping cost
                    var valueElement = element.find('.wc-block-components-totals-item__value .wc-block-components-formatted-money-amount');
                    if (valueElement.length) {
                        var costText = valueElement.text().trim();
                        var costMatch = costText.match(/[\d,]+\.?\d*/);
                        if (costMatch) {
                            shippingData.cost = parseFloat(costMatch[0].replace(/,/g, '')) || 0;
                        }
                    }
                    
                    // Try to get method ID from data attributes or other sources
                    var methodId = element.data('method-id') || element.attr('data-method-id');
                    if (methodId) {
                        shippingData.method_id = methodId;
                    }
                    
                    break;
                }
            }
        }
        
        // If we found shipping data, return it as JSON string
        if (shippingData.method || shippingData.cost > 0) {
            console.log('Extracted shipping data from block checkout:', shippingData);
            return JSON.stringify(shippingData);
        }
        
        // Fallback: try to get shipping data from WooCommerce data
        if (typeof wc_checkout_params !== 'undefined' && wc_checkout_params.shipping_methods) {
            try {
                var wcShipping = JSON.parse(wc_checkout_params.shipping_methods);
                if (wcShipping && wcShipping.length > 0) {
                    var selectedShipping = wcShipping.find(function(method) {
                        return method.selected === true;
                    });
                    if (selectedShipping) {
                        shippingData.method = selectedShipping.method_title || selectedShipping.method_id;
                        shippingData.method_title = selectedShipping.method_title || selectedShipping.method_id;
                        shippingData.method_id = selectedShipping.method_id;
                        shippingData.cost = parseFloat(selectedShipping.cost) || 0;
                        console.log('Extracted shipping data from WooCommerce params:', shippingData);
                        return JSON.stringify(shippingData);
                    }
                }
            } catch (e) {
                console.log('Error parsing WooCommerce shipping data:', e);
            }
        }
        
        // If no shipping data found, return empty object
        console.log('No shipping data found in block checkout');
        return JSON.stringify(shippingData);
    }

    /**
     * Extract currency from block checkout
     */
    function getBlockCheckoutCurrency() {
        console.log('[nmi-wallets.js] getBlockCheckoutCurrency(): Extracting currency from block checkout');
        
        // Try to get currency from price elements
        var priceElements = $('.wc-block-components-formatted-money-amount, .wc-block-components-price');
        if (priceElements.length > 0) {
            var priceText = priceElements.first().text().trim();
            
            // Look for currency symbols
            var currencyMap = {
                '$': 'USD',
                '€': 'EUR',
                '£': 'GBP',
            };
            
            for (var symbol in currencyMap) {
                if (priceText.indexOf(symbol) !== -1) {
                    console.log('[nmi-wallets.js] getBlockCheckoutCurrency(): Found currency from block checkout:', currencyMap[symbol]);
                    return currencyMap[symbol];
                }
            }
        }
        
        // Try to get from WooCommerce data
        if (typeof wc_checkout_params !== 'undefined' && wc_checkout_params.currency) {
            console.log('[nmi-wallets.js] getBlockCheckoutCurrency(): Found currency from WooCommerce params:', wc_checkout_params.currency);
            return wc_checkout_params.currency;
        }
        
        // Fallback to default currency
        console.log('[nmi-wallets.js] getBlockCheckoutCurrency(): No currency found in block checkout, using default');
        return 'USD';
    }

    /**
     * Shared updateFormFields function for both checkout and cart
     * 
     * @param {string} context The context ('checkout' or 'cart')
     */
    function updateFormFields(context) {
        console.log('[nmi-wallets.js] updateFormFields(): Updating form fields for context:', context);
        
        // Extract values from traditional checkout
        var country = $("#calc_shipping_country, #billing_country").val();
        var state = $("#calc_shipping_state, #billing_state").val();
        var city = $("#calc_shipping_city, #billing_city").val();
        var postcode = $("#calc_shipping_postcode, #billing_postcode").val();

        // If we're on block checkout, try to get values from block checkout
        if (window.isBlockCheckout) {
            if (!country || country === '') {
                country = getBlockCheckoutCountry();
            }
            
            // Try to get address fields from block checkout
            if (!state || state === '') {
                var blockStateField = document.querySelector('input[name*="state"]');
                if (blockStateField) {
                    state = blockStateField.value || '';
                }
            }
            
            if (!city || city === '') {
                var blockCityField = document.querySelector('input[name*="city"]');
                if (blockCityField) {
                    city = blockCityField.value || '';
                }
            }
            
            if (!postcode || postcode === '') {
                var blockPostcodeField = document.querySelector('input[name*="postcode"]');
                if (blockPostcodeField) {
                    postcode = blockPostcodeField.value || '';
                }
            }
        }

        // Extract total price using robust method
        var price = getWooCommercePrice();
        
        // If we're on block checkout, try to get price from block checkout
        if (window.isBlockCheckout) {
            var blockPrice = getBlockCheckoutPrice();
            if (blockPrice && blockPrice > 0) {
                price = blockPrice;
            }
        }

        nmi_info.cart_total = price;
        console.log('[nmi-wallets.js] updateFormFields(): Updated cart total:', nmi_info.cart_total);

        var form = $("#nmi_wallets_form");

        if (form.length) {
            // Get fresh shipping data based on current page type
            var freshShippingData = null;
            
            if (window.isBlockCheckout) {
                // For block checkout, extract shipping data from the page
                freshShippingData = extractBlockCheckoutShippingData();
            }
            // For normal checkout, we get shipping data from server via updateShippingDataInForm()
            
            console.log('[nmi-wallets.js] updateFormFields(): Fresh shipping data extracted:', freshShippingData);
            
            // Remove previous inputs (excluding shipping data which we've already preserved)
            form.find("input[name^='nmi_']").remove();

            // Append updated hidden inputs with proper escaping
            form.append($("<input>").attr({
                type: "hidden",
                name: "nmi_country",
                value: country || ""
            }));
            form.append($("<input>").attr({
                type: "hidden",
                name: "nmi_state",
                value: state || ""
            }));
            form.append($("<input>").attr({
                type: "hidden",
                name: "nmi_city",
                value: city || ""
            }));
            form.append($("<input>").attr({
                type: "hidden",
                name: "nmi_postcode",
                value: postcode || ""
            }));
            form.append($("<input>").attr({
                type: "hidden",
                name: "nmi_price",
                value: price || ""
            }));
            
            // Add fresh shipping data (only for block checkout)
            if (freshShippingData) {
                form.append($("<input>").attr({
                    type: "hidden",
                    name: "nmi_shipping",
                    value: freshShippingData
                }));
            }
            
            form.append($("<input>").attr({
                type: "hidden",
                name: "nmi_page",
                value: context
            }));
            
            console.log('[nmi-wallets.js] updateFormFields(): Form fields updated successfully');
        } else {
            console.log('[nmi-wallets.js] updateFormFields(): nmi_wallets_form not found');
        }

        // For cart context, also trigger NMI Wallets
        if (context === 'cart') {
            console.log('[nmi-wallets.js] updateFormFields(): Triggering NMI Wallets for cart context');
            triggerNMIWallets(parseFloat(price) || 0);
        }
    }

    /**
     * Wait for WooCommerce to update shipping data
     */
    function waitForWooCommerceShippingUpdate(callback, maxAttempts) {
        maxAttempts = maxAttempts || 10;
        var attempts = 0;
        
        function checkForUpdate() {
            attempts++;
            console.log('[nmi-wallets.js] waitForWooCommerceShippingUpdate(): Checking for WooCommerce shipping update, attempt:', attempts);
            
            // Check if WooCommerce has updated the shipping data
            var hasUpdated = false;
            
            // Check if shipping method is selected
            var shippingMethod = $('input[name="shipping_method[0]"]:checked, select[name="shipping_method[0]"] option:selected');
            if (shippingMethod.length) {
                var methodText = shippingMethod.text().trim();
                if (methodText && methodText.length > 0) {
                    console.log('[nmi-wallets.js] waitForWooCommerceShippingUpdate(): Found shipping method:', methodText);
                    hasUpdated = true;
                }
            }
            
            // Check if totals have been updated
            var totalsUpdated = $('.woocommerce-shipping-totals, .cart-subtotal + tr, .order-total').length > 0;
            if (totalsUpdated) {
                console.log('[nmi-wallets.js] waitForWooCommerceShippingUpdate(): Found shipping totals section');
                hasUpdated = true;
            }
            
            if (hasUpdated || attempts >= maxAttempts) {
                console.log('[nmi-wallets.js] waitForWooCommerceShippingUpdate(): WooCommerce shipping update check complete, calling callback');
                callback();
            } else {
                setTimeout(checkForUpdate, 500);
            }
        }
        
        checkForUpdate();
    }



    /**
     * Update shipping data specifically in the form for normal checkout
     */
    function updateShippingDataInForm() {
        console.log('[nmi-wallets.js] updateShippingDataInForm(): Updating shipping data in form for normal checkout');
        
        $.post(nmi_wallets_params.ajax_url, { 
            action: 'get_shipping_data_normal_checkout', 
            nonce: nmi_wallets_params.normal_checkout_nonce 
        }, function(response) {
            if (response.success) {
                console.log('[nmi-wallets.js] updateShippingDataInForm(): Updated shipping data:', response.data);
                
                var form = $("#nmi_wallets_form");
                if (form.length) {
                    var shippingData = JSON.stringify(response.data);
                    
                    // Update the nmi_shipping hidden input
                    var shippingInput = form.find('input[name="nmi_shipping"]');
                    if (shippingInput.length) {
                        shippingInput.val(shippingData);
                        console.log('[nmi-wallets.js] updateShippingDataInForm(): Updated nmi_shipping input with server data:', shippingData);
                    } else {
                        // If input doesn't exist, create it
                        form.append($("<input>").attr({
                            type: "hidden",
                            name: "nmi_shipping",
                            value: shippingData
                        }));
                        console.log('[nmi-wallets.js] updateShippingDataInForm(): Created new nmi_shipping input with server data:', shippingData);
                    }
                    
                    // Update the .nmi-checkout-data div
                    var checkoutDataDiv = $('.nmi-checkout-data');
                    if (checkoutDataDiv.length) {
                        checkoutDataDiv.attr('data-shipping', shippingData);
                        console.log('[nmi-wallets.js] updateShippingDataInForm(): Updated data-shipping attribute with server data:', shippingData);
                    }
                }
                triggerNMIWallets(nmi_info.cart_total);
            } else {
                console.error('[nmi-wallets.js] updateShippingDataInForm(): Failed to get shipping data');
            }
        });
    }

    /**
     * Initialize wallet button functionality
     */
    function initWalletButtons() {
        console.log('[nmi-wallets.js] initWalletButtons(): Initializing wallet button functionality');
        
        // Handle express checkout parameter
        const urlParams = new URLSearchParams(window.location.search);
        if (urlParams.get('express_checkout') === '1') {
            console.log('[nmi-wallets.js] initWalletButtons(): Express checkout parameter detected');
            $('#ship-to-different-address-checkbox').prop('checked', true);
        }

        // Handle wallet button clicks
        $("#applepaybutton").click(function(){
            console.log('[nmi-wallets.js] initWalletButtons(): Apple Pay button clicked');
            $('#terms').prop('checked', true);
        });
        
        $("#googlepaybutton").click(function(){
            console.log('[nmi-wallets.js] initWalletButtons(): Google Pay button clicked');
            $('#terms').prop('checked', true);
        });
    }

    /**
     * Show loading overlay
     */
    function showLoadingOverlay() {
        console.log('[nmi-wallets.js] showLoadingOverlay(): Showing loading overlay');
        
        // Remove any existing overlay first
        $('#nmi-loading-overlay').remove();
        
        // Create overlay with inline styles to ensure it works
        var overlay = $('<div id="nmi-loading-overlay" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); z-index: 999999; display: flex; align-items: center; justify-content: center;">');
        var content = $('<div style="background: white; padding: 20px; border-radius: 8px; text-align: center; max-width: 400px; margin: 1rem; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);">');
        var spinner = $('<div style="width: 40px; height: 40px; border: 4px solid #f3f3f3; border-top: 4px solid #007cba; border-radius: 50%; animation: spin 1s linear infinite; margin: 0 auto 10px;">');
        var text = $('<p style="margin: 0; font-size: 1.1rem; color: #333; font-weight: 500;">Please wait while your order is being processed.</p>');
        
        // Add spinner animation
        $('<style>@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }</style>').appendTo('head');
        
        content.append(spinner).append(text);
        overlay.append(content);
        $('body').append(overlay);
    }

    /**
     * Hide loading overlay
     */
    function hideLoadingOverlay() {
        console.log('[nmi-wallets.js] hideLoadingOverlay(): Hiding loading overlay');
        $('#nmi-loading-overlay').remove();
    }

    /**
     * Log error to server
     */
    function logError(error) {
        console.log('[nmi-wallets.js] logError(): Logging error to server:', error);
        
        if (typeof nmi_wallets_params !== 'undefined' && nmi_wallets_params.ajax_url) {
            $.ajax({
                type: "POST",
                url: nmi_wallets_params.ajax_url,
                data: {
                    action: "log_nmi_wallets_ajax_errors",
                    error: error,
                    nonce: nmi_wallets_params.log_errors_nonce
                },
                success: function(response) {
                    console.log('[nmi-wallets.js] logError(): Error logged successfully:', response);
                },
                error: function(error) {
                    console.log('[nmi-wallets.js] logError(): Failed to log error:', error);
                }
            });
        } else {
            console.log('[nmi-wallets.js] logError(): nmi_wallets_params not available, cannot log error');
        }
    }

    // Initialize when document is ready
    $(document).ready(function() {
        initNMIWallets();
    });

    // Make functions globally available for backward compatibility
    window.triggerNMIWallets = triggerNMIWallets;
    window.nmi_info = nmi_info;
    window.isBlockCheckout = isBlockCheckout;

})(jQuery); 

