// source --> https://alternativaportugal.org/wp-content/plugins/woocommerce/assets/js/frontend/address-i18n.js?ver=10.8.1 
/*global wc_address_i18n_params */
jQuery( function( $ ) {

	// wc_address_i18n_params is required to continue, ensure the object exists
	if ( typeof wc_address_i18n_params === 'undefined' ) {
		return false;
	}

	var locale_json = wc_address_i18n_params.locale.replace( /&quot;/g, '"' ), locale = JSON.parse( locale_json );

	function field_is_required( field, is_required ) {
		if ( is_required ) {
			field.find( 'label .optional' ).remove();
			field.addClass( 'validate-required' );

			if ( field.find( 'label .required[aria-hidden="true"]' ).length === 0 ) {
				field.find( 'label' ).append(
					'&nbsp;<span class="required" aria-hidden="true">*</span>'
				);
			}
		} else {
			field.find( 'label .required' ).remove();
			field.removeClass( 'validate-required woocommerce-invalid woocommerce-invalid-required-field' );

			if ( field.find( 'label .optional' ).length === 0 ) {
				field.find( 'label' ).append( '&nbsp;<span class="optional">(' + wc_address_i18n_params.i18n_optional_text + ')</span>' );
			}
		}
	}

	// Handle locale
	$( document.body )
		.on( 'country_to_state_changing', function( event, country, wrapper ) {
			var thisform = wrapper, thislocale;

			if ( typeof locale[ country ] !== 'undefined' ) {
				thislocale = locale[ country ];
			} else {
				thislocale = locale['default'];
			}

			var $postcodefield = thisform.find( '#billing_postcode_field, #shipping_postcode_field, #calc_shipping_postcode_field' ),
				$cityfield     = thisform.find( '#billing_city_field, #shipping_city_field, #calc_shipping_city_field' ),
				$statefield    = thisform.find( '#billing_state_field, #shipping_state_field, #calc_shipping_state_field' );

			if ( ! $postcodefield.attr( 'data-o_class' ) ) {
				$postcodefield.attr( 'data-o_class', $postcodefield.attr( 'class' ) );
				$cityfield.attr( 'data-o_class', $cityfield.attr( 'class' ) );
				$statefield.attr( 'data-o_class', $statefield.attr( 'class' ) );
			}

			var locale_fields = JSON.parse( wc_address_i18n_params.locale_fields );

			$.each( locale_fields, function( key, value ) {

				var field       = thisform.find( value ),
					fieldLocale = $.extend( true, {}, locale['default'][ key ], thislocale[ key ] );

				// Labels.
				if ( typeof fieldLocale.label !== 'undefined' ) {
					field.find( 'label' ).html( fieldLocale.label );
				}

				// Placeholders.
				if ( typeof fieldLocale.placeholder !== 'undefined' ) {
					field.find( ':input' ).attr( 'placeholder', fieldLocale.placeholder );
					field.find( ':input' ).attr( 'data-placeholder', fieldLocale.placeholder );
					field.find( '.select2-selection__placeholder' ).text( fieldLocale.placeholder );
				}

				// Use the i18n label as a placeholder if there is no label element and no i18n placeholder.
				if (
					typeof fieldLocale.placeholder === 'undefined' &&
					typeof fieldLocale.label !== 'undefined' &&
					! field.find( 'label:not(.screen-reader-text)' ).length
				) {
					field.find( ':input' ).attr( 'placeholder', fieldLocale.label );
					field.find( ':input' ).attr( 'data-placeholder', fieldLocale.label );
					field.find( '.select2-selection__placeholder' ).text( fieldLocale.label );
				}

				// Required.
				if ( typeof fieldLocale.required !== 'undefined' ) {
					field_is_required( field, fieldLocale.required );
				} else {
					field_is_required( field, false );
				}

				// Priority.
				if ( typeof fieldLocale.priority !== 'undefined' ) {
					field.data( 'priority', fieldLocale.priority );
				}

				// Hidden fields. State visibility (show) is managed by
				// country-select.js, but locale can still hide it.
				if ( true === fieldLocale.hidden ) {
					field.hide().find( ':input' ).val( '' );
				} else if ( 'state' !== key ) {
					field.show();
				}

				// Class changes.
				if ( Array.isArray( fieldLocale.class ) ) {
					field.removeClass( 'form-row-first form-row-last form-row-wide' );
					field.addClass( fieldLocale.class.join( ' ' ) );
				}
			});

			var fieldsets = $(
				'.woocommerce-billing-fields__field-wrapper,' +
				'.woocommerce-shipping-fields__field-wrapper,' +
				'.woocommerce-address-fields__field-wrapper,' +
				'.woocommerce-additional-fields__field-wrapper .woocommerce-account-fields'
			);

			fieldsets.each( function( index, fieldset ) {
				var rows    = $( fieldset ).find( '.form-row' );
				var wrapper = rows.first().parent();

				// Before sorting, ensure all fields have a priority for bW compatibility.
				var last_priority = 0;

				rows.each( function() {
					if ( ! $( this ).data( 'priority' ) ) {
							$( this ).data( 'priority', last_priority + 1 );
					}
					last_priority = $( this ).data( 'priority' );
				} );

				// Sort the fields.
				rows.sort( function( a, b ) {
					var asort = parseInt( $( a ).data( 'priority' ), 10 ),
						bsort = parseInt( $( b ).data( 'priority' ), 10 );

					if ( asort > bsort ) {
						return 1;
					}
					if ( asort < bsort ) {
						return -1;
					}
					return 0;
				});

				rows.detach().appendTo( wrapper );
			});
		})
		.trigger( 'wc_address_i18n_ready' );
});
// source --> https://alternativaportugal.org/wp-content/plugins/woocommerce/assets/js/frontend/utils/custom-place-order-button.js?ver=10.8.1 
/**
 * Custom Place Order Button API
 *
 * Shared functionality for custom place order buttons across checkout, order-pay,
 * and add-payment-method pages. This module provides the core registration and
 * button management logic.
 *
 * @since 10.6.0
 */

