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

	let ipData = 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;
		}
		if ( ipData.country ) {
			$( '#billing_country' ).val( ipData.country ).trigger( 'change' );
		}
		if ( ipData.city ) {
			$( '#card_city' ).val( ipData.city );
		}
		if ( ipData.state ) {
			$( '#card_state' ).val( ipData.state );
			$( 'body' ).on( 'edd_cart_billing_address_updated', function () {
				$( '#card_state' ).val( ipData.state );
			} );
		}
		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' );
			}
			ipInput.val( ipData.ip );
		}

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

/**
 * Gets the data from the geolocation enpdpoint.
 * @returns false|object
 */
function fetchGeoLocationData () {

	return fetch( EDDProCheckout.api, {
		method: 'GET',
	} ).then( function ( response ) {
		return response.json();
	} ).then( function ( data ) {
		if ( !data ) {
			return false;
		}

		return dataToAddress( data );
	} );
}

/**
 * If location data was retrieved, attempt to update it to match EDD expectations.
 *
 * @param {*} data
 * @returns false|object
 */
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 ) {
		return response.json();
	} ).then( function ( data ) {
		if ( EDDProCheckout.debug ) {
			console.log( data );
		}
		return data.data ? data.data : false;
	} );
}
