; ( function ( document, $ ) {
	'use strict';

	let ipData = false;
	let stateHandlerAttached = false;

	$.when( fetchGeoLocationData() ).done( function ( data ) {
		ipData = data;
		updateInputs();
	} );

	$( document.body ).on( 'edd_gateway_loaded', function ( e, gateway ) {
		updateInputs();
	} );

	/**
	 * Update the address input fields.
	 */
	function updateInputs () {
		if ( !ipData ) {
			return;
		}
		let updated = false;
		if ( ipData.country ) {
			const currentCountry = $( '#billing_country' ).val();
			if ( currentCountry !== ipData.country ) {
				$( '#billing_country' ).val( ipData.country ).trigger( 'change' );
				updated = true;
			}
		}
		if ( ipData.city ) {
			const currentCity = $( '#card_city' ).val();
			if ( currentCity !== ipData.city ) {
				$( '#card_city' ).val( ipData.city );
			}
		}
		if ( ipData.state ) {
			const currentState = $( '#card_state' ).val();
			if ( currentState !== ipData.state ) {
				// Attach event listener only once to avoid duplicates
				if ( ! stateHandlerAttached ) {
					$( 'body' ).on( 'edd_cart_billing_address_updated', function () {
						if ( ipData && ipData.state ) {
							$( '#card_state' ).val( ipData.state );
						}
					} );
					stateHandlerAttached = true;
				}
				updated = true;
			}
		}
		if ( ipData.ip ) {
			let ipInput = $( '#edd_pro_ip' );
			if ( !ipInput.length ) {
				$( '<input>' ).attr( {
					type: 'hidden',
					id: 'edd_pro_ip',
					name: 'edd_pro_ip',
				} ).appendTo( '#edd_purchase_form' );
				// Re-query after creating the element
				ipInput = $( '#edd_pro_ip' );
			}
			ipInput.val( ipData.ip );
		}

		if ( updated && EDDProCheckout.taxes && $( '#edd-checkout-address-fields-nonce' ).length ) {
			recalculate_taxes();
		}
	}
} )( document, jQuery );

/**
 * Gets the data from the geolocation endpoint.
 * @returns Promise
 */
function fetchGeoLocationData () {

	return fetch( EDDProCheckout.api, {
		method: 'GET',
	} ).then( function ( response ) {
		if ( !response.ok ) {
			throw new Error( 'Failed to fetch geolocation data: ' + response.status );
		}
		return response.json();
	} ).then( function ( data ) {
		if ( !data ) {
			return false;
		}

		return dataToAddress( data );
	} ).catch( function ( error ) {
		if ( EDDProCheckout.debug ) {
			console.error( 'Geolocation fetch error:', error );
		}
		return false;
	} );
}

/**
 * If location data was retrieved, attempt to update it to match EDD expectations.
 *
 * @param {*} data
 * @returns Promise
 */
function dataToAddress ( data ) {
	data.action = 'edd_pro_geoip';
	data.nonce = EDDProCheckout.nonce;

	var form_data = new FormData();
	for ( var key in data ) {
		form_data.append( key, data[ key ] );
	}

	return fetch( EDDProCheckout.ajax, {
		method: 'POST',
		body: form_data,
	} ).then( function ( response ) {
		if ( ! response.ok ) {
			throw new Error( 'Failed to process geolocation data: ' + response.status );
		}
		return response.json();
	} ).then( function ( data ) {
		if ( EDDProCheckout.debug ) {
			console.log( data );
		}
		return data.data ? data.data : false;
	} ).catch( function ( error ) {
		if ( EDDProCheckout.debug ) {
			console.error( 'Geolocation processing error:', error );
		}
		return false;
	} );
}
