/* eslint-disable */
/**
 * ConvesioPay Unified Classic Checkout Integration
 * Handles ConvesioPay payments for WooCommerce classic checkout
 */

(function($) {
    'use strict';

    // Global ConvesioPay state
    let convesioPayComponent = null;
    let isComponentMounted = false;
    let paymentConfirmedData = null;
    let currentPaymentMethod = null;
    let btcPaySession = null;
    let isSessionCreated = false;
    let lastKnownCartTotal = 0;
    let lastAppliedFeeAmount = 0; // Track the last fee we applied for accurate total calculation
    let convesioPayInitialized = false; // Track if one-time initialization has been done
    let mountConvesioPayComponentAttempt = 0;
    let applePayAuthorizedAmount = null;
    let googlePayAuthorizedAmount = null;

    /**
     * Single source of truth for ConvesioPay transaction ID (client-generated, no API call).
     * Created once per page load and reused for the entire checkout session.
     * @returns {string} Transaction ID (e.g. convesio-tx-1739123456789-abc12def3)
     */
    function getOrCreateConvesioTransactionId() {
        if (window.peachpayTransactionId) {
            return window.peachpayTransactionId;
        }
        const id = 'convesio-tx-' + Date.now() + '-' + Math.random().toString(36).substring(2, 11);
        window.peachpayTransactionId = id;
        return id;
    }

    /**
     * Store the selected method in WC session via AJAX.
     * We do NOT trigger update_checkout to avoid component reload.
     * Total is updated client-side by reading current values and adjusting for fee change.
     * Server-side calculation happens at order placement.
     * 
     * @param {string} method - The selected payment method (card, applepay, btcpay)
     */
    function storeMethodInSessionAndUpdateTotals(method) {
        // Get AJAX URL
        const ajaxUrl = window.peachpay_convesiopay_unified_data?.ajax_url || 
                       window.wc_checkout_params?.ajax_url || 
                       '/wp-admin/admin-ajax.php';

        // Keep hidden field in sync for final checkout submit payload.
        const methodField = document.getElementById('convesiopay_selected_method');
        if (methodField && methodField.value !== method) {
            methodField.value = method;
        }
        
        // Store method in session via AJAX (for server-side calculation at order placement)
        const formData = new FormData();
        formData.append('action', 'peachpay_store_convesiopay_method');
        formData.append('convesiopay_selected_method', method);
        
        return fetch(ajaxUrl, {
            method: 'POST',
            credentials: 'same-origin',
            body: formData
        })
        .then((response) => response.json())
        .then((payload) => {
            console.log('[ConvesioPay] Session method sync response:', payload);
            return true;
        })
        .catch(() => {
            // Silently handle error - fee display already updated client-side
            console.warn('[ConvesioPay] Session method sync failed');
            return false;
        });
    }

    /**
     * Returns true if the error indicates createApplePaySession API is not ready yet (race on slow connections or after update_checkout).
     */
    function isApplePaySessionNotReadyError(err) {
        var msg = (err && err.message) ? String(err.message) : '';
        return msg.indexOf('not initialized') !== -1 || msg.indexOf('not available') !== -1 || msg.indexOf('createApplePaySession') !== -1;
    }

    /**
     * Call component.createApplePaySession with retries. Handles "api.createApplePaySession is not initialized" on slow connections or after update_checkout.
     * @param {Object} component - ConvesioPay component (must have createApplePaySession)
     * @param {Object} params - Session params (integration, returnUrl, amount, currency, email, name)
     * @param {Object} options - { maxAttempts: number, delayMs: number }
     * @returns {Promise} Resolves with session result or undefined; rejects only after all retries fail with a non-retryable error.
     */
    function createApplePaySessionWithRetry(component, params, options) {
        options = options || {};
        var maxAttempts = options.maxAttempts || 3;
        var delayMs = options.delayMs || 600;
        var attempt = 0;

        function run() {
            attempt++;
            if (!component || typeof component.createApplePaySession !== 'function') {
                if (attempt < maxAttempts) {
                    return new Promise(function(resolve) { setTimeout(resolve, delayMs); }).then(run);
                }
                return Promise.resolve();
            }
            return Promise.resolve(component.createApplePaySession(params)).catch(function(err) {
                if (isApplePaySessionNotReadyError(err) && attempt < maxAttempts) {
                    return new Promise(function(resolve) { setTimeout(resolve, delayMs); }).then(run);
                }
                throw err;
            });
        }
        return run();
    }

    /**
     * Call component.createGooglePaySession with retries.
     * @param {Object} component - ConvesioPay component
     * @param {Object} params - Session params
     * @param {Object} options - { maxAttempts: number, delayMs: number }
     * @returns {Promise}
     */
    function createGooglePaySessionWithRetry(component, params, options) {
        options = options || {};
        var maxAttempts = options.maxAttempts || 3;
        var delayMs = options.delayMs || 600;
        var attempt = 0;

        function run() {
            attempt++;
            if (!component || typeof component.createGooglePaySession !== 'function') {
                if (attempt < maxAttempts) {
                    return new Promise(function(resolve) { setTimeout(resolve, delayMs); }).then(run);
                }
                return Promise.resolve();
            }
            return Promise.resolve(component.createGooglePaySession(params)).catch(function(err) {
                if (attempt < maxAttempts) {
                    return new Promise(function(resolve) { setTimeout(resolve, delayMs); }).then(run);
                }
                throw err;
            });
        }
        return run();
    }

    /**
     * Bind click handlers to accordion/tab containers for immediate fee updates.
     * Uses event delegation to catch clicks on dynamically rendered elements.
     */
    function bindAccordionFeeUpdates() {
        const container = document.getElementById('convesiopay-unified-payment-container');
        if (!container) {
            return;
        }
        
        // Avoid binding multiple times
        if (container.dataset.feeBindingAdded) return;
        container.dataset.feeBindingAdded = 'true';
        
        /**
         * Safely get className as string (handles SVG elements which have SVGAnimatedString)
         */
        function getClassName(element) {
            if (!element) return '';
            const cn = element.className;
            if (typeof cn === 'string') return cn;
            if (cn && typeof cn.baseVal === 'string') return cn.baseVal; // SVGAnimatedString
            return '';
        }
        
        /**
         * Check if an element is within an accordion header
         */
        function isWithinAccordionHeader(element) {
            let current = element;
            let depth = 0;
            const maxDepth = 10;
            
            while (current && depth < maxDepth) {
                const className = getClassName(current);
                // Check for accordion-header class
                if (className.includes('accordion-header')) {
                    return true;
                }
                current = current.parentElement;
                depth++;
            }
            return false;
        }
        
        /**
         * Find payment method from accordion-header element by checking its parent accordion-item
         * and the text content of the header. This is more reliable than checking the clicked element.
         */
        function detectPaymentMethodFromAccordionHeaderMain(accordionHeader) {
            if (!accordionHeader) return null;
            
            // Method 1: Check the parent accordion-item for payment method classes
            const accordionItem = accordionHeader.closest('.accordion-item');
            if (accordionItem) {
                const itemClassName = getClassName(accordionItem);
                const itemOuterHtml = accordionItem.outerHTML.toLowerCase().substring(0, 500);
                
                // Check class and HTML for BTCPay indicators
                if (itemClassName.includes('btc-pay') || itemClassName.includes('btcpay') || itemClassName.includes('crypto')
                    || itemOuterHtml.includes('btc-pay') || itemOuterHtml.includes('btcpay')) {
                    return 'btcpay';
                }
                
                // Check for Apple Pay
                if (itemClassName.includes('apple-pay') || itemClassName.includes('applepay')
                    || itemOuterHtml.includes('apple-pay') || itemOuterHtml.includes('applepay')) {
                    return 'applepay';
                }
                if (itemClassName.includes('google-pay') || itemClassName.includes('googlepay')
                    || itemOuterHtml.includes('google-pay') || itemOuterHtml.includes('googlepay')) {
                    return 'googlepay';
                }
                
                // Check for Card (but not if it's apple or btc)
                if ((itemClassName.includes('new-card') || itemClassName.includes('card-container') || itemClassName.includes('card'))
                    && !itemClassName.includes('apple') && !itemClassName.includes('btc')) {
                    return 'card';
                }
            }
            
            // Method 2: Check accordion-header's own classes and parent classes
            let current = accordionHeader;
            let depth = 0;
            while (current && depth < 5) {
                const className = getClassName(current);
                
                if (className.includes('btc-pay') || className.includes('btcpay') || className.includes('crypto')) {
                    return 'btcpay';
                }
                if (className.includes('apple-pay') || className.includes('applepay')) {
                    return 'applepay';
                }
                if (className.includes('google-pay') || className.includes('googlepay')) {
                    return 'googlepay';
                }
                if ((className.includes('new-card') || className.includes('card-container'))
                    && !className.includes('apple') && !className.includes('btc')) {
                    return 'card';
                }
                
                current = current.parentElement;
                depth++;
            }
            
            // Method 3: Check text content of the accordion header (most reliable fallback)
            const headerText = (accordionHeader.textContent || '').toLowerCase();
            
            if (headerText.includes('crypto') || headerText.includes('bitcoin') || headerText.includes('btc')) {
                return 'btcpay';
            }
            if (headerText.includes('apple')) {
                return 'applepay';
            }
            if (headerText.includes('google')) {
                return 'googlepay';
            }
            // For card, check that it doesn't mention apple or crypto
            if ((headerText.includes('card') || headerText.includes('credit') || headerText.includes('debit') || headerText.includes('pay'))
                && !headerText.includes('apple') && !headerText.includes('crypto') && !headerText.includes('bitcoin')) {
                return 'card';
            }
            
            return null;
        }
        
        // Use event delegation - only respond to clicks within accordion-header
        container.addEventListener('click', function(e) {
            const target = e.target;
            
            // Find the accordion-header from the clicked element
            const accordionHeader = target.closest('.accordion-header');
            if (!accordionHeader) {
                return;
            }
            
            
            // Detect method from the accordion-header (not the target)
            let detectedMethod = detectPaymentMethodFromAccordionHeaderMain(accordionHeader);
            
            if (!detectedMethod) {
            }
            
            if (detectedMethod) {
                // Always update hidden field and fee display on click
                const methodField = document.getElementById('convesiopay_selected_method');
                if (methodField) {
                    const previousValue = methodField.value;
                    
                    // Only trigger update if method actually changed
                    if (previousValue !== detectedMethod) {
                        methodField.value = detectedMethod;
                        currentPaymentMethod = detectedMethod;
                        
                        // Update fee display immediately for visual feedback
                        updateFeeDisplay(detectedMethod);
                        
                        // CRITICAL: If switching to Apple Pay, recreate the session with correct amount (only when Apple Pay is enabled)
                        if (detectedMethod === 'applepay' && convesioPayComponent && isApplePayEnabled()) {
                            const correctApplePayAmount = calculateCorrectTotalForMethod('applepay');
                            const orderData = getOrderData();
                            const config = getConfig();
                            const integrationName = config.integration_name || config.integrationName || 'PeachPay';
                            
                            createApplePaySessionWithRetry(convesioPayComponent, {
                                integration: integrationName,
                                returnUrl: window.location.href,
                                amount: correctApplePayAmount,
                                currency: orderData.currency,
                                email: orderData.email,
                                name: orderData.name
                            }, { maxAttempts: 3, delayMs: 600 }).then(() => {
                                applePayAuthorizedAmount = correctApplePayAmount;
                                window.convesiopayApplePayAuthorizedAmount = correctApplePayAmount;
                            }).catch(() => {
                                // Apple Pay session recreation failed - will use existing session
                            });
                        } else if (detectedMethod === 'googlepay' && convesioPayComponent && isGooglePayEnabled()) {
                            const correctGooglePayAmount = calculateCorrectTotalForMethod('googlepay');
                            const orderData = getOrderData();
                            const config = getConfig();
                            const integrationName = config.integration_name || config.integrationName || 'PeachPay';

                            createGooglePaySessionWithRetry(convesioPayComponent, {
                                integration: integrationName,
                                returnUrl: window.location.href,
                                orderNumber: orderData.orderNumber,
                                amount: correctGooglePayAmount,
                                currency: orderData.currency,
                                email: orderData.email,
                                name: orderData.name
                            }, { maxAttempts: 3, delayMs: 600 }).then(() => {
                                googlePayAuthorizedAmount = correctGooglePayAmount;
                                window.convesiopayGooglePayAuthorizedAmount = correctGooglePayAmount;
                            }).catch(() => {
                                // Google Pay session recreation failed - will use existing session
                            });
                        }
                        
                        // Store method in session via AJAX and trigger checkout update
                        storeMethodInSessionAndUpdateTotals(detectedMethod);
                    }
                }
            } else {
                // Log undetected clicks for debugging
                const targetText = (e.target.textContent || '').substring(0, 50).trim();
                if (targetText) {
                    const classList = target.className || '';
                    const parentClass = target.parentElement?.className || '';
                }
            }
        }, true); // Use capture phase
        
    }

    /**
     * Bind accordion fee updates on any given container element.
     * This is a fallback for when the standard container ID is not found.
     */
    function bindAccordionFeeUpdatesOnContainer(container) {
        
        if (!container) {
            return;
        }
        
        // Avoid binding multiple times
        if (container.dataset.feeBindingAdded) {
            return;
        }
        container.dataset.feeBindingAdded = 'true';
        
        // Safely get className as string (handles SVG elements)
        function getClassName(element) {
            if (!element) return '';
            const cn = element.className;
            if (typeof cn === 'string') return cn;
            if (cn && typeof cn.baseVal === 'string') return cn.baseVal;
            return '';
        }
        
        // Check if an element is within an accordion header
        function isWithinAccordionHeader(element) {
            let current = element;
            let depth = 0;
            const maxDepth = 10;
            
            while (current && depth < maxDepth) {
                const className = getClassName(current);
                if (className.includes('accordion-header')) {
                    return true;
                }
                current = current.parentElement;
                depth++;
            }
            return false;
        }
        
        // Find payment method from accordion-header element by checking its parent accordion-item
        // and the text content of the header. This is more reliable than checking the clicked element.
        function detectPaymentMethodFromAccordionHeader(accordionHeader) {
            if (!accordionHeader) return null;
            
            // Method 1: Check the parent accordion-item for payment method classes
            const accordionItem = accordionHeader.closest('.accordion-item');
            if (accordionItem) {
                const itemClassName = getClassName(accordionItem);
                const itemOuterHtml = accordionItem.outerHTML.toLowerCase().substring(0, 500);
                
                // Check class and HTML for BTCPay indicators
                if (itemClassName.includes('btc-pay') || itemClassName.includes('btcpay') || itemClassName.includes('crypto')
                    || itemOuterHtml.includes('btc-pay') || itemOuterHtml.includes('btcpay')) {
                    return 'btcpay';
                }
                
                // Check for Apple Pay
                if (itemClassName.includes('apple-pay') || itemClassName.includes('applepay')
                    || itemOuterHtml.includes('apple-pay') || itemOuterHtml.includes('applepay')) {
                    return 'applepay';
                }
                if (itemClassName.includes('google-pay') || itemClassName.includes('googlepay')
                    || itemOuterHtml.includes('google-pay') || itemOuterHtml.includes('googlepay')) {
                    return 'googlepay';
                }
                
                // Check for Card (but not if it's apple or btc)
                if ((itemClassName.includes('new-card') || itemClassName.includes('card-container') || itemClassName.includes('card'))
                    && !itemClassName.includes('apple') && !itemClassName.includes('btc')) {
                    return 'card';
                }
            }
            
            // Method 2: Check accordion-header's own classes and parent classes
            let current = accordionHeader;
            let depth = 0;
            while (current && depth < 5) {
                const className = getClassName(current);
                
                if (className.includes('btc-pay') || className.includes('btcpay') || className.includes('crypto')) {
                    return 'btcpay';
                }
                if (className.includes('apple-pay') || className.includes('applepay')) {
                    return 'applepay';
                }
                if (className.includes('google-pay') || className.includes('googlepay')) {
                    return 'googlepay';
                }
                if ((className.includes('new-card') || className.includes('card-container'))
                    && !className.includes('apple') && !className.includes('btc')) {
                    return 'card';
                }
                
                current = current.parentElement;
                depth++;
            }
            
            // Method 3: Check text content of the accordion header (most reliable fallback)
            const headerText = (accordionHeader.textContent || '').toLowerCase();
            
            if (headerText.includes('crypto') || headerText.includes('bitcoin') || headerText.includes('btc')) {
                return 'btcpay';
            }
            if (headerText.includes('apple')) {
                return 'applepay';
            }
            if (headerText.includes('google')) {
                return 'googlepay';
            }
            // For card, check that it doesn't mention apple or crypto
            if ((headerText.includes('card') || headerText.includes('credit') || headerText.includes('debit') || headerText.includes('pay'))
                && !headerText.includes('apple') && !headerText.includes('crypto') && !headerText.includes('bitcoin')) {
                return 'card';
            }
            
            return null;
        }
        
        // Only respond to clicks within accordion-header
        container.addEventListener('click', function(e) {
            const target = e.target;
            
            // Find the accordion-header from the clicked element
            const accordionHeader = target.closest('.accordion-header');
            if (!accordionHeader) {
                return;
            }
            
            
            // Detect method from the accordion-header (not the target)
            let detectedMethod = detectPaymentMethodFromAccordionHeader(accordionHeader);
            
            if (!detectedMethod) {
            }
            
            if (detectedMethod) {
                // Only trigger update if method actually changed
                if (currentPaymentMethod !== detectedMethod) {
                    // Update hidden field if it exists
                    const methodField = document.getElementById('convesiopay_selected_method');
                    if (methodField) {
                        methodField.value = detectedMethod;
                    }
                    
                    currentPaymentMethod = detectedMethod;
                    
                    // Update fee display immediately for visual feedback
                    updateFeeDisplay(detectedMethod);
                    
                    // If switching to Apple Pay, recreate the session with correct amount (only when Apple Pay is enabled)
                    if (detectedMethod === 'applepay' && convesioPayComponent && isApplePayEnabled()) {
                        const correctApplePayAmount = calculateCorrectTotalForMethod('applepay');
                        const orderData = getOrderData();
                        const config = getConfig();
                        const integrationName = config.integration_name || config.integrationName || 'PeachPay';
                        
                        createApplePaySessionWithRetry(convesioPayComponent, {
                            integration: integrationName,
                            returnUrl: window.location.href,
                            amount: correctApplePayAmount,
                            currency: orderData.currency,
                            email: orderData.email,
                            name: orderData.name
                        }, { maxAttempts: 3, delayMs: 600 }).then(() => {
                            applePayAuthorizedAmount = correctApplePayAmount;
                            window.convesiopayApplePayAuthorizedAmount = correctApplePayAmount;
                        }).catch((error) => {
                            // Apple Pay session recreation failed
                            console.log('Apple Pay session recreation failed', error);
                        });
                    } else if (detectedMethod === 'googlepay' && convesioPayComponent && isGooglePayEnabled()) {
                        const correctGooglePayAmount = calculateCorrectTotalForMethod('googlepay');
                        const orderData = getOrderData();
                        const config = getConfig();
                        const integrationName = config.integration_name || config.integrationName || 'PeachPay';

                        createGooglePaySessionWithRetry(convesioPayComponent, {
                            integration: integrationName,
                            returnUrl: window.location.href,
                            orderNumber: orderData.orderNumber,
                            amount: correctGooglePayAmount,
                            currency: orderData.currency,
                            email: orderData.email,
                            name: orderData.name
                        }, { maxAttempts: 3, delayMs: 600 }).then(() => {
                            googlePayAuthorizedAmount = correctGooglePayAmount;
                            window.convesiopayGooglePayAuthorizedAmount = correctGooglePayAmount;
                        }).catch((error) => {
                            console.log('Google Pay session recreation failed', error);
                        });
                    }
                    
                    // Store method in session via AJAX and trigger checkout update
                    storeMethodInSessionAndUpdateTotals(detectedMethod);
                }
            }
        }, true);
        
    }

    /**
     * Calculate the correct order total for a specific payment method.
     * Uses the base cart total (without gateway fee) and adds the correct fee for the method.
     * 
     * @param {string} method - The payment method (card, applepay, btcpay)
     * @returns {number} The correct total in cents for ConvesioPay
     */
    function calculateCorrectTotalForMethod(method) {
        const unifiedData = window.peachpay_convesiopay_unified_data || {};
        const feeConfig = unifiedData.fee_config || window.convesiopayFeeConfig || {};
        
        // Get base cart total from DOM (includes coupons, shipping, tax - reflects current state)
        // This is the displayed total which already includes any currently applied gateway fee
        const currentTotalInCents = getCurrentCartTotal();
        
        // Subtract any existing gateway fee to get the base total
        let baseCartTotal = currentTotalInCents / 100;
        
        // If there's a currently applied fee, subtract it to get the base
        if (lastAppliedFeeAmount > 0) {
            baseCartTotal = baseCartTotal - lastAppliedFeeAmount;
        }
        
        // Fallback to PHP-provided value if DOM read fails (page just loaded)
        if (baseCartTotal <= 0) {
            baseCartTotal = parseFloat(unifiedData.cart_total || window.convesiopayCartTotal || 0) || 0;
        }
        
        // Get fee config for the requested method
        const methodConfig = feeConfig[method] || {};
        
        // Calculate fee for this method
        let feeAmount = 0;
        if (methodConfig.enabled) {
            const feePercent = parseFloat(methodConfig.amount) || 0;
            if (methodConfig.type === 'percentage') {
                feeAmount = baseCartTotal * (feePercent / 100);
            } else {
                feeAmount = feePercent;
            }
            feeAmount = Math.round((feeAmount + 0.00000001) * 100) / 100;
        }
        
        // Calculate total and convert to cents
        const totalAmount = baseCartTotal + feeAmount;
        return Math.round(totalAmount * 100);
    }

    /**
     * Update the fee display AND total on the checkout page without triggering a full refresh.
     * Reads current total from DOM, subtracts old fee, adds new fee.
     * 
     * @param {string} method - The selected payment method (card, applepay, btcpay)
     */
    function updateFeeDisplay(method) {
        // Get fee config from localized script data
        const unifiedData = window.peachpay_convesiopay_unified_data || {};
        const feeConfig = unifiedData.fee_config || window.convesiopayFeeConfig || {};
        const methodConfig = feeConfig[method] || feeConfig['card'] || {};
        
        // Get base cart total from DOM (current total minus any existing fee)
        const currentTotalInCents = getCurrentCartTotal();
        let baseCartTotal = currentTotalInCents / 100;
        
        // Subtract existing fee to get the base total for percentage calculations
        if (lastAppliedFeeAmount > 0) {
            baseCartTotal = baseCartTotal - lastAppliedFeeAmount;
        }
        
        // Fallback to PHP-provided value if DOM read fails
        if (baseCartTotal <= 0) {
            baseCartTotal = parseFloat(unifiedData.cart_total || window.convesiopayCartTotal || 0) || 0;
        }
        
        // Calculate new fee amount
        let newFeeAmount = 0;
        if (methodConfig.enabled) {
            const feePercent = parseFloat(methodConfig.amount) || 0;
            if (methodConfig.type === 'percentage') {
                newFeeAmount = baseCartTotal * (feePercent / 100);
            } else {
                newFeeAmount = feePercent;
            }
            // Apply rounding to 2 decimals (matching server-side PHP rounding fix)
            newFeeAmount = Math.round((newFeeAmount + 0.00000001) * 100) / 100;
        }
        
        // Find elements - try multiple selectors for compatibility
        const feeRow = document.querySelector('.fee') || document.querySelector('tr.fee');
        const orderTotalRow = document.querySelector('.order-total') || document.querySelector('tr.order-total');
        
        // Use tracked fee amount instead of reading from DOM (more reliable)
        const oldFeeAmount = lastAppliedFeeAmount;
        
        // Get current total from DOM - try multiple selectors
        let currentTotal = 0;
        if (orderTotalRow) {
            // Try multiple selectors for the amount
            const totalAmountEl = orderTotalRow.querySelector('.woocommerce-Price-amount') ||
                                  orderTotalRow.querySelector('.amount') ||
                                  orderTotalRow.querySelector('bdi') ||
                                  orderTotalRow.querySelector('td:last-child');
            if (totalAmountEl) {
                const totalText = totalAmountEl.textContent || '';
                currentTotal = parseFloat(totalText.replace(/[^0-9.-]/g, '')) || 0;
            }
        }
        
        // Calculate new total: currentTotal - oldFee + newFee
        const newTotal = currentTotal - oldFeeAmount + newFeeAmount;
        
        // Update fee row
        if (newFeeAmount > 0) {
            const formattedFee = '$' + newFeeAmount.toFixed(2);
            const feeLabel = methodConfig.label || 'Payment gateway fee';
            
            if (feeRow) {
                const feeNameCell = feeRow.querySelector('th');
                // Try multiple selectors for fee amount cell
                const feeAmountCell = feeRow.querySelector('td .woocommerce-Price-amount') ||
                                      feeRow.querySelector('td .amount') ||
                                      feeRow.querySelector('td bdi') ||
                                      feeRow.querySelector('td:last-child');
                if (feeNameCell) feeNameCell.textContent = feeLabel;
                if (feeAmountCell) feeAmountCell.textContent = formattedFee;
                feeRow.style.display = '';
            }
        } else {
            if (feeRow) {
                feeRow.style.display = 'none';
            }
        }
        
        // Track the fee we just applied
        lastAppliedFeeAmount = newFeeAmount;
        
        // Update total
        if (orderTotalRow && newTotal > 0) {
            const totalAmountEl = orderTotalRow.querySelector('.woocommerce-Price-amount') ||
                                  orderTotalRow.querySelector('.amount') ||
                                  orderTotalRow.querySelector('bdi') ||
                                  orderTotalRow.querySelector('td:last-child');
            if (totalAmountEl) {
                totalAmountEl.textContent = '$' + newTotal.toFixed(2);
            }
        }
    }

    /**
     * Reset session state for new checkout
     */
    function resetSessionState() {
        convesioPayComponent = null;
        isComponentMounted = false;
        btcPaySession = null;
        isSessionCreated = false;
        paymentConfirmedData = null;
        currentPaymentMethod = null;
    }

    /**
     * Clear stored Apple Pay authorization when total has changed.
     * Prevents submitting a stale amount (e.g. after failed submit then user changes address).
     * Call before updateComponentAmount when total change is detected.
     */
    function clearApplePayAuthorizationIfSet() {
        if (paymentConfirmedData && (paymentConfirmedData.paymentMethod === 'applepay' || paymentConfirmedData.paymentMethod === 'googlepay')) {
            paymentConfirmedData = null;
            currentPaymentMethod = null;
            applePayAuthorizedAmount = null;
            googlePayAuthorizedAmount = null;
            if (typeof window !== 'undefined') {
                window.convesiopayApplePayAuthorizedAmount = undefined;
                window.convesiopayApplePayPaymentData = undefined;
                window.convesiopayGooglePayAuthorizedAmount = undefined;
                window.convesiopayGooglePayPaymentData = undefined;
            }
        }
    }

    /**
     * Unmount and destroy the ConvesioPay component while the container is still in the DOM.
     * Must be called before WooCommerce replaces the checkout fragment (e.g. on update_checkout).
     * If the container was already replaced, unmount may throw NotFoundError; we catch and ignore it.
     */
    function unmountConvesioPayComponentSafely() {
        console.log('unmounting component in line 641');
        if (!convesioPayComponent) {
            console.log('convesioPayComponent not found in line 643, not unmounting component');
            resetSessionState();
            return;
        }
        try {
            if (typeof convesioPayComponent.unmount === 'function') {
                console.log('unmounting component in line 649');
                Promise.resolve(convesioPayComponent.unmount()).catch(function() {});
            }
            if (typeof convesioPayComponent.destroy === 'function') {
                console.log('destroying component in line 654');
                convesioPayComponent.destroy();
            }
        } catch (e) {
            console.log('error unmounting component in line 657', e);
            // NotFoundError: node already removed by fragment replace - ignore
            if (e && e.name !== 'NotFoundError' && e.code !== 8) {
                console.warn('[ConvesioPay] Unmount warning:', e);
            }
        }
        convesioPayComponent = null;
        isComponentMounted = false;
        const container = document.getElementById('convesiopay-unified-payment-container');
        if (container) {
            console.log('container found in line 667, clearing container');
            try {
                container.innerHTML = '';
            } catch (e) {
                console.log('error clearing container in line 669', e);
                if (e && e.name !== 'NotFoundError' && e.code !== 8) {
                    console.warn('[ConvesioPay] Container clear warning:', e);
                }
            }
        }
    }

    /**
     * Store payment token in form (unified classic version)
     */
    function storePaymentTokenUnified(token) {
        // Store in hidden field for traditional checkout
        const tokenField = document.getElementById('convesiopay-payment-token');
        if (tokenField) {
            tokenField.value = token;
        }

        // Store globally for WooCommerce processing
        window.convesiopayPaymentToken = token;
    }

    /**
     * Enable submit button (unified classic version)
     */
    function enableSubmitButtonUnified() {
        // Support both classic checkout and order-pay form
        const checkoutForm = getCheckoutForm()[0];
        if (checkoutForm) {
            const submitBtn = checkoutForm.querySelector('#place_order');
            if (submitBtn) {
                submitBtn.disabled = false;
            }
        }
        getCheckoutForm().find('#place_order').prop('disabled', false);
    }

    /**
     * Disable submit button (unified classic version)
     */
    function disableSubmitButtonUnified() {
        // Support both classic checkout and order-pay form
        const checkoutForm = getCheckoutForm()[0];
        if (checkoutForm) {
            const submitBtn = checkoutForm.querySelector('#place_order');
            if (submitBtn) {
                submitBtn.disabled = true;
            }
        }
        getCheckoutForm().find('#place_order').prop('disabled', true);
    }

    /**
     * Show error message (unified classic version)
     */
    function showErrorUnified(message) {
        // Use the existing showError function for consistency
        showError(message);
    }

    /**
     * Hide error message (unified classic version)
     */
    function hideErrorUnified() {
        // Clear any existing error messages
        try {
            const errorMessages = document.querySelectorAll('.convesiopay-unified-error');
            errorMessages.forEach(error => {
                if (error.parentNode) {
                    error.remove();
                }
            });
        } catch (error) {
            // Ignore errors in hiding errors
        }
    }

    /**
     * Get ConvesioPay configuration safely
     */
    function getConfig() {
        const config = window.peachpay_convesiopay_unified_data || {};
        return config;
    }

    /**
     * Return true when current page is WooCommerce order-pay.
     * We use server-provided flag first, then URL endpoint fallback.
     */
    function isOrderPayContext() {
        const config = getConfig();
        if (typeof config.is_order_pay !== 'undefined') {
            return !!config.is_order_pay;
        }
        return window.location.pathname.includes('/order-pay/');
    }

    /**
     * Resolve checkout form for both classic checkout and order-pay.
     */
    function getCheckoutForm() {
        let $form = $('form.checkout');
        if ($form.length) {
            return $form;
        }
        $form = $('form#order_review');
        return $form;
    }

    /**
     * Determine if BTCPay/crypto is enabled for this site based on the
     * unified gateway configuration. This is the client-side source of
     * truth for deciding whether any BTCPay sessions/intents should be
     * created.
     * 
     * STRICT CHECK: Only returns true if 'crypto' is explicitly in active_methods,
     * which should only happen when the BTC Pay gateway is enabled in WooCommerce.
     */
    function isBtcpayEnabled() {
        const config = getConfig();
        const activeMethods = config.active_methods || [];
        // Only return true if 'crypto' is explicitly in the array
        // This ensures BTC Pay is only enabled when the gateway is actually enabled
        const isEnabled = activeMethods.includes('crypto') || activeMethods.includes('btcpay');
        
        // Additional safety: if active_methods is empty or doesn't include crypto, BTC Pay is disabled
        if (activeMethods.length === 0) {
            return false;
        }
        console.log('[CPay Classic] isBtcpayEnabled', isEnabled);
        return isEnabled;
    }

    /**
     * Whether Apple Pay is enabled for ConvesioPay unified (from active_methods).
     * When false, we must not call createApplePaySession at all.
     */
    function isApplePayEnabled() {
        const config = getConfig();
        const activeMethods = config.active_methods || [];
        return activeMethods.includes('applepay');
    }

    /**
     * Whether Google Pay is enabled for ConvesioPay unified.
     */
    function isGooglePayEnabled() {
        const config = getConfig();
        const activeMethods = config.active_methods || [];
        return activeMethods.includes('googlepay');
    }

    /**
     * Check if any payment methods are available in the ConvesioPay component
     * @returns {boolean} True if payment methods are available
     */
    function hasPaymentMethodsAvailable() {
        // Check if component is mounted
        if (!convesioPayComponent || !isComponentMounted) {
            return false;
        }

        // Check if ConvesioPay unified gateway is selected
        const $selectedPayment = $('input[name="payment_method"]:checked');
        if (!$selectedPayment.length || $selectedPayment.val() !== 'peachpay_convesiopay_unified') {
            return false;
        }

        // Check if payment container exists
        const container = document.getElementById('convesiopay-unified-payment-container');
        if (!container) {
            return false;
        }

        // Check if container explicitly shows "No Payment Methods Available" message
        const containerText = (container.textContent || container.innerText || '').toLowerCase();
        const hasNoPaymentMethodsMessage = containerText.includes('no payment method') || 
                                          containerText.includes('no payment methods available');
        
        if (hasNoPaymentMethodsMessage) {
            return false;
        }
        
        // Check if container has meaningful content (more than just empty divs or loading elements)
        const hasContent = container.innerHTML.trim().length > 50; // Increased threshold
        
        // Check for actual payment method UI elements (more strict)
        // Card payment fields - actual input fields for card data (check for visible input fields)
        const cardInputs = container.querySelectorAll('input[type="text"]:not([type="hidden"]), input[type="tel"], input[type="password"]');
        const hasCardFields = cardInputs.length > 0 && Array.from(cardInputs).some(input => input.offsetParent !== null);
        
        // BTCPay iframe - actual payment iframe with source
        const iframes = container.querySelectorAll('iframe[src]');
        const hasBTCPayIframe = iframes.length > 0 && Array.from(iframes).some(iframe => 
            iframe.src.includes('btcpay') || iframe.src.includes('convesiopay')
        );
        
        // Apple Pay button - actual Apple Pay button element (visible)
        const applePayButtons = container.querySelectorAll('button[class*="apple"], [class*="apple-pay"], [id*="apple"]');
        const hasApplePayButton = applePayButtons.length > 0 && Array.from(applePayButtons).some(btn => btn.offsetParent !== null);

        // Google Pay button - actual Google Pay button element (visible)
        const googlePayButtons = container.querySelectorAll('button[class*="google"], [class*="google-pay"], [id*="google"]');
        const hasGooglePayButton = googlePayButtons.length > 0 && Array.from(googlePayButtons).some(btn => btn.offsetParent !== null);
        
        // Payment methods are available ONLY if:
        // - Container has meaningful content AND
        // - Has actual payment method UI elements (card fields, BTCPay iframe, or Apple Pay button)
        // NOTE: We don't just check for any interactive elements - we need SPECIFIC payment method elements
        // Empty divs or containers don't count as available payment methods
        const isAvailable = hasContent && (hasCardFields || hasBTCPayIframe || hasApplePayButton || hasGooglePayButton);
        
        return isAvailable;
    }

    /**
     * Update submit button state based on payment method availability
     * Only controls button when ConvesioPay unified gateway is selected
     * For other payment methods (like Cash on Delivery), enables the button
     */
    function updateSubmitButtonState() {
        const $selectedPayment = $('input[name="payment_method"]:checked');
        
        if (!$selectedPayment.length) {
            // No payment method selected, don't interfere
            return;
        }
        
        const selectedMethod = $selectedPayment.val();
        
        // If ConvesioPay unified is selected, check payment method availability
        if (selectedMethod === 'peachpay_convesiopay_unified') {
            const hasMethods = hasPaymentMethodsAvailable();
            
            if (hasMethods) {
                enableSubmitButtonUnified();
            } else {
                disableSubmitButtonUnified();
            }
        } else {
            // Other payment methods selected (Cash on Delivery, etc.) - enable button
            // This matches the behavior in blocks checkout where other payment methods work normally
            enableSubmitButtonUnified();
        }
    }
    const config = getConfig();
    
    /**
     * Initialize lastAppliedFeeAmount from the current DOM state
     * This ensures we know the initial fee when switching payment methods
     */
    function initializeFeeFromDOM() {
        const feeRow = document.querySelector('.fee') || document.querySelector('tr.fee');
        if (feeRow && feeRow.style.display !== 'none') {
            // Try multiple selectors for fee amount
            const feeAmountCell = feeRow.querySelector('td .woocommerce-Price-amount') ||
                                  feeRow.querySelector('td .amount') ||
                                  feeRow.querySelector('td bdi') ||
                                  feeRow.querySelector('td:last-child');
            if (feeAmountCell) {
                const feeText = feeAmountCell.textContent || '';
                lastAppliedFeeAmount = parseFloat(feeText.replace(/[^0-9.-]/g, '')) || 0;
            }
        }
    }
    
    /**
     * Initialize ConvesioPay for classic checkout
     */
    function initConvesioPayClassic() {
        
        // Wait for ConvesioPay SDK to load
        if (!window.ConvesioPay) {
            setTimeout(initConvesioPayClassic, 100);
            return;
        }
        
        // Initialize the fee tracker from current DOM state
        initializeFeeFromDOM();

        // Find ConvesioPay payment method radio button
        const $convesioPayRadio = $('input[name="payment_method"][value="peachpay_convesiopay_unified"]');

        if ($convesioPayRadio.length === 0) {
            return;
        }
        
        // Only run one-time initialization if not already done
        // This prevents duplicate handlers and unwanted session resets on checkout updates
        if (!convesioPayInitialized) {
            convesioPayInitialized = true;
            
            // Only sync session to default 'card' if ConvesioPay is already selected on INITIAL page load
            // This prevents mismatch between the visually selected method and the fee shown
            if ($convesioPayRadio.is(':checked')) {
                const defaultMethod = 'card';
                storeMethodInSessionAndUpdateTotals(defaultMethod);
                updateFeeDisplay(defaultMethod);
            }

            // Initialize ConvesioPay when this payment method is selected
            // Using namespaced events and .off() first to prevent duplicate handlers
            $convesioPayRadio.off('change.convesiopayInit').on('change.convesiopayInit', function() {
                if ($(this).is(':checked')) {
                    // Ensure transaction ID exists as soon as ConvesioPay is selected (client-generated, no API)
                    getOrCreateConvesioTransactionId();
                    // Reset to default 'card' when ConvesioPay is selected
                    const defaultMethod = 'card';
                    storeMethodInSessionAndUpdateTotals(defaultMethod);
                    updateFeeDisplay(defaultMethod);
                    
                    setTimeout(initConvesioPayComponent, 100);
                    // Disable button initially until payment methods are confirmed available
                    disableSubmitButtonUnified();
                } else {
                    // ConvesioPay deselected - update button state (will enable if other method selected)
                    updateSubmitButtonState();
                }
            });
            
            // Listen for payment method changes to update button state when switching between methods
            $('input[name="payment_method"]').off('change.convesiopayButton').on('change.convesiopayButton', function() {
                updateSubmitButtonState();
            });
        }

        // Initialize immediately if already selected (this can run multiple times safely)
        if ($convesioPayRadio.is(':checked')) {
            getOrCreateConvesioTransactionId(); // Ensure id exists before any submit
            setTimeout(initConvesioPayComponent, 100);
            // Disable button initially until payment methods are confirmed available
            disableSubmitButtonUnified();
        }

        // CRITICAL FIX: Bind directly to form.checkout, NOT document.body
        // WooCommerce uses triggerHandler() for checkout_place_order events, which does NOT bubble!
        // Events triggered with triggerHandler() only fire on the exact element they're bound to.
        // Using $(document.body).on() would never catch these events.
        
        // Use namespaced events (.convesiopay) and unbind before binding to prevent duplicate handlers
        // when initConvesioPayClassic is called multiple times (e.g., after updated_checkout)
        const $checkoutForm = getCheckoutForm();
        if (!$checkoutForm.length) {
            return;
        }

        // Keep checkout_place_order hooks for classic checkout form.
        if ($checkoutForm.is('form.checkout')) {
            $checkoutForm
                .off('checkout_place_order_peachpay_convesiopay_unified.convesiopay')
                .on('checkout_place_order_peachpay_convesiopay_unified.convesiopay', handleCheckoutSubmission);
        
        // Hook into the general checkout_place_order event (fires BEFORE payment-specific event)
        // This ensures payment data is added before WooCommerce serializes the form
            $checkoutForm
                .off('checkout_place_order.convesiopay')
                .on('checkout_place_order.convesiopay', function() {
                    const $selectedPayment = $('input[name="payment_method"]:checked');
                    if ($selectedPayment.val() === 'peachpay_convesiopay_unified') {
                        // Ensure form fields are present before any form serialization
                        addPaymentDataToForm();
                    }
                    return true; // Allow checkout to continue
                });
        }
        
        // Fallback: Also listen for form submission to ensure transaction ID is added
        $checkoutForm
            .off('submit.convesiopay')
            .on('submit.convesiopay', function(e) {
                const $selectedPayment = $('input[name="payment_method"]:checked');
                if ($selectedPayment.val() === 'peachpay_convesiopay_unified') {
                    addPaymentDataToForm();
                }
            });
    }

    /**
     * Initialize ConvesioPay component
     */
    function initConvesioPayComponent() {
        
        if (isComponentMounted || !window.ConvesioPay) {
            return;
        }

        const container = document.getElementById('convesiopay-unified-payment-container');
        if (!container) {
            return;
        }

        // If BTCPay is disabled in the unified configuration, mount the
        // component for card/Apple Pay only and completely skip BTCPay
        // session creation. This avoids unnecessary API calls and
        // prevents the "Failed to create BTCPay session" error when
        // crypto is intentionally turned off.
        if (!isBtcpayEnabled()) {
            console.log('[CPay Classic] isBtcpayEnabled is false in line 1045, not creating BTC Pay session');
            // BTC Pay is disabled - mount component without BTC Pay session
            mountConvesioPayComponent();
            return;
        }

        // Create BTCPay session first, then mount component (following blocks pattern)
        // Only attempt session creation if BTC Pay is enabled
        if (isBtcpayEnabled()) {
            console.log('[CPay Classic] isBtcpayEnabled is true in line 1054, creating BTC Pay session');
                createBTCPaySession().then(sessionResult => {
                console.log('[CPay Classic] createBTCPaySession result in line 1056', sessionResult);
                if (sessionResult.success) {
                    console.log('[CPay Classic] createBTCPaySession success in line 1058, mounting component');
                    // After session is created, mount the ConvesioPay component
                    setTimeout(() => {
                        console.log('[CPay Classic] createBTCPaySession success in line 1058, mounting component');
                        mountConvesioPayComponent();
                    }, 100);
                } else {
                    console.log('[CPay Classic] createBTCPaySession failed in line 1064, mounting component');
                    // BTC Pay session creation failed - mount component anyway so Card and Apple Pay can work
                    // Only show a warning (not blocking error) if BTC Pay was supposed to be enabled
                    // The component will work with Card and Apple Pay even without BTC Pay session
                    if (sessionResult.disabled || sessionResult.message?.toLowerCase().includes('disabled')) {
                        console.log('[CPay Classic] createBTCPaySession disabled in line 1067, mounting component');
                            // BTC Pay is intentionally disabled - this is expected, don't log as error
                    } else if (isBtcpayEnabled() && sessionResult.message && !sessionResult.disabled) {
                        // BTC Pay session failed but it should be enabled - still mount for Card/Apple Pay
                        console.log('[CPay Classic] createBTCPaySession enabled in line 1074, mounting component');
                    }
                    // Always mount the component so Card and Apple Pay can work
                    // BTC Pay will simply not be available if session creation failed
                    console.log('[CPay Classic] createBTCPaySession failed in line 1078, mounting component');
                    mountConvesioPayComponent();
                }
            }).catch(error => {
                // BTC Pay session creation error - mount component anyway so Card and Apple Pay can work
                // Log the error but don't block the component from mounting
                // BTC Pay session creation error - still mount for Card/Apple Pay
                // Always mount the component so Card and Apple Pay can work
                // BTC Pay will simply not be available if session creation failed
                mountConvesioPayComponent();
            });
        } else {
            // Double-check: if somehow we got here but BTC Pay is disabled, just mount
            mountConvesioPayComponent();
        }
    }

    /**
     * Mount ConvesioPay component (following blocks pattern)
     */
    async function mountConvesioPayComponent() {
        console.log('mounting component in line 1028');
        const container = document.getElementById('convesiopay-unified-payment-container');
        if (!container) {
            console.log('container not found in line 1031, not mounting component');
            return;
        }
        console.log('container found in line 1034, mounting component');
        window._convesioPayContainerRef = container; // diagnostic: after country change run document.contains(window._convesioPayContainerRef)

        try {
            // Check if ConvesioPay SDK is available
            if (typeof window.ConvesioPay === 'undefined') {
                throw new Error('ConvesioPay SDK not available');
            }

            const config = getConfig();
    
            const clientKey = config.convesiopay_config?.clientKey || config.clientKey;
            const apiKey = config.convesiopay_config?.apiKey || config.apiKey;
            const integrationName = config.integration_name || config.integrationName;


            if (!apiKey || apiKey.trim() === '') {
                throw new Error('ConvesioPay API key not configured. Please configure ConvesioPay in PeachPay admin settings.');
            }

            if (!integrationName || integrationName.trim() === '') {
                throw new Error('ConvesioPay integration name not configured. Please configure ConvesioPay in PeachPay admin settings.');
            }

            // Create ConvesioPay instance (correct way)
            const cpay = window.ConvesioPay(apiKey);


            // Get customer email
            const rawEmail = $('#billing_email').val();
            const customerEmail = rawEmail && rawEmail.trim() !== '' ? rawEmail.trim() : null;

            // Initialize component (correct syntax)
            const componentConfig = {
                environment: config.convesiopay_config?.api_url?.includes('qa') ? 'test' : 'live',
                clientKey: clientKey,
                integration: integrationName,
                theme: config.checkout_theme || 'light'
            };
            
            // Only attach email if we actually have one
            if (customerEmail) {
                componentConfig.customerEmail = customerEmail;
            }
            
            const component = cpay.component(componentConfig);

            // Mount component to container (replaces loader)
            component.mount('#convesiopay-unified-payment-container');
            
            // Bind to accordion/tab clicks for immediate fee updates
            // This is more reliable than waiting for component.on('change') events
            setTimeout(function() {
                bindAccordionFeeUpdates();
            }, 500); // Wait for component to fully render

            /**
             * Disable submit button immediately after component mount to prevent premature checkout.
             * 
             * Reason: When the ConvesioPay component first mounts, payment methods (card fields, 
             * BTCPay, Apple Pay) may not be immediately rendered or available. We disable the 
             * submit button here as a safety measure, and it will be automatically enabled by 
             * updateSubmitButtonState() once payment methods are confirmed to be available and 
             * rendered in the container. This prevents users from attempting checkout before 
             * payment methods are ready, which could result in errors or incomplete payment data.
             */
            disableSubmitButtonUnified();

            // Set up event handling (following blocks pattern exactly)
            component.on('change', (event) => {
                // Update submit button state when component changes
                updateSubmitButtonState();

                const methodField = document.getElementById('convesiopay_selected_method');
                const selectedMethod = methodField && methodField.value ? methodField.value : currentPaymentMethod;
                
                // Track payment method changes for dynamic fee calculation
                if (event.type && event.type !== currentPaymentMethod) {
                    // Some SDK flows emit card validation events even while a wallet method
                    // is selected. Ignore those so we don't switch the checkout state back to card.
                    if (!selectedMethod || event.type === selectedMethod) {
                        currentPaymentMethod = event.type;
                        
                        // Update hidden field with selected method
                        if (methodField) {
                            const previousFieldValue = methodField.value;
                            
                            // Only update if the hidden field value is actually changing
                            if (previousFieldValue !== event.type) {
                                methodField.value = event.type;
                                
                                // Update fee display directly for immediate visual feedback
                                // and persist selected method for server-side fee/order sync.
                                updateFeeDisplay(event.type);
                                storeMethodInSessionAndUpdateTotals(event.type);
                            } else {
                            }
                        } else {
                        }
                    }
                } else if (event.type) {
                }
                
                // Check if this is a card payment event based on event.type
                if (event.type === 'card') {
                    if (selectedMethod && selectedMethod !== 'card') {
                        return;
                    }
                    handleCardPaymentWithPeachPayFunctions(event, component);
                } else if (event.type === 'btcpay') {
                    // Handle BTCPay payments directly when event.type is btcpay
                    // GUARD: Only handle BTC Pay events if BTC Pay is enabled
                    if (isBtcpayEnabled()) {
                        handleBTCPayPayment(event);
                    } else {
                        // BTC Pay is disabled - ignore BTC Pay events
                    }
                } else if (event.type === 'applepay') {
                    // Handle ApplePay payments with auto-submit when successful
                    if (event.isSuccessful) {
                        // ApplePay payment intent was successfully authorized
                        handleApplePayPaymentSuccess(component, event);
                    } else if (event.errors) {
                        // Handle ApplePay errors
                        const errorMessage = event.errors[0]?.message || 'ApplePay payment failed';
                        showErrorUnified(errorMessage);
                    }
                } else if (event.type === 'googlepay') {
                    if (event.isSuccessful) {
                        handleGooglePayPaymentSuccess(component, event);
                    } else if (event.errors) {
                        const errorMessage = event.errors[0]?.message || 'Google Pay payment failed';
                        showErrorUnified(errorMessage);
                    }
                } else {
                    // Detect payment method type and handle accordingly for other methods
                    const paymentMethod = detectPaymentMethod(event);

                    // Only process payment when user explicitly submits/confirms, not on input change
                    if (paymentMethod === 'card' && event.isValid === true && event.isSuccessful === true) {
                        handleCardPayment(component, event);
                    } else if (paymentMethod === 'btcpay' && event.isValid === true && event.isSuccessful === true) {
                        // GUARD: Only handle BTC Pay payments if BTC Pay is enabled
                        if (isBtcpayEnabled()) {
                            handleBTCPayPayment(event);
                        } else {
                            // BTC Pay is disabled - ignore BTC Pay payment events
                        }
                    } else if (paymentMethod === 'applepay' && event.isValid === true && event.isSuccessful === true) {
                        handleApplePayPayment(component, event);
                    } else if (paymentMethod === 'googlepay' && event.isValid === true && event.isSuccessful === true) {
                        handleGooglePayPaymentSuccess(component, event);
                    } else {
                        // Other payment methods or invalid states
                    }
                }
            });

            convesioPayComponent = component;
            isComponentMounted = true;

            // Monitor container for payment method availability and update submit button
            const containerObserver = new MutationObserver(() => {
                // Small delay to ensure DOM is updated
                setTimeout(() => {
                    updateSubmitButtonState();
                }, 100);
            });
            
            containerObserver.observe(container, {
                childList: true,
                subtree: true,
                attributes: true,
                characterData: true
            });

            // Initial check after component mounts - use multiple checks with increasing delays
            // This ensures we catch the component even if it renders slowly
            setTimeout(() => {
                updateSubmitButtonState();
            }, 300);
            
            setTimeout(() => {
                updateSubmitButtonState();
            }, 800);
            
            setTimeout(() => {
                updateSubmitButtonState();
            }, 1500);
            
            setTimeout(() => {
                updateSubmitButtonState();
            }, 2500);

            // Get order data
            const orderData = getOrderData();

            if (!orderData.isValid) {
                showErrorUnified('Invalid order data');
                disableSubmitButtonUnified();
                return;
            }
            
            // Create Apple Pay session only when Apple Pay is enabled (with retry for slow connections)
            if (isApplePayEnabled()) {
                try {
                    await createApplePaySessionWithRetry(component, {
                        integration: integrationName,
                        returnUrl: window.location.href,
                        amount: orderData.amount,
                        currency: orderData.currency,
                        email: orderData.email,
                        name: orderData.name
                    }, { maxAttempts: 3, delayMs: 600 });
                } catch (e) {
                    console.log('apple pay session creation failed in line 1234', e);
                    // Don't fail mount; Apple Pay may still work on user interaction
                }
            }

            if (isGooglePayEnabled()) {
                try {
                    await createGooglePaySessionWithRetry(component, {
                        integration: integrationName,
                        returnUrl: window.location.href,
                        orderNumber: orderData.orderNumber,
                        amount: orderData.amount,
                        currency: orderData.currency,
                        email: orderData.email,
                        name: orderData.name
                    }, { maxAttempts: 3, delayMs: 600 });
                } catch (e) {
                    // Don't fail mount; Google Pay may still work on user interaction
                }
            }

            // Only create BTCPay intent if BTC Pay is enabled and we have a session
            // GUARD: Check if BTC Pay is enabled before attempting to create intent
            if (isBtcpayEnabled() && btcPaySession) {
                try {
                    const btcPayIntentData = {
                        session: btcPaySession
                    };
                    // Create BTCPay intent using the mounted component (following blocks pattern)
                    convesioPayComponent.createBTCPayIntent(btcPayIntentData);
                    
                    // Set up postMessage listener for iframe communication
                    setupBTCPayMessageListener();
                } catch (error) {
                    // Silently fail if BTC Pay intent creation fails when BTC Pay is disabled
                    // Only log error if BTC Pay should be enabled
                    // BTCPay intent creation failed - handled silently
                    console.log('btcpay intent creation failed in line 1258', error);
                }
            } else {
                // BTC Pay is disabled - do not create intent or set up listeners
                // Component will work with Card and Apple Pay only
            }
            
            // Check again after BTCPay intent is created
            setTimeout(() => {
                updateSubmitButtonState();
            }, 1000);

        } catch (error) {
            // NotFoundError: DOM node was removed (e.g. by WooCommerce fragment replace). Don't show error; re-init will run from updated_checkout.
            const isNotFoundError = error && (error.name === 'NotFoundError' || error.code === 8);
            if (isNotFoundError) {
                console.log('[ConvesioPay] NotFoundError in mount (container was removed by fragment replace); retrying.');
            }
            if (!isNotFoundError) {
                container.innerHTML = '<p style="color: red;">Payment component failed to load. Please refresh and try again.</p>';
                console.error('payment component failed to load in line 1274', error);
            }
            const container2 = document.getElementById('convesiopay-unified-payment-container');
            if (container2) {
                mountConvesioPayComponentAttempt++;
                if (mountConvesioPayComponentAttempt > 3) {
                    return;
                }
                if (!isNotFoundError) {
                    container2.innerHTML = '';
                }
                setTimeout(() => {
                    mountConvesioPayComponent();
                }, isNotFoundError ? 300 : 1000);
            }
        }
    }


    /**
     * Ensure ConvesioPay transaction ID exists (client-generated, no API call).
     * Uses single source of truth so all paths share the same id for this checkout.
     */
    function createPeachPayTransactionUnified() {
        getOrCreateConvesioTransactionId();
    }

    /**
     * Handle card payment using peachpay_convesiopay_card functions (when event.type === 'card')
     * This mimics what happens when peachpay_convesiopay_card is selected (following blocks pattern)
     */
    function handleCardPaymentWithPeachPayFunctions(event, component) {
        // STEP 1: Call createPeachPayTransaction() (what peachpay_convesiopay_card does)
        createPeachPayTransactionUnified();

        // STEP 2: Handle component change validation (like checkout.js handleComponentChange)
        // Note: Don't check event.isValid here like blocks version - just process when event.type === 'card'
        if (event.isValid) {
            // All component fields are valid and we can get the token
            try {
                const tokenResult = component.createToken();

                // Handle both Promise and direct string return
                let token;
                if (tokenResult && typeof tokenResult.then === 'function') {
                    // It's a Promise, await it
                    tokenResult.then(function(resolvedToken) {
                        token = resolvedToken;
                        processCardPaymentWithPeachPayFunctions(token, event, component);
                    }).catch(function(error) {
                        // Don't show error immediately - user might still be typing
                    });
                } else {
                    // It's a direct value
                    token = tokenResult;
                    if (token) {
                        processCardPaymentWithPeachPayFunctions(token, event, component);
                    }
                }

            } catch (error) {
                // Don't show error immediately - user might still be typing
            }
        } else {
            // Don't show error message immediately - user might still be typing
            // The blocks version doesn't show error messages on invalid events
        }
    }

    /**
     * Process card payment with token (PeachPay functions version)
     */
    function processCardPaymentWithPeachPayFunctions(token, event, component) {
        if (!token) {
            showErrorUnified('Failed to create payment token');
            return;
        }

        // Get order data
        const orderData = getOrderData();

        if (!orderData.isValid) {
            showErrorUnified('Invalid order data');
            return;
        }

        // Store payment data (following blocks pattern)
        paymentConfirmedData = {
            paymentId: 'card_' + Date.now(),
            status: 'succeeded',
            paymentMethod: 'card',
            amount: orderData.amount,
            currency: orderData.currency,
            orderNumber: orderData.orderNumber,
            token: token
        };

        currentPaymentMethod = 'card';

        // Store payment token (exactly like blocks version storePaymentToken function)
        storePaymentTokenUnified(token);

        // CRITICAL: Add payment data to form IMMEDIATELY after setting paymentConfirmedData
        // This ensures the hidden fields are present BEFORE WooCommerce serializes the form
        // on the first checkout attempt (fixes race condition where fields were only added
        // during checkout_place_order event which is too late - form is already serialized)
        addPaymentDataToForm();

        // Component is valid, enable checkout (exactly like blocks version enableSubmitButton)
        enableSubmitButtonUnified();
        hideErrorUnified();
        
        // Also update button state to ensure it's enabled
        updateSubmitButtonState();
    }

    /**
     * Handle card payment (following blocks pattern)
     */
    function handleCardPayment(component, event) {
        try {
            // Create payment token using component (following checkout.js pattern)
            const tokenResult = component.createToken();

            // Handle both Promise and direct string return
            let token;
            if (tokenResult && typeof tokenResult.then === 'function') {
                // It's a Promise, await it
                tokenResult.then(function(resolvedToken) {
                    token = resolvedToken;

                    if (!token) {
                        showErrorUnified('Failed to create payment token');
                        return;
                    }

                    processCardPayment(token, event);
                }).catch(function(error) {
                    showErrorUnified('Failed to create payment token');
                });
            } else {
                // It's a direct value
                token = tokenResult;

                if (!token) {
                    showErrorUnified('Failed to create payment token');
                    return;
                }

                processCardPayment(token, event);
            }

        } catch (error) {
            showErrorUnified('Card payment failed: ' + error.message);
        }
    }

    /**
     * Process card payment with token
     */
    function processCardPayment(token, event) {
        if (!token) {
            showErrorUnified('Failed to create payment token');
            return;
        }

        // Get order data
        const orderData = getOrderData();

        if (!orderData.isValid) {
            showErrorUnified('Invalid order data');
            return;
        }

        // Store payment data
        paymentConfirmedData = {
            paymentId: 'card_' + Date.now(),
            status: 'succeeded',
            paymentMethod: 'card',
            amount: orderData.amount,
            currency: orderData.currency,
            orderNumber: orderData.orderNumber,
            token: token
        };

        currentPaymentMethod = 'card';

        // Add form data and trigger WooCommerce checkout event
        addPaymentDataToForm();
        $(document.body).trigger('checkout_place_order_peachpay_convesiopay_unified');
    }


    /**
     * Handle Apple Pay payment success with auto-submit (NEW TOKEN-BASED FLOW)
     * After user authorizes payment on device, we receive a token (NOT a paymentId)
     * Backend will create the payment using secret key AFTER WC order is created
     */
    async function handleApplePayPaymentSuccess(component, event) {
        try {
            // Get order data
            const orderData = getOrderData();

            if (!orderData.isValid) {
                showErrorUnified('Invalid order data');
                return;
            }

            // NEW FLOW: Extract token from event (SDK provides this after device authorization)
            // Payment does NOT exist yet - it will be created by backend with secret key
            const paymentToken = event.token
                ?? event.paymentData?.token
                ?? event.data?.token
                ?? null;

            if (!paymentToken) {
                showErrorUnified('Apple Pay authorization successful but token is missing. Please try again.');
                return;
            }

            // Store ApplePay payment data globally for use in checkout submission
            // NOTE: No paymentId yet - that will be created by backend
            paymentConfirmedData = {
                paymentId: null, // Will be created by backend
                status: 'authorized', // Device authorized, payment will be created by backend
                paymentMethod: 'applepay',
                amount: event.paymentData?.amount || orderData.amount,
                currency: event.paymentData?.currency || orderData.currency,
                orderNumber: orderData.orderNumber,
                token: paymentToken
            };

            currentPaymentMethod = 'applepay';

            // IMPORTANT: Clear BTCPay session for ApplePay to prevent misdetection
            const hadBtcPaySession = btcPaySession !== null;
            btcPaySession = null;

            // Store payment token for backend processing
            if (typeof storePaymentTokenUnified === 'function') {
                storePaymentTokenUnified(paymentToken);
            }
            window.convesiopayPaymentToken = paymentToken;
            window.convesiopayApplePayPaymentData = paymentConfirmedData;

            // Add form data before auto-submitting
            addPaymentDataToForm();

            // Auto-submit the WooCommerce order
            setTimeout(() => {
                autoClickPlaceOrderButton();
            }, 500);

        } catch (error) {
            showErrorUnified('Apple Pay failed: ' + error.message);
        }
    }

    /**
     * Handle Google Pay payment success with auto-submit.
     */
    async function handleGooglePayPaymentSuccess(component, event) {
        try {
            const orderData = getOrderData();

            if (!orderData.isValid) {
                showErrorUnified('Invalid order data');
                return;
            }

            const paymentToken = event.token
                ?? event.paymentData?.token
                ?? event.data?.token
                ?? null;

            if (!paymentToken) {
                showErrorUnified('Google Pay authorization successful but token is missing. Please try again.');
                return;
            }

            paymentConfirmedData = {
                paymentId: null,
                status: 'authorized',
                paymentMethod: 'googlepay',
                amount: event.paymentData?.amount || orderData.amount,
                currency: event.paymentData?.currency || orderData.currency,
                orderNumber: orderData.orderNumber,
                token: paymentToken
            };

            currentPaymentMethod = 'googlepay';
            btcPaySession = null;

            if (typeof storePaymentTokenUnified === 'function') {
                storePaymentTokenUnified(paymentToken);
            }
            window.convesiopayPaymentToken = paymentToken;
            window.convesiopayGooglePayPaymentData = paymentConfirmedData;

            addPaymentDataToForm();

            setTimeout(() => {
                autoClickPlaceOrderButton();
            }, 500);
        } catch (error) {
            showErrorUnified('Google Pay failed: ' + error.message);
        }
    }

    /**
     * Handle Apple Pay payment (following blocks pattern) - LEGACY
     */
    function handleApplePayPayment(component, event) {
        try {
            // Create payment token using component (following checkout.js pattern)
            const tokenResult = component.createToken();

            // Handle both Promise and direct string return
            let token;
            if (tokenResult && typeof tokenResult.then === 'function') {
                // It's a Promise, await it
                tokenResult.then(function(resolvedToken) {
                    token = resolvedToken;

                    if (!token) {
                        showErrorUnified('Failed to create Apple Pay token');
                        return;
                    }

                    processApplePayPayment(token, event);
                }).catch(function(error) {
                    showErrorUnified('Failed to create Apple Pay token');
                });
            } else {
                // It's a direct value
                token = tokenResult;

                if (!token) {
                    showErrorUnified('Failed to create Apple Pay token');
                    return;
                }

                processApplePayPayment(token, event);
            }
        } catch (error) {
            showErrorUnified('Apple Pay failed: ' + error.message);
        }
    }

    /**
     * Process Apple Pay payment with token and AUTO-SUBMIT the order (NEW)
     */
    function processApplePayPaymentWithAutoSubmit(token, event) {
        if (!token) {
            showErrorUnified('Failed to create Apple Pay token');
            return;
        }

        // Get order data
        const orderData = getOrderData();

        if (!orderData.isValid) {
            showErrorUnified('Invalid order data');
            return;
        }

        // Store payment data
        paymentConfirmedData = {
            paymentId: 'applepay_' + Date.now(),
            status: 'succeeded',
            paymentMethod: 'applepay',
            amount: orderData.amount,
            currency: orderData.currency,
            orderNumber: orderData.orderNumber,
            token: token
        };

        currentPaymentMethod = 'applepay';

        // IMPORTANT: Clear BTCPay session for ApplePay to prevent misdetection
        btcPaySession = null;

        // Store payment token for backend processing
        storePaymentTokenUnified(token);

        // Add form data before auto-submitting
        addPaymentDataToForm();

        // Auto-submit the WooCommerce order (don't require customer to click Complete Order)
        setTimeout(() => {
            autoClickPlaceOrderButton();
        }, 500);
    }

    /**
     * Process Apple Pay payment with token (LEGACY - requires manual click)
     */
    function processApplePayPayment(token, event) {
        if (!token) {
            showErrorUnified('Failed to create Apple Pay token');
            return;
        }

        // Get order data
        const orderData = getOrderData();

        if (!orderData.isValid) {
            showErrorUnified('Invalid order data');
            return;
        }

        // Store payment data
        paymentConfirmedData = {
            paymentId: 'applepay_' + Date.now(),
            status: 'succeeded',
            paymentMethod: 'applepay',
            amount: orderData.amount,
            currency: orderData.currency,
            orderNumber: orderData.orderNumber,
            token: token
        };

        currentPaymentMethod = 'applepay';

        // IMPORTANT: Clear BTCPay session for ApplePay to prevent misdetection
        btcPaySession = null;

        // Add form data and trigger WooCommerce checkout event
        addPaymentDataToForm();
        $(document.body).trigger('checkout_place_order_peachpay_convesiopay_unified');
    }

    /**
     * Add payment data to checkout form (simplified to match blocks version)
     */
    function addPaymentDataToForm() {
        // Single source of truth: client-generated id, same for entire checkout
        const transactionId = getOrCreateConvesioTransactionId();

        // Add transaction ID field
        addHiddenField('peachpay_transaction_id', transactionId);
        
        // Debug: Verify the field was added
        setTimeout(() => {
            const $form = getCheckoutForm();
            if (!$form.length || !$form[0]) {
                return;
            }
            const $transactionField = $form.find('input[name="peachpay_transaction_id"]');
            
            // Show all form data that will be submitted
            const formData = new FormData($form[0]);
        }, 100);

        // Create simplified payment method data (matching blocks format)
        const paymentMethodData = {
            peachpay_transaction_id: String(transactionId), // same id as hidden field
            payment_method_type: String(paymentConfirmedData?.paymentMethod || currentPaymentMethod || 'btcpay')
        };


        if (paymentConfirmedData) {
            // Add essential payment data in both camelCase and lowercase for compatibility
            paymentMethodData.paymentId = String(paymentConfirmedData.paymentId || '');
            paymentMethodData.paymentMethod = String(paymentConfirmedData.paymentMethod || '');
            paymentMethodData.status = String(paymentConfirmedData.status || '');

            // Also add lowercase versions for backward compatibility
            paymentMethodData.paymentid = String(paymentConfirmedData.paymentId || '');
            paymentMethodData.paymentmethod = String(paymentConfirmedData.paymentMethod || '');

            // Add payment token based on payment method
            if (paymentConfirmedData.paymentMethod === 'card' || paymentConfirmedData.paymentMethod === 'applepay' || paymentConfirmedData.paymentMethod === 'googlepay') {
                // Use token from paymentConfirmedData, or fallback to window.convesiopayPaymentToken
                const token = paymentConfirmedData.token || window.convesiopayPaymentToken || '';
                paymentMethodData.convesiopay_payment_token = String(token);
                
                // Also add to hidden form field for classic checkout
                if (token) {
                    addHiddenField('convesiopay_payment_token', token);
                }
                
                // For ApplePay, also add payment_method_type
                if (paymentConfirmedData.paymentMethod === 'applepay') {
                    paymentMethodData.payment_method_type = String('applepay');
                    paymentMethodData.applepay_amount = String(paymentConfirmedData.amount || 0);
                    paymentMethodData.applepay_currency = String(paymentConfirmedData.currency || 'USD');
                } else if (paymentConfirmedData.paymentMethod === 'googlepay') {
                    paymentMethodData.payment_method_type = String('googlepay');
                    paymentMethodData.googlepay_amount = String(paymentConfirmedData.amount || 0);
                    paymentMethodData.googlepay_currency = String(paymentConfirmedData.currency || 'USD');
                }
            } else if (paymentConfirmedData.paymentMethod === 'btcpay') {
                paymentMethodData.convesiopay_payment_token = String('btc-session-' + btcPaySession);
                paymentMethodData.btcpay_session_id = String(btcPaySession || '');
                paymentMethodData.btcpay_payment_id = String(paymentConfirmedData.paymentId || '');
                paymentMethodData.btcpay_invoice_id = String(paymentConfirmedData.invoiceId || '');
                paymentMethodData.btcpay_status = String(paymentConfirmedData.status || '');
            }
        } else {
            // Fallback: Check if we have ApplePay token in window
            if (window.convesiopayApplePayPaymentData && window.convesiopayApplePayPaymentData.token) {
                // ApplePay payment but paymentConfirmedData not set - use window data
                const applePayToken = window.convesiopayApplePayPaymentData.token;
                paymentMethodData.convesiopay_payment_token = String(applePayToken);
                paymentMethodData.payment_method_type = String('applepay');
                paymentMethodData.paymentmethod = String('applepay');
                paymentMethodData.status = String('authorized');
                addHiddenField('convesiopay_payment_token', applePayToken);
                addHiddenField('payment_method_type', 'applepay');
            } else if (window.convesiopayPaymentToken && currentPaymentMethod === 'applepay') {
                // ApplePay token in window but not in paymentConfirmedData
                paymentMethodData.convesiopay_payment_token = String(window.convesiopayPaymentToken);
                paymentMethodData.payment_method_type = String('applepay');
                paymentMethodData.paymentmethod = String('applepay');
                paymentMethodData.status = String('authorized');
                addHiddenField('convesiopay_payment_token', window.convesiopayPaymentToken);
                addHiddenField('payment_method_type', 'applepay');
            } else if (window.convesiopayGooglePayPaymentData && window.convesiopayGooglePayPaymentData.token) {
                const googlePayToken = window.convesiopayGooglePayPaymentData.token;
                paymentMethodData.convesiopay_payment_token = String(googlePayToken);
                paymentMethodData.payment_method_type = String('googlepay');
                paymentMethodData.paymentmethod = String('googlepay');
                paymentMethodData.status = String('authorized');
                addHiddenField('convesiopay_payment_token', googlePayToken);
                addHiddenField('payment_method_type', 'googlepay');
            } else if (window.convesiopayPaymentToken && currentPaymentMethod === 'googlepay') {
                paymentMethodData.convesiopay_payment_token = String(window.convesiopayPaymentToken);
                paymentMethodData.payment_method_type = String('googlepay');
                paymentMethodData.paymentmethod = String('googlepay');
                paymentMethodData.status = String('authorized');
                addHiddenField('convesiopay_payment_token', window.convesiopayPaymentToken);
                addHiddenField('payment_method_type', 'googlepay');
            } else {
                // Fallback for BTCPay session
                paymentMethodData.paymentid = String('btc-session-' + btcPaySession);
                paymentMethodData.paymentmethod = String('btcpay');
                paymentMethodData.status = String('pending');
                paymentMethodData.convesiopay_payment_token = String('btc-session-' + btcPaySession);
                paymentMethodData.btcpay_session_id = String(btcPaySession || '');
            }
        }

        // Add payment method data as JSON (primary format)
        addHiddenField('payment_method_data', JSON.stringify(paymentMethodData));

        // IMPORTANT: Also add individual fields that the PHP gateway expects
        if (paymentConfirmedData && paymentConfirmedData.paymentMethod === 'btcpay') {
            addHiddenField('btcpay_payment_id', String(paymentConfirmedData.paymentId || ''));
            addHiddenField('btcpay_invoice_id', String(paymentConfirmedData.invoiceId || ''));
            addHiddenField('btcpay_status', String(paymentConfirmedData.status || ''));
            addHiddenField('btcpay_session_id', String(btcPaySession || ''));
        }
        
        // IMPORTANT: For ApplePay and Card, ensure token is in hidden field
        if (paymentConfirmedData && (paymentConfirmedData.paymentMethod === 'applepay' || paymentConfirmedData.paymentMethod === 'googlepay' || paymentConfirmedData.paymentMethod === 'card')) {
            const token = paymentConfirmedData.token || window.convesiopayPaymentToken || '';
            if (token) {
                addHiddenField('convesiopay_payment_token', token);
                if (paymentConfirmedData.paymentMethod === 'applepay') {
                    addHiddenField('payment_method_type', 'applepay');
                    addHiddenField('applepay_amount', String(paymentConfirmedData.amount || 0));
                    addHiddenField('applepay_currency', String(paymentConfirmedData.currency || 'USD'));
                } else if (paymentConfirmedData.paymentMethod === 'googlepay') {
                    addHiddenField('payment_method_type', 'googlepay');
                    addHiddenField('googlepay_amount', String(paymentConfirmedData.amount || 0));
                    addHiddenField('googlepay_currency', String(paymentConfirmedData.currency || 'USD'));
                }
            }
        } else if (window.convesiopayApplePayPaymentData && window.convesiopayApplePayPaymentData.token) {
            // Fallback for ApplePay
            addHiddenField('convesiopay_payment_token', window.convesiopayApplePayPaymentData.token);
            addHiddenField('payment_method_type', 'applepay');
            addHiddenField('applepay_amount', String(window.convesiopayApplePayPaymentData.amount || 0));
            addHiddenField('applepay_currency', String(window.convesiopayApplePayPaymentData.currency || 'USD'));
        } else if (window.convesiopayPaymentToken && currentPaymentMethod === 'applepay') {
            // Another fallback for ApplePay
            addHiddenField('convesiopay_payment_token', window.convesiopayPaymentToken);
            addHiddenField('payment_method_type', 'applepay');
        } else if (window.convesiopayGooglePayPaymentData && window.convesiopayGooglePayPaymentData.token) {
            addHiddenField('convesiopay_payment_token', window.convesiopayGooglePayPaymentData.token);
            addHiddenField('payment_method_type', 'googlepay');
            addHiddenField('googlepay_amount', String(window.convesiopayGooglePayPaymentData.amount || 0));
            addHiddenField('googlepay_currency', String(window.convesiopayGooglePayPaymentData.currency || 'USD'));
        } else if (window.convesiopayPaymentToken && currentPaymentMethod === 'googlepay') {
            addHiddenField('convesiopay_payment_token', window.convesiopayPaymentToken);
            addHiddenField('payment_method_type', 'googlepay');
        }

    }

    /**
     * Detect payment method from event data
     */
    function detectPaymentMethod(event) {
        if (!event.data) {
            return 'unknown';
        }

        // Check for explicit payment method
        if (event.data.paymentMethod) {
            return event.data.paymentMethod;
        }

        // Check for event type
        if (event.data.eventType) {
            return event.data.eventType;
        }

        // Check for BTCPay indicators
        if (event.data.invoiceId || event.data.qrCodeData || event.data.paymentUri) {
            return 'btcpay';
        }

        // Check for card indicators
        if (event.data.token && !event.data.invoiceId) {
            return 'card';
        }

        // Check for Apple Pay indicators
        if (event.data.applePayData || event.data.paymentMethod === 'applepay') {
            return 'applepay';
        }

        if (event.data.googlePayData || event.data.paymentMethod === 'googlepay') {
            return 'googlepay';
        }

        return 'card'; // Default fallback
    }

    /**
     * Handle checkout form submission (improved to be more robust)
     */
    function handleCheckoutSubmission(event) {

        if (!paymentConfirmedData) {
            // Payment not confirmed yet, prevent submission
            showErrorUnified('Please complete the payment process first.');
            
            // Prevent the default form submission
            if (event && event.preventDefault) {
                event.preventDefault();
            }
            return false;
        }

        
        // Add payment data to form before submission
        addPaymentDataToForm();
        
        // Hide any existing errors
        hideErrorUnified();
        
        return true;
    }

    /**
     * Add hidden field to checkout form
     */
    function addHiddenField(name, value) {
        const $form = getCheckoutForm();
        
        if (!$form.length) {
            // Fallback: try to find the form by other selectors (for Elementor compatibility)
            const $altForm = $('form.woocommerce-checkout, form[name="checkout"], form#order_review');
            if ($altForm.length) {
                $altForm.find('input[name="' + name + '"]').remove();
                $('<input>')
                    .attr('type', 'hidden')
                    .attr('name', name)
                    .attr('value', value)
                    .prependTo($altForm);
                return;
            }
            return;
        }

        // Remove existing field if present
        $form.find('input[name="' + name + '"]').remove();

        // CRITICAL: Use prependTo instead of appendTo
        // Prepending ensures the field is at the beginning of the form,
        // making it less likely to be removed by WooCommerce partial re-renders
        // which typically replace content sections further down in the form
        $('<input>')
            .attr('type', 'hidden')
            .attr('name', name)
            .attr('value', value)
            .prependTo($form);
    }

    /**
     * Get current cart total from the checkout page
     * @returns {number} Current cart total in cents
     */
    function getCurrentCartTotal() {
        // Try to get the total from the order review section first
        const orderTotal = $('.woocommerce-checkout-review-order-table .order-total .amount').text();

        if (orderTotal) {
            // Remove currency symbols and convert to number
            const cleanTotal = orderTotal.replace(/[^\d.,]/g, '').replace(',', '.');
            const total = parseFloat(cleanTotal);

            if (!isNaN(total)) {
                return Math.round(total * 100); // Convert to cents
            }
        }

        // Fallback to alternative selectors
        const altSelectors = [
            '.shop_table .order-total .amount',
            '.cart-subtotal .amount',
            '.order_total .amount'
        ];

        for (const selector of altSelectors) {
            const altElement = $(selector);
            if (altElement.length) {
                const altText = altElement.text().replace(/[^\d.,]/g, '').replace(',', '.');
                const altAmount = parseFloat(altText);
                if (!isNaN(altAmount)) {
                    return Math.round(altAmount * 100);
                }
            }
        }

        return 0;
    }

    /**
     * Monitor cart total changes and update component amount for ApplePay/BTCPay
     */
    function setupCartTotalMonitoring() {

        // Listen for WooCommerce checkout updates
        $(document.body).on('updated_checkout', function() {
            // Re-sync fee tracker from server-rendered DOM after checkout update
            initializeFeeFromDOM();
            
            const currentTotal = getCurrentCartTotal();

            // Check if total has changed
            if (currentTotal !== lastKnownCartTotal && currentTotal > 0) {

                lastKnownCartTotal = currentTotal;

                // Invalidate any stored Apple Pay auth so we never submit a stale amount
                clearApplePayAuthorizationIfSet();

                // Update component amount if component exists (for ApplePay, BTCPay)
                // Don't rely on currentPaymentMethod as it might not be set yet
                if (convesioPayComponent) {
                    updateComponentAmount(currentTotal);
                }
            }
        });

        // Also monitor manual changes to the checkout form
        $(document).on('change', 'form.checkout input, form.checkout select, form#order_review input, form#order_review select', function() {
            setTimeout(() => {
                const currentTotal = getCurrentCartTotal();

                if (currentTotal !== lastKnownCartTotal && currentTotal > 0) {

                    lastKnownCartTotal = currentTotal;

                    // Invalidate any stored Apple Pay auth so we never submit a stale amount
                    clearApplePayAuthorizationIfSet();

                    // Update component amount if component exists
                    if (convesioPayComponent) {
                        updateComponentAmount(currentTotal);
                    }
                }
            }, 500);
        });
    }

    /**
     * Update component amount when cart total changes
     * Recreates the ApplePay and BTCPay sessions with new amount
     */
    async function updateComponentAmount(newAmountInCents) {
        try {
            // Step 1: Unmount and destroy the old component
            if (convesioPayComponent) {
                try {
                    // Unmount the component if it has an unmount method
                    if (typeof convesioPayComponent.unmount === 'function') {
                        await convesioPayComponent.unmount();
                    }

                    // Destroy the component if it has a destroy method
                    if (typeof convesioPayComponent.destroy === 'function') {
                        convesioPayComponent.destroy();
                    }
                } catch (unmountError) {
                    // NotFoundError (code 8): container was already replaced by WooCommerce fragment update - ignore
                    if (unmountError && unmountError.name !== 'NotFoundError' && unmountError.code !== 8) {
                        console.warn('[ConvesioPay] Unmount during amount update:', unmountError);
                    }
                }

                // Clear the component reference
                convesioPayComponent = null;
                isComponentMounted = false;

                // Clear the container (may be new node after fragment replace)
                const container = document.getElementById('convesiopay-unified-payment-container');
                if (container) {
                    try {
                        container.innerHTML = '';
                    } catch (e) {
                        if (e && e.name !== 'NotFoundError' && e.code !== 8) {
                            console.warn('[ConvesioPay] Container clear:', e);
                        }
                    }
                }
            }

            // Step 2: Clear session state
            isSessionCreated = false;
            const hadBtcPaySession = btcPaySession !== null;
            btcPaySession = null;

            // Step 3: Create new BTCPay session with updated amount (only if BTC Pay is enabled)
            // GUARD: Only create BTC Pay session if BTC Pay is enabled
            if (isBtcpayEnabled()) {
                const sessionResult = await createBTCPaySession();

                // Only proceed if session creation was successful
                // If disabled or failed, continue without BTC Pay session
                if (sessionResult.success && !sessionResult.disabled) {
                    btcPaySession = sessionResult.session;
                } else if (sessionResult.disabled) {
                    // BTC Pay is disabled - continue without BTC Pay session
                    // Component will work with Card and Apple Pay only
                } else {
                    // Session creation failed but BTC Pay should be enabled
                    // BTCPay session creation failed during amount update - component will work without BTC Pay
                }
            } else {
                // BTC Pay is disabled - skip session creation
            }

            // Step 4: Create and mount new component
            await mountConvesioPayComponent();

            if (!convesioPayComponent) {
                return;
            }

            // Step 5: Get fresh order data with updated amount
            const orderData = getOrderData();

            // Override with the new amount (in case getOrderData() hasn't updated yet)
            orderData.amount = newAmountInCents;

            const config = getConfig();
            const integrationName = config.integration_name || config.integrationName;

            // Step 6: Create ApplePay session with new amount only when Apple Pay is enabled
            if (isApplePayEnabled()) {
                try {
                    await createApplePaySessionWithRetry(convesioPayComponent, {
                        integration: integrationName || 'PeachPay',
                        returnUrl: window.location.href,
                        amount: orderData.amount,
                        currency: orderData.currency,
                        email: orderData.email,
                        name: orderData.name
                    }, { maxAttempts: 3, delayMs: 600 });
                } catch (applePayError) {
                    // ApplePay session creation failed
                }
            }

            if (isGooglePayEnabled()) {
                try {
                    await createGooglePaySessionWithRetry(convesioPayComponent, {
                        integration: integrationName || 'PeachPay',
                        returnUrl: window.location.href,
                        orderNumber: orderData.orderNumber,
                        amount: orderData.amount,
                        currency: orderData.currency,
                        email: orderData.email,
                        name: orderData.name
                    }, { maxAttempts: 3, delayMs: 600 });
                } catch (googlePayError) {
                    // GooglePay session creation failed
                }
            }

            // Step 7: Create BTCPay intent with new session (only if BTC Pay is enabled and session exists)
            // GUARD: Only create BTC Pay intent if BTC Pay is enabled and we have a session
            if (isBtcpayEnabled() && btcPaySession) {
                try {
                    // Prepare BTCPay intent data
                    const btcPayIntentData = {
                        session: btcPaySession
                    };

                    // Create the BTCPay intent with the new session
                    await convesioPayComponent.createBTCPayIntent(btcPayIntentData);

                    // Re-setup the message listener
                    setupBTCPayMessageListener();
                } catch (btcPayError) {
                    // Silently fail if BTC Pay intent creation fails when BTC Pay is disabled
                    // Only log error if BTC Pay should be enabled
                    // BTCPay intent creation failed during amount update - handled silently
                }
            } else {
                // BTC Pay is disabled or no session - skip intent creation
            }

        } catch (error) {
            // Error updating amount
        }
    }

    /**
     * Get order data for ConvesioPay (following blocks pattern)
     */
    function getOrderData() {
        const config = getConfig();
        const orderPayData = config.order_pay || {};
        const orderData = {
            isValid: false,
            orderNumber: getOrderNumber(),
            amount: 0,
            currency: config.currency || 'USD',
            email: '',
            name: 'Customer',
            // Required address fields for ConvesioPay API
            billingAddress: {
                street: '123 Default Street',
                city: 'Default City',
                state: 'CA',
                postalCode: '90210',
                country: 'US'
            },
            shippingAddress: {
                street: '123 Default Street',
                city: 'Default City',
                state: 'CA',
                postalCode: '90210',
                country: 'US'
            }
        };

        // order-pay pages use an existing WC order, not a live cart.
        // Prefer server-provided data to avoid fragile DOM/cart scraping.
        if (isOrderPayContext() && orderPayData && orderPayData.order_id) {
            const orderTotal = parseFloat(orderPayData.total);
            if (!isNaN(orderTotal) && orderTotal > 0) {
                orderData.amount = Math.round(orderTotal * 100);
            }

            orderData.currency = orderPayData.currency || orderData.currency;
            orderData.email = orderPayData.billing_email || orderData.email;

            const firstName = orderPayData.billing_first_name || '';
            const lastName = orderPayData.billing_last_name || '';
            const fullName = (firstName + ' ' + lastName).trim();
            if (fullName) {
                orderData.name = fullName;
            }

            if (orderPayData.billing_address && orderPayData.billing_address.street) {
                orderData.billingAddress = {
                    street: orderPayData.billing_address.street,
                    city: orderPayData.billing_address.city || 'Default City',
                    state: orderPayData.billing_address.state || 'CA',
                    postalCode: orderPayData.billing_address.postalCode || '90210',
                    country: orderPayData.billing_address.country || 'US'
                };
            }

            if (orderPayData.shipping_address && orderPayData.shipping_address.street) {
                orderData.shippingAddress = {
                    street: orderPayData.shipping_address.street,
                    city: orderPayData.shipping_address.city || 'Default City',
                    state: orderPayData.shipping_address.state || 'CA',
                    postalCode: orderPayData.shipping_address.postalCode || '90210',
                    country: orderPayData.shipping_address.country || 'US'
                };
            } else {
                orderData.shippingAddress = { ...orderData.billingAddress };
            }

            orderData.isValid = orderData.amount > 0;
            return orderData;
        }

        // Get amount from order total
        const totalElement = $('.order-total .amount') || $('.cart-total .amount');

        if (totalElement.length) {
            const totalText = totalElement.text().replace(/[^\d.]/g, '');

            const amount = parseFloat(totalText);

            if (!isNaN(amount)) {
                orderData.amount = Math.round(amount * 100); // Convert to cents
            }
        } else {

            // Try more selectors
            const altSelectors = [
                '.woocommerce-checkout-review-order-table .order-total .amount',
                '.shop_table .order-total .amount',
                '.cart-subtotal .amount',
                '.order_total .amount'
            ];

            for (const selector of altSelectors) {
                const altElement = $(selector);
                if (altElement.length) {
                    const altText = altElement.text().replace(/[^\d.]/g, '');
                    const altAmount = parseFloat(altText);
                    if (!isNaN(altAmount)) {
                        orderData.amount = Math.round(altAmount * 100);
                        break;
                    }
                }
            }
        }

        // Get customer data from form fields
        const emailField = $('#billing_email');
        if (emailField.length && emailField.val()) {
            orderData.email = emailField.val();
        } else {
            orderData.email = 'customer@example.com';
        }

        const firstNameField = $('#billing_first_name');
        const lastNameField = $('#billing_last_name');
        if (firstNameField.length && lastNameField.length) {
            orderData.name = (firstNameField.val() + ' ' + lastNameField.val()).trim() || 'Customer';
        }

        // Get billing address
        const address1Field = $('#billing_address_1');
        const address2Field = $('#billing_address_2');
        const cityField = $('#billing_city');
        const stateField = $('#billing_state');
        const postcodeField = $('#billing_postcode');
        const countryField = $('#billing_country');

        if (address1Field.length && address1Field.val() && address1Field.val().trim()) {
            orderData.billingAddress = {
                street: address1Field.val().trim() + (address2Field.val() ? ' ' + address2Field.val().trim() : ''),
                city: cityField.val() || 'Default City',
                state: stateField.val() || 'CA',
                postalCode: postcodeField.val() || '90210',
                country: countryField.val() || 'US'
            };
        }

        // Use billing address as shipping if shipping fields don't exist or are empty
        const shippingAddress1Field = $('#shipping_address_1');
        if (shippingAddress1Field.length && shippingAddress1Field.val() && shippingAddress1Field.val().trim()) {
            const shippingAddress2Field = $('#shipping_address_2');
            const shippingCityField = $('#shipping_city');
            const shippingStateField = $('#shipping_state');
            const shippingPostcodeField = $('#shipping_postcode');
            const shippingCountryField = $('#shipping_country');

            orderData.shippingAddress = {
                street: shippingAddress1Field.val().trim() + (shippingAddress2Field.val() ? ' ' + shippingAddress2Field.val().trim() : ''),
                city: shippingCityField.val() || 'Default City',
                state: shippingStateField.val() || 'CA',
                postalCode: shippingPostcodeField.val() || '90210',
                country: shippingCountryField.val() || 'US'
            };
        } else {
            // Use billing address as shipping
            orderData.shippingAddress = { ...orderData.billingAddress };
        }

        // Ensure valid data
        orderData.isValid = orderData.amount > 0;

        // Final validation - ensure street addresses are never empty
        if (!orderData.billingAddress.street || orderData.billingAddress.street.trim().length === 0) {
            orderData.billingAddress.street = '123 Default Street';
        }
        if (!orderData.shippingAddress.street || orderData.shippingAddress.street.trim().length === 0) {
            orderData.shippingAddress.street = '123 Default Street';
        }

        return orderData;
    }

    /**
     * Get temporary session identifier for checkout (before order is created)
     * The real order number will be available after woocommerce_checkout_create_order
     */
    function getOrderNumber() {
        const config = getConfig();
        if (isOrderPayContext() && config.order_pay && config.order_pay.order_id) {
            return String(config.order_pay.order_id);
        }

        // Try to get from URL parameters (for order-received page with real order)
        const urlParams = new URLSearchParams(window.location.search);
        const orderId = urlParams.get('order');

        if (orderId) {
            return orderId;
        }

        // For checkout page: Use temporary session ID that will be linked to real order later
        // This matches the WooCommerce session approach you suggested

        // Try to get existing temp session from WooCommerce (passed via localized script)
        if (window.peachpay_convesiopay_unified_data && window.peachpay_convesiopay_unified_data.temp_session_id) {
            const tempSessionId = window.peachpay_convesiopay_unified_data.temp_session_id;
            return tempSessionId;
        }

        // Fallback: Generate temp session ID (will be linked to real order via PHP hooks)
        const timestamp = Date.now();
        const random = Math.floor(Math.random() * 10000);
        const tempSessionId = `TEMP-${timestamp}-${random}`;

        return tempSessionId;
    }

    /**
     * Create BTCPay session via AJAX call (following blocks pattern)
     * 
     * STRICT GUARD: Returns early with success:false (not an error) when disabled
     * to prevent any error messages from being shown.
     */
    function createBTCPaySession() {
        // STRICT CHECK: Do not create BTCPay sessions when the method is disabled in
        // PeachPay/WooCommerce settings. This prevents unnecessary
        // ConvesioPay API calls and avoids BTCPay behaviour on sites
        // that have explicitly disabled crypto.
        if (!isBtcpayEnabled()) {
            // Return success:false with a message indicating it's disabled
            // This is NOT an error - it's expected behavior when disabled
            return Promise.resolve({ success: false, message: 'BTCPay payment method is disabled', disabled: true });
        }

        // If session already created and exists, return it
        if (isSessionCreated && btcPaySession) {
            return Promise.resolve({ success: true, session: btcPaySession });
        }

        return new Promise((resolve) => {
            try {
                const orderData = getOrderData();
                if (!orderData.isValid) {
                    throw new Error('Unable to get order details');
                }

                const config = getConfig();
                const requestData = {
                    action: 'peachpay_convesiopay_create_btcpay_session',
                    nonce: window.peachpay_convesiopay_unified_data?.nonce || '',
                    integration: config.integration_name,
                    returnUrl: window.location.href,
                    orderNumber: orderData.orderNumber,
                    amount: orderData.amount,
                    currency: orderData.currency,
                    email: orderData.email,
                    name: orderData.name,
                    // Include required address fields for ConvesioPay API
                    billingAddress: JSON.stringify(orderData.billingAddress),
                    shippingAddress: JSON.stringify(orderData.shippingAddress)
                };

                $.ajax({
                    url: window.peachpay_convesiopay_unified_data?.ajax_url || '/wp-admin/admin-ajax.php',
                    method: 'POST',
                    data: requestData,
                    success: function(sessionResponse) {
                        if (sessionResponse.success && sessionResponse.data?.session) {
                            // Store session
                            btcPaySession = sessionResponse.data.session;
                            isSessionCreated = true;
                            resolve({ success: true, session: btcPaySession });
                        } else {
                            // Extract message from WordPress AJAX response structure
                            // WordPress error responses have message in data.message or directly in message
                            const errorMessage = sessionResponse.data?.message || sessionResponse.message || 'Failed to create BTCPay session';
                            
                            // Check if the error is because BTC Pay is disabled
                            const isDisabled = errorMessage.toLowerCase().includes('disabled') || 
                                             errorMessage.toLowerCase().includes('btcpay payment method is disabled');
                            
                            // If disabled, mark it as such so the error won't be shown
                            resolve({ 
                                success: false, 
                                message: errorMessage,
                                disabled: isDisabled
                            });
                        }
                    },
                    error: function(xhr, status, error) {
                        // On AJAX error, check if BTC Pay is still enabled before reporting error
                        // If disabled, this is expected behavior
                        const isDisabled = !isBtcpayEnabled();
                        resolve({ 
                            success: false, 
                            message: 'AJAX request failed: ' + error,
                            disabled: isDisabled
                        });
                    }
                });

            } catch (error) {
                resolve({ success: false, message: error.message });
            }
        });
    }

    /**
     * Setup BTCPay message listener for iframe communication (following blocks pattern)
     */
    function setupBTCPayMessageListener() {
        // If BTCPay is disabled, do not attach any listeners.
        if (!isBtcpayEnabled()) {
            return;
        }

        window.addEventListener('message', (event) => {
            // Verify the origin is from BTCPay
            if (!event.origin.includes('btcpay') && !event.origin.includes('convesiopay')) {
                // Still check the data in case origin is different but message is valid
                if (event.data && (
                    (typeof event.data === 'string' && event.data.includes('Processing')) ||
                    (typeof event.data === 'object' && event.data.status === 'Processing')
                )) {
                    // Process anyway
                } else {
                    return;
                }
            }

            try {
                let messageData;

                // Handle both string and object message data
                if (typeof event.data === 'string') {
                    try {
                        messageData = JSON.parse(event.data);
                    } catch (e) {
                        messageData = { type: event.data };
                    }
                } else {
                    messageData = event.data;
                }

                // Check for payment status messages - 'Processing' means payment received
                if (messageData.status === 'Processing') {
                    // Get order data for complete payment information
                    const orderData = getOrderData();

                    // Extract payment details from the message with complete order info
                    const extractedData = {
                        invoiceId: messageData.invoiceId,
                        status: 'Processing',
                        paymentId: messageData.invoiceId,
                        paymentMethod: 'btcpay',
                        amount: orderData.amount || 0,
                        currency: orderData.currency || 'USD',
                        orderNumber: orderData.orderNumber || 'UNKNOWN'
                    };

                    paymentConfirmedData = extractedData;
                    currentPaymentMethod = 'btcpay';

                    // Add form data and trigger WooCommerce checkout event
                    addPaymentDataToForm();
                    $(document.body).trigger('checkout_place_order_peachpay_convesiopay_unified');

                    // Also auto-click the place order button after a delay (like blocks checkout)
                    setTimeout(() => {
                        autoClickPlaceOrderButton();
                    }, 500);
                }

            } catch (error) {
                // Ignore processing errors
            }
        });
    }

    /**
     * Show error message (improved to match blocks version)
     */
    function showError(message) {
        // Try WooCommerce notices first
        const $notices = $('.woocommerce-notices-wrapper').first();
        if ($notices.length) {
            $notices.html('<div class="woocommerce-error">' + message + '</div>');
            $('html, body').animate({ scrollTop: $notices.offset().top - 100 }, 500);
        } else {
            // Fallback to custom error display (matching blocks version)
            const errorDiv = $('<div class="convesiopay-unified-error" style="color: #721c24; padding: 12px; margin: 10px 0; background-color: #f8d7da; border: 1px solid #f5c6cb; border-radius: 4px; font-family: inherit;"><strong>Payment Error:</strong> ' + message + '</div>');
            
            // Insert error message near the payment container
            const $container = $('#convesiopay-unified-payment-container');
            if ($container.length) {
                $container.before(errorDiv);
                
                // Auto-remove after 8 seconds
                setTimeout(() => {
                    errorDiv.remove();
                }, 8000);
            } else {
                // Last resort: alert (for critical errors)
                if (message.includes('token') || message.includes('payment')) {
                    alert('Payment Error: ' + message);
                }
            }
        }
    }

    /**
     * Hide error message (matching blocks version)
     */
    function hideError() {
        // Clear WooCommerce notices
        const $notices = $('.woocommerce-notices-wrapper').first();
        if ($notices.length) {
            $notices.empty();
        }
        
        // Clear custom error messages
        $('.convesiopay-unified-error').remove();
    }

    // Add CSS to hide payment method label when it's the only payment method
    function addClassicCheckoutStyles() {
        const styleId = 'convesiopay-unified-classic-styles';
        if (!document.getElementById(styleId)) {
            const style = document.createElement('style');
            style.id = styleId;
            style.textContent = `
                /* Hide payment method label when ConvesioPay is the only payment method */
                ul.wc_payment_methods li.payment_method_peachpay_convesiopay_unified:only-child > label {
                    display: none !important;
                }
                /* Remove padding when it's the only payment method */
                ul.wc_payment_methods li.payment_method_peachpay_convesiopay_unified:only-child .payment_box {
                    padding: 0 !important;
                    margin: 0 !important;
                }

                /* Fixed Card Holder Name Input height and border */
                ul.wc_payment_methods li.payment_method_peachpay_convesiopay_unified input[name='holderName'] {
                    min-height: auto !important;
                    border: none !important;
                }

                /* Fixed Card Holder Name Input Margin */
                #payment ul li input[type=text][name='holderName'] {
                    margin: 0 !important;
                }

                /* Fixed Adyen Checkbox label display */
                ul.wc_payment_methods li.payment_method_peachpay_convesiopay_unified .adyen-checkout__store-details .adyen-checkout__checkbox::before {
                    display: block !important;
                }
                #convesiopay-unified-payment-container.loading-in-progress {
                    min-height: 300px !important;
                    min-width: 100% !important;
                    display: flex !important;
                    align-items: center !important;
                    justify-content: center !important;
                }
                #convesiopay-unified-payment-container.loading-in-progress .adyen-checkout,
                #convesiopay-unified-payment-container.loading-in-progress [class*="adyen-checkout"] {
                    min-height: 280px !important;
                    min-width: 100% !important;
                    display: flex !important;
                    align-items: center !important;
                    justify-content: center !important;
                }
            `;
            document.head.appendChild(style);
        }
    }

    // // Initialize when document is ready
    $(document).ready(function() {
        
        addClassicCheckoutStyles();
        initConvesioPayClassic();
        setupCartTotalMonitoring();

        // Initialize last known cart total
        lastKnownCartTotal = getCurrentCartTotal();
        
        // FALLBACK: If the container exists but was mounted by a different mechanism,
        // still bind the accordion fee updates after a delay
        // BUT skip if this is a Blocks checkout - let the Blocks script handle it
        setTimeout(function() {
            
            // Check if this is a Blocks checkout - skip if so to avoid duplicate bindings
            const isBlocksCheckout = document.querySelector('.wc-block-checkout') || 
                                     document.querySelector('.wp-block-woocommerce-checkout') ||
                                     document.querySelector('.wc-convesiopay-unified-blocks-content');
            
            if (isBlocksCheckout) {
                return;
            }
            
            // Try multiple possible container selectors (Classic checkout only)
            const possibleContainers = [
                document.getElementById('convesiopay-unified-payment-container'),
                document.querySelector('.convesiopay-payment-container'),
                document.querySelector('.adyen-checkout__payment-methods-list'),
                document.querySelector('[class*="adyen-payment"]')
            ];
            
            // Find first existing container
            let container = null;
            for (const c of possibleContainers) {
                if (c) {
                    container = c;
                    break;
                }
            }
            
            if (container && !container.dataset.feeBindingAdded) {
                // Use the found container for binding
                bindAccordionFeeUpdatesOnContainer(container);
            } else if (!container) {
                // Log all elements with payment-related classes for debugging
                const paymentElements = document.querySelectorAll('[class*="payment"], [class*="adyen"], [class*="cpay"]');
                // Debug: payment elements found on page (removed for production)
            }
        }, 1500); // Wait for component to be fully rendered
    });

    // Reinitialize on checkout update
    /**
     * Handle BTCPay payment (following blocks pattern)
     */
    function handleBTCPayPayment(event) {
        // For BTCPay, only proceed if status is 'Processing' (not 'Pending')
        if (event.paymentData && event.paymentData.status === 'Processing') {

            // Store payment data and trigger auto-click
            paymentConfirmedData = {
                paymentId: event.paymentData.paymentId,
                invoiceId: event.paymentData.paymentId,
                status: event.paymentData.status,
                amount: event.paymentData.amount,
                currency: event.paymentData.currency,
                orderNumber: event.paymentData.orderNumber,
                paymentMethod: 'btcpay'
            };

            currentPaymentMethod = 'btcpay';

            setTimeout(() => {
                autoClickPlaceOrderButton();
            }, 500);
        } else if (event.paymentData) {
        }
    }

    /**
     * Auto-click place order button for classic checkout (following blocks pattern)
     */
    function autoClickPlaceOrderButton() {
        // Use stored payment data
        if (!paymentConfirmedData) {

            // Disable the place order button
            const placeOrderButton = getCheckoutForm().find('#place_order');
            if (placeOrderButton.length) {
                placeOrderButton.prop('disabled', true);
                placeOrderButton.css({
                    'opacity': '0.5',
                    'cursor': 'not-allowed'
                });
            }
            return;
        }


        // Add payment data to form before submission
        addPaymentDataToForm();

        // Find and click the place order button (classic checkout)
        // Priority 1: The exact button you specified
        let placeOrderButton = $('button[type="submit"][name="woocommerce_checkout_place_order"][id="place_order"]');

        // Priority 2: Try by ID first (most common)
        if (!placeOrderButton.length) {
            placeOrderButton = getCheckoutForm().find('#place_order');
        }

        // Priority 3: Try by name attribute
        if (!placeOrderButton.length) {
            placeOrderButton = $('button[name="woocommerce_checkout_place_order"]');
        }

        // Priority 4: Try generic submit button
        if (!placeOrderButton.length) {
            placeOrderButton = getCheckoutForm().find('button[type="submit"]');
        }

        if (placeOrderButton.length) {
            // Enable the button first
            placeOrderButton.prop('disabled', false);
            placeOrderButton.css({
                'opacity': '1',
                'cursor': 'pointer'
            });

            // Trigger the click
            placeOrderButton.trigger('click');
        }
    }

    // Diagnostic: store container reference before fragment replace (confirm root cause for NotFoundError)
    $(document.body).on('update_checkout', function() {
        var el = document.getElementById('convesiopay-unified-payment-container');
        window._oldConvesioContainer = el || null;
        console.log('[ConvesioPay] update_checkout (before fragment replace), stored container:', !!el);
    });

    $(document.body).on('updated_checkout', function() {
        // CRITICAL: Snapshot payment state BEFORE unmount. unmountConvesioPayComponentSafely() may call
        // resetSessionState() when no component exists, which clears paymentConfirmedData — so we must
        // capture it first to avoid losing token/method and forcing re-authorization.
        const savedPaymentData = paymentConfirmedData;
        const savedPaymentMethod = currentPaymentMethod;
        const savedToken = window.convesiopayPaymentToken;

        // Diagnostic: confirm old container was removed and current node is new (root cause of NotFoundError)
        if (window._oldConvesioContainer) {
            var stillInDoc = document.contains(window._oldConvesioContainer);
            var currentEl = document.getElementById('convesiopay-unified-payment-container');
            var isSameNode = currentEl === window._oldConvesioContainer;
            console.log('[ConvesioPay] updated_checkout (after fragment replaced). Old container still in document?', stillInDoc, '| Current container is same node?', isSameNode);
        } else {
            console.log('[ConvesioPay] updated_checkout (after fragment replaced)');
        }
        // Unmount ConvesioPay before re-init so we don't hold a reference to a replaced container.
        // When country/address changes, WooCommerce replaces the fragment and the old React root can throw NotFoundError on removeChild.
        unmountConvesioPayComponentSafely();

        // Reset session state (component refs etc.). Payment data already saved above.
        resetSessionState();
        
        // If we had valid payment data with a token, restore it and re-add form fields
        // This ensures payment data persists across checkout updates (e.g., shipping method changes)
        if (savedPaymentData && savedPaymentData.token) {
            paymentConfirmedData = savedPaymentData;
            currentPaymentMethod = savedPaymentMethod;
            window.convesiopayPaymentToken = savedToken;
            
            // Re-add form fields after a short delay to ensure DOM is fully updated
            setTimeout(function() {
                addPaymentDataToForm();
            }, 100);
        }
        mountConvesioPayComponentAttempt = 0;
        setTimeout(initConvesioPayClassic, 500);
    });

})(jQuery);
