(function ($) {
	'use strict';

	var mapsLoader;

	function loadMapsApi() {
		if (window.google && window.google.maps) {
			return Promise.resolve(window.google.maps);
		}

		if (mapsLoader) {
			return mapsLoader;
		}

		mapsLoader = new Promise(function (resolve, reject) {
			if (!gmdsAdmin.apiKey) {
				reject(new Error(gmdsAdmin.strings.noApiKey));
				return;
			}

			var existingScript = document.getElementById('gmds-google-maps-js');

			window.gmdsMapsReady = function () {
				resolve(window.google.maps);
				delete window.gmdsMapsReady;
			};

			window.gm_authFailure = function () {
				reject(new Error(gmdsAdmin.strings.authError));
			};

			if (existingScript) {
				return;
			}

			var script = document.createElement('script');
			script.id = 'gmds-google-maps-js';
			script.src = 'https://maps.googleapis.com/maps/api/js?key=' + encodeURIComponent(gmdsAdmin.apiKey) + '&v=weekly&callback=gmdsMapsReady';
			script.async = true;
			script.defer = true;
			script.onerror = function () {
				reject(new Error(gmdsAdmin.strings.loadError));
			};

			document.head.appendChild(script);
		});

		return mapsLoader;
	}

	function bindPreviewButton() {
		$('input[data-original_name="address"], input[name="address"]').each(function () {
			var $input = $(this);

			if (!$input.is(':visible') || $input.data('gmdsPreviewBound')) {
				return;
			}

			var $tools = $('<div class="gmds-preview-tools" style="margin-top:10px;"></div>');
			var $button = $('<button type="button" class="button button-secondary"></button>').text(gmdsAdmin.strings.preview);
			var $status = $('<div class="description" style="margin-top:8px;"></div>');

			$input.data('gmdsPreviewBound', true);
			$tools.append($button).append($status);
			$input.after($tools);

			$button.on('click', function () {
				var address = $input.val();

				if (!address) {
					$status.text(gmdsAdmin.strings.noAddress);
					return;
				}

				if (!gmdsAdmin.apiKey) {
					$status.text(gmdsAdmin.strings.noApiKey);
					return;
				}

				$button.prop('disabled', true).text(gmdsAdmin.strings.previewing);
				$status.text('');

				loadMapsApi()
					.then(function (maps) {
						var geocoder = new maps.Geocoder();

						return geocoder.geocode({ address: address });
					})
					.then(function (response) {
						if (!response || !response.results || !response.results.length) {
							throw new Error(gmdsAdmin.strings.error);
						}

						var result = response.results[0];

						if (result.formatted_address) {
							$input.val(result.formatted_address);
						}

						$input.trigger('input');
						$input.trigger('change');
						$input.trigger('blur');

						$status.text(gmdsAdmin.strings.success);
					})
					.catch(function (error) {
						$status.text(error && error.message ? error.message : gmdsAdmin.strings.error);
					})
					.finally(function () {
						$button.prop('disabled', false).text(gmdsAdmin.strings.preview);
					});
			});
		});
	}

	$(document).ready(function () {
		bindPreviewButton();
		window.setInterval(bindPreviewButton, 1000);
	});
})(jQuery);
