let walletPaymentsInitialized = false;
let walletInstances = {}; // Cache wallet instances

// Global helper functions to avoid duplication
/**********************************************************/
/** Helper: transformContact                             **/
/**********************************************************/
function transformContact( contact, isAfterpay, fallback = {} ) {
	// If there's no contact at all, we immediately fallback.
	if ( ! contact || typeof contact !== 'object' ) {
		contact = {};
	}

	const {
		familyName,
		givenName,
		region, // Afterpay uses `region`
		state, // Apple/Google Pay uses `state`
		country, // Afterpay uses `country`
		countryCode, // Apple/Google uses `countryCode`
		city,
		addressLines,
		postalCode,
		phone,
		email,
	} = contact;

	const {
		first_name: fallbackGivenName = '',
		last_name: fallbackFamilyName = '',
		address_1: fallbackAddress1 = '',
		address_2: fallbackAddress2 = '',
		city: fallbackCity = '',
		state: fallbackState = '',
		country: fallbackCountry = '',
		postcode: fallbackPostcode = '',
		phone: fallbackPhone = '',
		email: fallbackEmail = '',
	} = fallback;

	// Use || instead of ?? to handle empty strings from Apple Pay
	const mergedGivenName = givenName || fallbackGivenName;
	const mergedFamilyName = familyName || fallbackFamilyName;
	const mergedCity = city || fallbackCity;
	const mergedPostalCode = postalCode || fallbackPostcode;
	const mergedEmail = email || fallbackEmail;
	const mergedPhone = phone || fallbackPhone;

	// For region/state
	const mergedState = isAfterpay
		? region || fallbackState
		: state || region || fallbackState;

	// For country / countryCode
	const mergedCountry = isAfterpay
		? country || fallbackCountry
		: countryCode || country || fallbackCountry;

	// For address lines
	let mergedAddressLines = [];
	if ( Array.isArray( addressLines ) && addressLines.length > 0 ) {
		mergedAddressLines = addressLines;
	} else {
		// Merge fallback address_1 and address_2 if present
		mergedAddressLines = [ fallbackAddress1, fallbackAddress2 ].filter(
			Boolean
		);
	}

	return {
		givenName: mergedGivenName,
		familyName: mergedFamilyName,
		state: mergedState,
		countryCode: mergedCountry,
		city: mergedCity,
		addressLines: mergedAddressLines,
		postalCode: mergedPostalCode,
		phone: mergedPhone,
		email: mergedEmail,
	};
}

/**********************************************************/
/** Helper: isBillingComplete                            **/
/**********************************************************/
function isBillingComplete( billingContact ) {
	// Define whatever fields you consider "required"
	// Adjust as needed for your store's requirements
	return (
		billingContact &&
		billingContact.givenName &&
		billingContact.familyName &&
		billingContact.addressLines &&
		billingContact.addressLines.length > 0 &&
		billingContact.city &&
		billingContact.state &&
		billingContact.postalCode &&
		billingContact.countryCode
	);
}

/**********************************************************/
/** Helper: isExistingBillingComplete                    **/
/** Check if WooCommerce billing form fields are filled  **/
/**********************************************************/
function isExistingBillingComplete() {
	const firstName = jQuery( '#billing_first_name' ).val();
	const lastName = jQuery( '#billing_last_name' ).val();
	const address1 = jQuery( '#billing_address_1' ).val();
	const city = jQuery( '#billing_city' ).val();
	const postcode = jQuery( '#billing_postcode' ).val();
	const country = jQuery( '#billing_country' ).val();

	return (
		firstName && firstName.trim() &&
		lastName && lastName.trim() &&
		address1 && address1.trim() &&
		city && city.trim() &&
		postcode && postcode.trim() &&
		country && country.trim()
	);
}

/**********************************************************/
/** Helper: isExistingShippingComplete                   **/
/** Check if WooCommerce shipping form fields are filled **/
/**********************************************************/
function isExistingShippingComplete() {
	const firstName = jQuery( '#shipping_first_name' ).val();
	const lastName = jQuery( '#shipping_last_name' ).val();
	const address1 = jQuery( '#shipping_address_1' ).val();
	const city = jQuery( '#shipping_city' ).val();
	const postcode = jQuery( '#shipping_postcode' ).val();
	const country = jQuery( '#shipping_country' ).val();

	return (
		firstName && firstName.trim() &&
		lastName && lastName.trim() &&
		address1 && address1.trim() &&
		city && city.trim() &&
		postcode && postcode.trim() &&
		country && country.trim()
	);
}