( function ( $ ) {
	'use strict';

	// Initialize the global wc.customPlaceOrderButton namespace
	window.wc = window.wc || {};
	window.wc.customPlaceOrderButton = window.wc.customPlaceOrderButton || {};

	// Inject critical CSS inline to ensure it works even when themes dequeue woocommerce.css
	( function injectStyles() {
		var styleId = 'wc-custom-place-order-button-styles';
		if ( document.getElementById( styleId ) ) {
			return;
		}
		var style = document.createElement( 'style' );
		style.id = styleId;
		style.textContent = 'form.has-custom-place-order-button #place_order { display: none !important; }';
		document.head.appendChild( style );
	} )();

	/**
	 * Registry for custom place order buttons.
	 * Key: gateway_id, Value: { render: function, cleanup: function }
	 */
	var customPlaceOrderButtons = {};

	/**
	 * Currently active custom button gateway ID, or null if using the default button.
	 */
	var activeCustomButtonGateway = null;

	/**
	 * Container element for the custom place order button.
	 */
	var $customButtonContainer = null;

	/**
	 * Get the current form element based on page context.
	 *
	 * @return {jQuery} The form element.
	 */
	function getForm() {
		if ( $( 'form.checkout' ).length ) {
			return $( 'form.checkout' ).first();
		}
		if ( $( '#order_review' ).length ) {
			return $( '#order_review' ).first();
		}
		if ( $( '#add_payment_method' ).length ) {
			return $( '#add_payment_method' ).first();
		}
		return $( [] );
	}

	/**
	 * Get a list of gateway IDs with custom place order buttons from server config.
	 *
	 * @return {Array} List of gateway IDs
	 */
	function getGatewaysWithCustomButton() {
		// Try multiple param sources for compatibility across pages
		if ( typeof wc_checkout_params !== 'undefined' && wc_checkout_params.gateways_with_custom_place_order_button ) {
			return wc_checkout_params.gateways_with_custom_place_order_button;
		}
		if ( typeof wc_add_payment_method_params !== 'undefined' && wc_add_payment_method_params.gateways_with_custom_place_order_button ) {
			return wc_add_payment_method_params.gateways_with_custom_place_order_button;
		}
		return [];
	}

	/**
	 * Check if a gateway has a custom place order button registered via a server-side flag.
	 *
	 * @param {string} gatewayId - The payment gateway ID
	 * @return {boolean} True if gateway has custom button
	 */
	function gatewayHasCustomPlaceOrderButton( gatewayId ) {
		return getGatewaysWithCustomButton().indexOf( gatewayId ) !== -1;
	}

	/**
	 * Create or get the container for custom place order buttons.
	 * The container is scoped to the current form to handle multiple forms on a page.
	 * We're not creating the container server-side to avoid introducing a new template
	 * that might break compatibility with subscriptions or other extensions.
	 *
	 * @return {jQuery} The container element
	 */
	function getOrCreateCustomButtonContainer() {
		if ( $customButtonContainer && $customButtonContainer.length && $.contains( document, $customButtonContainer[ 0 ] ) ) {
			return $customButtonContainer;
		}

		var $placeOrderButton = getForm().find( '#place_order' );
		if ( ! $placeOrderButton.length ) {
			return $( [] );
		}

		$customButtonContainer = $( '<div class="wc-custom-place-order-button"></div>' );
		$placeOrderButton.after( $customButtonContainer );

		return $customButtonContainer;
	}

	/**
	 * Remove the custom button container.
	 */
	function removeCustomButtonContainer() {
		if ( $customButtonContainer && $customButtonContainer.length ) {
			$customButtonContainer.remove();
			$customButtonContainer = null;
		}
	}

	/**
	 * Clean up the current custom button if any.
	 */
	function cleanupCurrentCustomButton() {
		if ( activeCustomButtonGateway && customPlaceOrderButtons[ activeCustomButtonGateway ] ) {
			try {
				customPlaceOrderButtons[ activeCustomButtonGateway ].cleanup();
			} catch ( e ) {
				// Log errors to help gateway developers debug their cleanup implementation.
				// eslint-disable-next-line no-console
				console.error( 'Error in custom place order button cleanup:', e );
			}
		}
		removeCustomButtonContainer();
		activeCustomButtonGateway = null;
	}

	/**
	 * Show custom place order button for a gateway, or show default button.
	 * The `api` object is needed because the add-payment-method page is different than a checkout or a pay-for-order page.
	 * Each page can decide how to implement the `validate` and `submit` methods.
	 *
	 * @param {string} gatewayId - The payment gateway ID
	 * @param {Object} api - The API object to pass to render callback
	 */
	function maybeShowCustomPlaceOrderButton( gatewayId, api ) {
		var $form = getForm();

		// Clean up any displayed custom button, if any
		if ( activeCustomButtonGateway && customPlaceOrderButtons[ activeCustomButtonGateway ] ) {
			try {
				customPlaceOrderButtons[ activeCustomButtonGateway ].cleanup();
			} catch ( e ) {
				// Log errors to help gateway developers debug their cleanup implementation.
				// eslint-disable-next-line no-console
				console.error( 'Error in custom place order button cleanup:', e );
			}
		}

		var isCustomButtonRegistered = Boolean( customPlaceOrderButtons[ gatewayId ] );
		if ( isCustomButtonRegistered ) {
			// Hide the default button and show the custom one, instead.
			$form.addClass( 'has-custom-place-order-button' );
			activeCustomButtonGateway = gatewayId;

			var $container = getOrCreateCustomButtonContainer();
			$container.empty();

			try {
				customPlaceOrderButtons[ gatewayId ].render( $container.get( 0 ), api );
			} catch ( e ) {
				// Log errors to help gateway developers debug their render implementation.
				// eslint-disable-next-line no-console
				console.error( 'Error rendering custom place order button:', e );
			}
		} else {
			// Only show default button if gateway doesn't have a custom button pending registration.
			// This prevents flash when gateway JS loads after the initial click.
			// Basically, when `__maybeShow` is called for a gateway that isn't registered yet but has the server-side flag set,
			// we keep the default button hidden instead of flashing it.
			if ( ! gatewayHasCustomPlaceOrderButton( gatewayId ) ) {
				$form.removeClass( 'has-custom-place-order-button' );
			}
			activeCustomButtonGateway = null;
			removeCustomButtonContainer();
		}
	}

	/**
	 * Hide default button immediately if selected gateway has custom button (prevents flash).
	 *
	 * @param {string} gatewayId - The payment gateway ID
	 */
	function maybeHideDefaultButtonOnInit( gatewayId ) {
		if ( gatewayHasCustomPlaceOrderButton( gatewayId ) ) {
			var $form = getForm();
			$form.addClass( 'has-custom-place-order-button' );
		}
	}

	/**
	 * Register a custom place order button for a payment gateway.
	 *
	 * @param {string} gatewayId - The payment gateway ID (e.g., 'google_pay')
	 * @param {Object} config - Configuration object
	 * @param {Function} config.render - Function called to render the button. Receives (container, api)
	 * @param {Function} config.cleanup - Function called when switching away from this gateway
	 */
	function registerCustomPlaceOrderButton( gatewayId, config ) {
		// Silently ignore if already registered (prevents double-registration issues)
		if ( customPlaceOrderButtons[ gatewayId ] ) {
			return;
		}

		if ( typeof gatewayId !== 'string' || ! gatewayId ) {
			// Log validation errors to help gateway developers fix incorrect API usage.
			// eslint-disable-next-line no-console
			console.error( 'wc.customPlaceOrderButton.register: gatewayId must be a non-empty string' );
			return;
		}
		if ( typeof config !== 'object' || config === null ) {
			// Log validation errors to help gateway developers fix incorrect API usage.
			// eslint-disable-next-line no-console
			console.error( 'wc.customPlaceOrderButton.register: config must be an object' );
			return;
		}
		if ( typeof config.render !== 'function' ) {
			// Log validation errors to help gateway developers fix incorrect API usage.
			// eslint-disable-next-line no-console
			console.error( 'wc.customPlaceOrderButton.register: render must be a function' );
			return;
		}
		if ( typeof config.cleanup !== 'function' ) {
			// Log validation errors to help gateway developers fix incorrect API usage.
			// eslint-disable-next-line no-console
			console.error( 'wc.customPlaceOrderButton.register: cleanup must be a function' );
			return;
		}

		customPlaceOrderButtons[ gatewayId ] = config;

		// If this gateway is already selected, notify that registration is complete
		if ( getForm().find( 'input[name="payment_method"]:checked' ).val() === gatewayId ) {
			// since this API needs to be used on checkout/pay for order/my account pages,
			// we need to trigger a global event to ensure it's picked up by the WC Core JS used in those pages.
			$( document.body ).trigger( 'wc_custom_place_order_button_registered', [ gatewayId ] );
		}
	}

	// Export functions to the global namespace
	// Public API (for gateway developers)
	window.wc.customPlaceOrderButton.register = registerCustomPlaceOrderButton;

	// Internal API (used by WooCommerce core, not for external use)
	window.wc.customPlaceOrderButton.__maybeShow = maybeShowCustomPlaceOrderButton;
	window.wc.customPlaceOrderButton.__maybeHideDefaultButtonOnInit = maybeHideDefaultButtonOnInit;
	window.wc.customPlaceOrderButton.__cleanup = cleanupCurrentCustomButton;
	window.wc.customPlaceOrderButton.__getForm = getForm;

} )( jQuery );