/**********************************************************/
/** Helper: cleanupWalletInstances                       **/
/**********************************************************/
function cleanupWalletInstances() {
	// Destroy existing wallet instances to prevent memory leaks
	for (let key in walletInstances) {
		if (walletInstances[key]) {
			// Reset the attached flag
			if (walletInstances[key]._isAttached) {
				walletInstances[key]._isAttached = false;
			}
			// Try to destroy if method exists
			if (typeof walletInstances[key].destroy === 'function') {
				try {
					walletInstances[key].destroy();
				} catch (e) {
					console.warn(`Error destroying ${key} instance:`, e);
				}
			}
		}
		delete walletInstances[key];
	}
}

async function initWalletPayments(
	payments,
	walletPaymentRequest,
	needsShipping,
	couponApplied
) {
	if ( walletPaymentsInitialized ) {
		return; // Don't run again
	}
	walletPaymentsInitialized = true;

	if ( ! payments ) {
		console.error( 'Payments object is required for wallet payments.' );
		return;
	}

	// Initialize or reinitialize wallet buttons with updated payment request
	async function reinitializeWalletButtons() {
		const updatedWalletPaymentRequest = await initPaymentRequest(
			payments,
			needsShipping,
			couponApplied
		);

		if ( updatedWalletPaymentRequest ) {
			await attachWalletButtons(
				updatedWalletPaymentRequest,
				payments,
				needsShipping,
				couponApplied
			);
		}
	}

	// Attach initial wallet buttons on page load
	if ( walletPaymentRequest ) {
		await attachWalletButtons(
			walletPaymentRequest,
			payments,
			needsShipping,
			couponApplied
		);
	}
}

async function attachWalletButtons(
	paymentRequest,
	payments,
	needsShipping,
	couponApplied
) {
	// Ensure payments object exists
	if (!payments) {
		console.error('Payments object is required for wallet buttons');
		return;
	}

	// Add event listeners to paymentRequest for Apple Pay / Google Pay
	// These must be added before wallet button initialization
	// Using window-scoped functions from utils.js for proper cross-script access
	if (paymentRequest && !paymentRequest._walletListenersAdded) {
		paymentRequest.addEventListener(
			'shippingcontactchanged',
			async ( shippingContact ) => {
				return await window.handleShippingAddressChanged( shippingContact );
			}
		);
		paymentRequest.addEventListener(
			'shippingoptionchanged',
			async ( option ) => {
				return await window.handleShippingOptionChanged( option );
			}
		);
		paymentRequest._walletListenersAdded = true;
	}

	// Track which wallets were successfully initialized
	let activeWallets = 0;

	// Get all wallet containers and remove the has-wallets class initially
	const walletContainers = document.querySelectorAll('.sws-legacy-wallets');
	walletContainers.forEach(container => {
		container.classList.remove('has-wallets');
	});

	/**********************************************************/
	/** handleTokenizationAndVerification                    **/
	/**********************************************************/
	async function handleTokenizationAndVerification(
		walletInstance,
		walletType
	) {
		if (!walletInstance) {
			console.error(`${walletType} instance is null or undefined`);
			return;
		}

		try {
			const tokenResult = await walletInstance.tokenize();

			if ( tokenResult.status === 'OK' ) {
				// Attach raw nonce/token to a hidden field
				attachTokenToForm( tokenResult.token );

				// We assume `walletType === "AfterpayClearpay"` for Afterpay logic
				const isAfterpay = walletType === 'Afterpay';

				// Ensure "Ship to a different address" is checked if we have shipping details
				const shipToDifferentAddressCheckbox = jQuery(
					'#ship-to-different-address-checkbox'
				);
				if ( shipToDifferentAddressCheckbox.length && ! shipToDifferentAddressCheckbox.is( ':checked' ) ) {
					shipToDifferentAddressCheckbox.prop( 'checked', true );
					jQuery( 'div.shipping_address' ).show(); // Make sure shipping fields are visible
				}

				/*******************************************************/
				/** Extract shipping & billing from tokenResult      **/
				/*******************************************************/
				const shippingDetails =
					tokenResult?.details?.shipping?.contact || {};
				const billingDetails = tokenResult?.details?.billing || {};

				// In case your legacy checkout still needs to fallback to
				// current form values if the contact is missing data:
				const fallbackShipping = {
					first_name: jQuery( '#shipping_first_name' ).val(),
					last_name: jQuery( '#shipping_last_name' ).val(),
					address_1: jQuery( '#shipping_address_1' ).val(),
					address_2: jQuery( '#shipping_address_2' ).val(),
					city: jQuery( '#shipping_city' ).val(),
					state: jQuery( '#shipping_state' ).val(),
					postcode: jQuery( '#shipping_postcode' ).val(),
					country: jQuery( '#shipping_country' ).val(),
					phone: jQuery( '#shipping_phone' ).val(),
					email: jQuery( '#billing_email' ).val(), // Sometimes shipping doesn't have its own email
				};
				const fallbackBilling = {
					first_name: jQuery( '#billing_first_name' ).val(),
					last_name: jQuery( '#billing_last_name' ).val(),
					address_1: jQuery( '#billing_address_1' ).val(),
					address_2: jQuery( '#billing_address_2' ).val(),
					city: jQuery( '#billing_city' ).val(),
					state: jQuery( '#billing_state' ).val(),
					postcode: jQuery( '#billing_postcode' ).val(),
					country: jQuery( '#billing_country' ).val(),
					phone: jQuery( '#billing_phone' ).val(),
					email: jQuery( '#billing_email' ).val(),
				};

				// Transform shipping contact
				const shippingContact = transformContact(
					shippingDetails,
					isAfterpay,
					fallbackShipping
				);

				// Transform billing contact
				let billingContact = transformContact(
					billingDetails,
					isAfterpay,
					fallbackBilling
				);

				// If billing is incomplete, prioritize WooCommerce billing fields
				if ( ! isBillingComplete( billingContact ) ) {
					// First try WooCommerce billing form fields directly
					const wooCommerceBilling = transformContact(
						{},  // No Apple Pay data - use fallback only
						isAfterpay,
						fallbackBilling  // Use WooCommerce BILLING form fields
					);

					// Only use shipping as last resort if WooCommerce billing is also empty
					if ( ! isBillingComplete( wooCommerceBilling ) ) {
						const shippingAsBilling = transformContact(
							shippingDetails,
							isAfterpay,
							fallbackBilling  // Still use billing fallback, not shipping
						);
						billingContact = {
							...shippingAsBilling,
							email:
								billingContact.email ||
								shippingAsBilling.email ||
								shippingDetails.email,
						};
					} else {
						// Use WooCommerce billing as primary fallback
						billingContact = {
							...wooCommerceBilling,
							email: billingContact.email || wooCommerceBilling.email,
						};
					}
				}

				// Verify buyer for SCA compliance (3D Secure)
				const orderTotal = SquareConfig.orderTotal || '0.00';
				const verificationDetails = {
					intent: 'CHARGE',
					amount: orderTotal,
					currencyCode: SquareConfig.currency || 'USD',
					billingContact: {
						givenName: billingContact.givenName || '',
						familyName: billingContact.familyName || '',
						email: billingContact.email || '',
						phone: billingContact.phone || '',
						country: billingContact.countryCode || '',
						region: billingContact.state || '',
						city: billingContact.city || '',
						postalCode: billingContact.postalCode || '',
						addressLines: billingContact.addressLines || [],
					},
				};

				try {
					const verificationResult = await payments.verifyBuyer(
						tokenResult.token,
						verificationDetails
					);
					if ( verificationResult && verificationResult.token ) {
						attachVerificationTokenToForm( verificationResult.token );
					}
				} catch ( verifyError ) {
					console.error( 'Buyer verification failed:', verifyError );
					// Continue anyway for non-SCA regions, but log the error
				}

				// Shipping:
				// Only update shipping if store needs shipping AND existing shipping is incomplete
				const shouldUpdateShipping = typeof needsShipping !== 'undefined' && needsShipping && ! isExistingShippingComplete();

				if ( shouldUpdateShipping ) {
					jQuery( '#shipping_first_name' ).val(
						shippingContact.givenName || ''
					);
					jQuery( '#shipping_last_name' ).val(
						shippingContact.familyName || ''
					);
					jQuery( '#shipping_company' ).val( '' );
					jQuery( '#shipping_address_1' ).val(
						shippingContact.addressLines[ 0 ] || ''
					);
					jQuery( '#shipping_address_2' ).val(
						shippingContact.addressLines[ 1 ] || ''
					);
					jQuery( '#shipping_city' ).val(
						shippingContact.city || ''
					);
					jQuery( '#shipping_state' ).val(
						shippingContact.state || ''
					);
					jQuery( '#shipping_postcode' ).val(
						shippingContact.postalCode || ''
					);
					jQuery( '#shipping_country' ).val(
						shippingContact.countryCode || ''
					);
					jQuery( '#shipping_phone' ).val(
						shippingContact.phone || ''
					);
				}

				/*********************************************************/
				/** Update Legacy Billing & Shipping form fields       **/
				/*********************************************************/
				// Only update billing fields if existing billing is incomplete
				const shouldUpdateBilling = ! isExistingBillingComplete();

				if ( shouldUpdateBilling ) {
					// — now country/state —
					jQuery( '#billing_country' )
						.val( billingContact.countryCode || '' )
						.trigger( 'change' ); // ⬅️ rebuild states
				}

				// give WooCommerce a moment to repopulate the state <select>
				setTimeout( function () {
					if ( shouldUpdateBilling ) {
						jQuery( '#billing_state' )
							.val( billingContact.state || '' )
							.trigger( 'change' );

						// Billing:
						jQuery( '#billing_first_name' ).val(
							billingContact.givenName || ''
						);
						jQuery( '#billing_last_name' ).val(
							billingContact.familyName || ''
						);
						jQuery( '#billing_company' ).val( '' ); // no company in token result
						jQuery( '#billing_address_1' ).val(
							billingContact.addressLines[ 0 ] || ''
						);
						jQuery( '#billing_address_2' ).val(
							billingContact.addressLines[ 1 ] || ''
						);
						// … your other field‐fills …
						jQuery( '#billing_city' ).val( billingContact.city || '' );
						jQuery( '#billing_postcode' ).val(
							billingContact.postalCode || ''
						);

						// … then the rest …
						jQuery( '#billing_phone' ).val(
							billingContact.phone || ''
						);
						jQuery( '#billing_email' ).val(
							billingContact.email || ''
						);
					}

					// Handle both checkout and pay-for-order forms
					const $form = jQuery( 'form.checkout, form#order_review' );
					$form.trigger( 'submit' );
				}, 100 );
			} else {
				// Clear stored tokens or error-handling
				clearStoredTokens();
				if ( tokenResult.status !== 'Cancel' ) {
					const errorMessage = tokenResult.errors
						? tokenResult.errors.map(e => e.message || e).join(', ')
						: 'Unknown error';
					logPaymentError(`${walletType} payment failed: ${errorMessage}`);
				}
			}
		} catch ( error ) {
			clearStoredTokens();
			logPaymentError(
				`${ walletType } tokenization or verification error: ${ error.message }`
			);
		}
	}

	// Apple Pay Initialization or Update
	if ( SquareConfig.applePayEnabled === 'yes' ) {
		try {
			const applePayButtonContainer =
				document.querySelector( '#sws-applepay-legacy' );
			if ( applePayButtonContainer ) {
				// Remove active class initially
				applePayButtonContainer.classList.remove('wallet-active');

				try {
					// Reuse existing instance if available
					if (!walletInstances.applePay) {
						// Apple Pay also needs the paymentRequest object
						walletInstances.applePay = await payments.applePay(
							paymentRequest
						);
					}

					// Only show if initialization was successful
					if (walletInstances.applePay) {
						applePayButtonContainer.classList.add('wallet-active');
						applePayButtonContainer.style.display = 'block'; // Override for Apple Pay
						activeWallets++;

						jQuery( '#sws-applepay-legacy' )
							.off( 'click.squarepay' )
							.on( 'click.squarepay', async function ( e ) {
								e.preventDefault();
								await handleTokenizationAndVerification(
									walletInstances.applePay,
									'Apple Pay'
								);
							} );
					}
				} catch (initError) {
					// Apple Pay genuinely not available (expected on non-Safari browsers)
					if (!initError.message || (!initError.message.includes('not supported') && !initError.message.includes('not available'))) {
						console.error('Apple Pay initialization error:', initError);
					}
					walletInstances.applePay = null;
				}
			}
		} catch ( error ) {
			console.error( 'Apple Pay outer error:', error );
			walletInstances.applePay = null;
			// Remove active class from the Apple Pay button
			const applePayButton = document.querySelector('#sws-applepay-legacy');
			if (applePayButton) {
				applePayButton.classList.remove('wallet-active');
			}
		}
	}

	// Google Pay Initialization or Update
	if ( SquareConfig.googlePayEnabled === 'yes' ) {
		try {
			const googlePayButtonContainer =
				document.querySelector( '#sws-gpay-legacy' );

			// Check if the Google Pay button is already present
			const googlePayButtonExists = document.querySelector(
				'#gpay-button-online-api-id'
			);

			if ( googlePayButtonContainer ) {
				// Remove active class initially
				googlePayButtonContainer.classList.remove('wallet-active');

				if ( ! googlePayButtonExists ) {
					try {
						// Reuse existing instance if available
						if (!walletInstances.googlePay) {
							// Google Pay requires the actual paymentRequest object
							if (!paymentRequest || typeof paymentRequest !== 'object') {
								console.error('Invalid payment request object for Google Pay:', paymentRequest);
								return;
							}
							// Pass the paymentRequest directly without modification
							walletInstances.googlePay = await payments.googlePay(
								paymentRequest
							);
						}

						if (walletInstances.googlePay) {
							// Remove any existing click handler before attaching the new one
							jQuery( '#sws-gpay-legacy' )
								.off( 'click.squarepay' )
								.on( 'click.squarepay', async function ( e ) {
									e.preventDefault();
									await handleTokenizationAndVerification(
										walletInstances.googlePay,
										'Google Pay'
									);
								} );

							// Attach the Google Pay button
							await walletInstances.googlePay.attach( '#sws-gpay-legacy' );
							googlePayButtonContainer.classList.add('wallet-active');
							googlePayButtonContainer.style.display = 'block'; // Override inline
							activeWallets++;
						}
					} catch (attachError) {
						// Check if it's a real availability issue or just an initialization error
						if (!attachError.message || !attachError.message.includes('not supported')) {
							console.error('Google Pay initialization error:', attachError);
							// Try to show more details about the error
							if (attachError.statusCode) {
								console.error('Status code:', attachError.statusCode);
							}
							if (attachError.errors) {
								console.error('Errors:', attachError.errors);
							}
						}
						walletInstances.googlePay = null;
					}
				} else if (googlePayButtonExists) {
					// Button already exists, just mark as active
					googlePayButtonContainer.classList.add('wallet-active');
					googlePayButtonContainer.style.display = 'block';
					activeWallets++;
				}
			}
		} catch ( error ) {
			console.error( 'Google Pay outer error:', error );
			walletInstances.googlePay = null;
			// Remove active class from the Google Pay button
			const googlePayButton = document.querySelector('#sws-gpay-legacy');
			if (googlePayButton) {
				googlePayButton.classList.remove('wallet-active');
			}
		}
	}

	// Afterpay Initialization or Update
	if ( SquareConfig.afterPayEnabled === 'yes' ) {
		try {
			const afterPayButtonContainer =
				document.querySelector( '#sws-afterpay-legacy' );
			// Check for an existing Afterpay button *inside* the container
			const afterPayButtonExists = afterPayButtonContainer
				? afterPayButtonContainer.querySelector( '.sq-ap__button' )
				: null;

			if ( afterPayButtonContainer ) {
				// Remove active class initially
				afterPayButtonContainer.classList.remove('wallet-active');
				afterPayButtonContainer.style.minWidth = '240px';

				if ( ! afterPayButtonExists ) {
					try {
						// Add event listeners to paymentRequest BEFORE creating Afterpay instance
						// Using window-scoped functions from utils.js for proper cross-script access
						if (paymentRequest && !paymentRequest._afterpayListenersAdded) {
							paymentRequest.addEventListener(
								'afterpay_shippingaddresschanged',
								async ( shippingContact ) => {
									const result = await window.handleShippingAddressChanged( shippingContact );
									return result;
								}
							);
							paymentRequest.addEventListener(
								'afterpay_shippingoptionchanged',
								async ( option ) => {
									const result = await window.handleShippingOptionChanged( option );
									return result;
								}
							);
							paymentRequest._afterpayListenersAdded = true;
						}

						// Reuse existing instance if available
						if (!walletInstances.afterPay) {
							walletInstances.afterPay =
								await payments.afterpayClearpay( paymentRequest );
						}

						if (walletInstances.afterPay) {
							// Only attach if we haven't already
							if (!walletInstances.afterPay._isAttached) {
								await walletInstances.afterPay.attach( '#sws-afterpay-legacy' );
								walletInstances.afterPay._isAttached = true;

								// Add click handler to button - Afterpay's attach() does NOT add auto-tokenization
								// We must manually call tokenize() when the user clicks
								const afterpayButtonContainer = document.getElementById('sws-afterpay-legacy');

								if (afterpayButtonContainer) {
									// Remove any existing click handlers
									jQuery(afterpayButtonContainer).off('click.afterpay');

									// Add our click handler
									jQuery(afterpayButtonContainer).on('click.afterpay', async function(event) {
										// Prevent double-submission
										if (jQuery(this).hasClass('processing')) {
											return;
										}

										jQuery(this).addClass('processing');

										try {
											// This opens the Afterpay modal and waits for user to complete
											const tokenResult = await walletInstances.afterPay.tokenize();

											if (tokenResult.status === 'OK') {
												// Process the token result
												attachTokenToForm( tokenResult.token );

												const isAfterpay = true;

												// Apply the selected shipping method if one was chosen in Afterpay
												if (window._afterpaySelectedShipping && window._afterpaySelectedShipping.id) {
													const shippingRadio = jQuery(
														`input[name="shipping_method[0]"][value="${window._afterpaySelectedShipping.id}"]`
													);
													if (shippingRadio.length) {
														shippingRadio.prop('checked', true);
													}
													// Clear the stored value
													delete window._afterpaySelectedShipping;
												}

												// Ensure "Ship to a different address" is checked if we have shipping details
												const shipToDifferentAddressCheckbox = jQuery(
													'#ship-to-different-address-checkbox'
												);
												if ( shipToDifferentAddressCheckbox.length && ! shipToDifferentAddressCheckbox.is( ':checked' ) ) {
													shipToDifferentAddressCheckbox.prop( 'checked', true );
													jQuery( 'div.shipping_address' ).show();
												}

												// Extract shipping & billing from tokenResult
												const shippingDetails =
													tokenResult?.details?.shipping?.contact || {};
												const billingDetails = tokenResult?.details?.billing || {};

												const fallbackShipping = {
													first_name: jQuery( '#shipping_first_name' ).val(),
													last_name: jQuery( '#shipping_last_name' ).val(),
													address_1: jQuery( '#shipping_address_1' ).val(),
													address_2: jQuery( '#shipping_address_2' ).val(),
													city: jQuery( '#shipping_city' ).val(),
													state: jQuery( '#shipping_state' ).val(),
													postcode: jQuery( '#shipping_postcode' ).val(),
													country: jQuery( '#shipping_country' ).val(),
													phone: jQuery( '#shipping_phone' ).val(),
													email: jQuery( '#billing_email' ).val(),
												};
												const fallbackBilling = {
													first_name: jQuery( '#billing_first_name' ).val(),
													last_name: jQuery( '#billing_last_name' ).val(),
													address_1: jQuery( '#billing_address_1' ).val(),
													address_2: jQuery( '#billing_address_2' ).val(),
													city: jQuery( '#billing_city' ).val(),
													state: jQuery( '#billing_state' ).val(),
													postcode: jQuery( '#billing_postcode' ).val(),
													country: jQuery( '#billing_country' ).val(),
													phone: jQuery( '#billing_phone' ).val(),
													email: jQuery( '#billing_email' ).val(),
												};

												// Transform shipping contact
												const shippingContact = transformContact(
													shippingDetails,
													isAfterpay,
													fallbackShipping
												);

												// Transform billing contact
												let billingContact = transformContact(
													billingDetails,
													isAfterpay,
													fallbackBilling
												);

												// If billing is incomplete, prioritize WooCommerce billing fields
												if ( ! isBillingComplete( billingContact ) ) {
													// First try WooCommerce billing form fields directly
													const wooCommerceBilling = transformContact(
														{},  // No Afterpay data - use fallback only
														isAfterpay,
														fallbackBilling  // Use WooCommerce BILLING form fields
													);

													// Only use shipping as last resort if WooCommerce billing is also empty
													if ( ! isBillingComplete( wooCommerceBilling ) ) {
														const shippingAsBilling = transformContact(
															shippingDetails,
															isAfterpay,
															fallbackBilling  // Still use billing fallback, not shipping
														);
														billingContact = {
															...shippingAsBilling,
															email:
																billingContact.email ||
																shippingAsBilling.email ||
																shippingDetails.email,
														};
													} else {
														// Use WooCommerce billing as primary fallback
														billingContact = {
															...wooCommerceBilling,
															email: billingContact.email || wooCommerceBilling.email,
														};
													}
												}

												// Verify buyer for SCA compliance (3D Secure) - Afterpay
												const afterpayOrderTotal = SquareConfig.orderTotal || '0.00';
												const afterpayVerificationDetails = {
													intent: 'CHARGE',
													amount: afterpayOrderTotal,
													currencyCode: SquareConfig.currency || 'USD',
													billingContact: {
														givenName: billingContact.givenName || '',
														familyName: billingContact.familyName || '',
														email: billingContact.email || '',
														phone: billingContact.phone || '',
														country: billingContact.countryCode || '',
														region: billingContact.state || '',
														city: billingContact.city || '',
														postalCode: billingContact.postalCode || '',
														addressLines: billingContact.addressLines || [],
													},
												};

												try {
													const verificationResult = await payments.verifyBuyer(
														tokenResult.token,
														afterpayVerificationDetails
													);
													if ( verificationResult && verificationResult.token ) {
														attachVerificationTokenToForm( verificationResult.token );
													}
												} catch ( verifyError ) {
													console.error( 'Afterpay buyer verification failed:', verifyError );
													// Continue anyway for non-SCA regions, but log the error
												}

												// Update shipping fields only if existing shipping is incomplete
												const shouldUpdateShippingAfterpay = typeof needsShipping !== 'undefined' && needsShipping && ! isExistingShippingComplete();

												if ( shouldUpdateShippingAfterpay ) {
													jQuery( '#shipping_first_name' ).val(
														shippingContact.givenName || ''
													);
													jQuery( '#shipping_last_name' ).val(
														shippingContact.familyName || ''
													);
													jQuery( '#shipping_company' ).val( '' );
													jQuery( '#shipping_address_1' ).val(
														shippingContact.addressLines[ 0 ] || ''
													);
													jQuery( '#shipping_address_2' ).val(
														shippingContact.addressLines[ 1 ] || ''
													);
													jQuery( '#shipping_city' ).val(
														shippingContact.city || ''
													);
													jQuery( '#shipping_state' ).val(
														shippingContact.state || ''
													);
													jQuery( '#shipping_postcode' ).val(
														shippingContact.postalCode || ''
													);
													jQuery( '#shipping_country' ).val(
														shippingContact.countryCode || ''
													);
													jQuery( '#shipping_phone' ).val(
														shippingContact.phone || ''
													);
												}

												// Only update billing fields if existing billing is incomplete
												const shouldUpdateBillingAfterpay = ! isExistingBillingComplete();

												if ( shouldUpdateBillingAfterpay ) {
													// Update billing fields
													jQuery( '#billing_country' )
														.val( billingContact.countryCode || '' )
														.trigger( 'change' );
												}

												// Give WooCommerce time to repopulate state dropdown
												setTimeout( function () {
													if ( shouldUpdateBillingAfterpay ) {
														jQuery( '#billing_state' )
															.val( billingContact.state || '' )
															.trigger( 'change' );

														jQuery( '#billing_first_name' ).val(
															billingContact.givenName || ''
														);
														jQuery( '#billing_last_name' ).val(
															billingContact.familyName || ''
														);
														jQuery( '#billing_company' ).val( '' );
														jQuery( '#billing_address_1' ).val(
															billingContact.addressLines[ 0 ] || ''
														);
														jQuery( '#billing_address_2' ).val(
															billingContact.addressLines[ 1 ] || ''
														);
														jQuery( '#billing_city' ).val( billingContact.city || '' );
														jQuery( '#billing_postcode' ).val(
															billingContact.postalCode || ''
														);
														jQuery( '#billing_phone' ).val(
															billingContact.phone || ''
														);
														jQuery( '#billing_email' ).val(
															billingContact.email || ''
														);
													}

													// Submit the checkout form
													// Handle both checkout and pay-for-order forms
													const $form = jQuery( 'form.checkout, form#order_review' );
													$form.trigger( 'submit' );
												}, 100 );
											} else if (tokenResult.status === 'CANCEL') {
												// User cancelled, don't show error
											} else {
												clearStoredTokens();
												const errorMessage = tokenResult.errors
													? tokenResult.errors.map(e => e.message || e).join(', ')
													: 'Unknown error';
												logPaymentError(`Afterpay payment failed: ${errorMessage}`);
											}
										} catch (error) {
											clearStoredTokens();
											logPaymentError(`Afterpay error: ${error.message || 'Unknown error'}`);
										} finally {
											// Remove processing class
											jQuery(afterpayButtonContainer).removeClass('processing');
										}
									});
								}
							}
							afterPayButtonContainer.classList.add('wallet-active');
							afterPayButtonContainer.style.display = 'block'; // Override inline
							activeWallets++;
						}
					} catch (initError) {
						if (!initError.message || !initError.message.includes('not available')) {
							console.error('Afterpay initialization error:', initError);
						}
						walletInstances.afterPay = null;
					}
				} else if (afterPayButtonExists) {
					// Button already exists, just mark as active
					afterPayButtonContainer.classList.add('wallet-active');
					afterPayButtonContainer.style.display = 'block';
					activeWallets++;
				}
			}
		} catch ( error ) {
			console.error( 'Afterpay outer error:', error );
			walletInstances.afterPay = null;
			// Remove active class from the Afterpay button
			const afterPayButton = document.querySelector('#sws-afterpay-legacy');
			if (afterPayButton) {
				afterPayButton.classList.remove('wallet-active');
			}
		}
	}

	// Cash App Pay Initialization
	if ( SquareConfig.cashAppPayEnabled === 'yes' ) {
		try {
			const cashAppPayButtonContainer =
				document.querySelector( '#sws-cashapp-legacy' );

			if ( cashAppPayButtonContainer ) {
				// Remove active class initially
				cashAppPayButtonContainer.classList.remove('wallet-active');

				// Check if button already exists
				const cashAppPayButtonExists = cashAppPayButtonContainer.querySelector( '[data-cashapp-button]' );

				if ( ! cashAppPayButtonExists ) {
					try {
						// Reuse existing instance if available
						if (!walletInstances.cashAppPay) {
							// Cash App Pay requires redirectURL for mobile flow
							const redirectURL = window.location.href;
							const referenceId = `order-${Date.now()}`;

							walletInstances.cashAppPay = await payments.cashAppPay(
								paymentRequest,
								{
									redirectURL,
									referenceId,
								}
							);
						}

						if (walletInstances.cashAppPay) {
							// Attach the Cash App Pay button with styling options
							await walletInstances.cashAppPay.attach( '#sws-cashapp-legacy', {
								shape: 'semiround',
								width: 'static',
								size: 'medium',
								theme: 'dark',
							} );

							// Add tokenization event listener for Cash App Pay
							walletInstances.cashAppPay.addEventListener('ontokenization', async function(event) {
								const { tokenResult, error } = event.detail;

								if (error) {
									console.error('Cash App Pay tokenization error:', error);
									clearStoredTokens();
									logPaymentError(`Cash App Pay error: ${error.message || 'Unknown error'}`);
									return;
								}

								if (tokenResult && tokenResult.status === 'OK') {
									// Process the token result using existing handler
									await handleTokenizationAndVerification(
										walletInstances.cashAppPay,
										'Cash App Pay'
									);
								} else if (tokenResult && tokenResult.status !== 'Cancel') {
									clearStoredTokens();
									const errorMessage = tokenResult.errors
										? tokenResult.errors.map(e => e.message || e).join(', ')
										: 'Unknown error';
									logPaymentError(`Cash App Pay payment failed: ${errorMessage}`);
								}
							});

							cashAppPayButtonContainer.classList.add('wallet-active');
							cashAppPayButtonContainer.style.display = 'block';
							activeWallets++;
						}
					} catch (initError) {
						if (!initError.message || (!initError.message.includes('not supported') && !initError.message.includes('not available'))) {
							console.error('Cash App Pay initialization error:', initError);
						}
						walletInstances.cashAppPay = null;
					}
				} else if (cashAppPayButtonExists) {
					// Button already exists, just mark as active
					cashAppPayButtonContainer.classList.add('wallet-active');
					cashAppPayButtonContainer.style.display = 'block';
					activeWallets++;
				}
			}
		} catch ( error ) {
			console.error( 'Cash App Pay outer error:', error );
			walletInstances.cashAppPay = null;
			// Remove active class from the Cash App Pay button
			const cashAppPayButton = document.querySelector('#sws-cashapp-legacy');
			if (cashAppPayButton) {
				cashAppPayButton.classList.remove('wallet-active');
			}
		}
	}

	// Show the wallet container only if at least one wallet was successfully initialized
	if (activeWallets > 0) {
		walletContainers.forEach(container => {
			container.classList.add('has-wallets');
			container.style.display = 'block'; // Override the initial hidden state
		});
	} else {
		// Ensure containers stay hidden
		walletContainers.forEach(container => {
			container.style.display = 'none';
		});
	}
}

function updateWooCommerceShippingFields( shipping ) {
	// Bail out if shipping or addressLines is missing
	if (
		! shipping ||
		! Array.isArray( shipping.addressLines ) ||
		shipping.addressLines.length === 0
	) {
		return;
	}

	jQuery( '#shipping_first_name' ).val( shipping.givenName );
	jQuery( '#shipping_last_name' ).val( shipping.familyName );
	jQuery( '#shipping_address_1' ).val( shipping.addressLines[ 0 ] );
	jQuery( '#shipping_city' ).val( shipping.city );
	jQuery( '#shipping_postcode' ).val( shipping.postalCode );
	jQuery( '#shipping_state' ).val( shipping.state );
	jQuery( '#shipping_country' ).val( shipping.countryCode );
	jQuery( '#shipping_phone' ).val( shipping.phone );
}

// Cleanup on page unload
jQuery( window ).on( 'beforeunload', function() {
	cleanupWalletInstances();
});