(function($) {
    'use strict';

    var omAutocomplete = {
        instances: {},
        updateCheckoutTimer: null,
        isPopulating: false, // Flag to prevent change events during population

        init: function() {
            this.waitForGoogle();
        },

        waitForGoogle: function() {
            var self = this;
            var attempts = 0;
            var maxAttempts = 50;

            function check() {
                attempts++;
                if (typeof google !== 'undefined' && google.maps && google.maps.places) {
                    self.setup();
                } else if (attempts < maxAttempts) {
                    setTimeout(check, 100);
                } else {
                    console.error('Google Maps API failed to load');
                }
            }
            check();
        },

        setup: function() {
            var self = this;

            // Setup billing autocomplete
            var $billingSearch = $('#billing_address_search');
            if ($billingSearch.length) {
                self.initAutocomplete($billingSearch, 'billing');
            }

            // Setup shipping autocomplete
            var $shippingSearch = $('#shipping_address_search');
            if ($shippingSearch.length) {
                self.initAutocomplete($shippingSearch, 'shipping');
            }

            // Re-init on checkout update (for dynamic forms)
            // Only re-init if instances don't exist AND we're not currently populating
            // This prevents re-initialization loops during autocomplete selection
            $(document.body).on('updated_checkout', function() {
                // Skip if we're in the middle of populating fields
                if (self.isPopulating) {
                    return;
                }

                if ($('#billing_address_search').length && !self.instances.billing) {
                    self.initAutocomplete($('#billing_address_search'), 'billing');
                }
                if ($('#shipping_address_search').length && !self.instances.shipping) {
                    self.initAutocomplete($('#shipping_address_search'), 'shipping');
                }
            });
        },

        initAutocomplete: function($input, type) {
            var self = this;
            var input = $input[0];

            if (!input) return;

            var options = {
                types: ['address'],
                fields: ['address_components', 'formatted_address'],
            };

            // Add country restriction
            if (window.omAI && window.omAI.country) {
                options.componentRestrictions = { country: window.omAI.country };
            }

            var autocomplete = new google.maps.places.Autocomplete(input, options);

            // Set language if available
            if (window.omAI && window.omAI.language) {
                // Language is set via API URL, but we can add hints
            }

            // Listen for place selection
            autocomplete.addListener('place_changed', function() {
                self.handlePlaceSelect(autocomplete, type);
            });

            // Store instance
            this.instances[type] = autocomplete;

            // Prevent form submission on enter
            $input.on('keydown', function(e) {
                if (e.key === 'Enter') {
                    e.preventDefault();
                }
            });
        },

        handlePlaceSelect: function(autocomplete, type) {
            var self = this;
            var place = autocomplete.getPlace();

            if (!place || !place.address_components) {
                return;
            }

            var address = this.parseAddress(place);
            this.populateFields(address, type);

            // Debounced checkout update - prevents multiple rapid updates
            // which cause flickering in shipping method areas
            self.scheduleCheckoutUpdate();
        },

        /**
         * Schedule a debounced checkout update
         * This consolidates multiple field changes into a single update
         */
        scheduleCheckoutUpdate: function() {
            var self = this;

            // Clear any pending update
            if (self.updateCheckoutTimer) {
                clearTimeout(self.updateCheckoutTimer);
            }

            // Schedule new update after a short delay
            // 150ms is enough to batch all field changes together
            self.updateCheckoutTimer = setTimeout(function() {
                self.updateCheckoutTimer = null;
                $(document.body).trigger('update_checkout');
            }, 150);
        },

        parseAddress: function(place) {
            var data = {
                street_number: '',
                route: '',
                city: '',
                state: '',
                postcode: '',
                country: ''
            };

            var components = place.address_components;
            for (var i = 0; i < components.length; i++) {
                var component = components[i];
                var type = component.types[0];

                switch (type) {
                    case 'street_number':
                        data.street_number = component.long_name;
                        break;
                    case 'route':
                        data.route = component.long_name;
                        break;
                    case 'locality':
                    case 'sublocality_level_1':
                    case 'administrative_area_level_3':
                        if (!data.city) data.city = component.long_name;
                        break;
                    case 'administrative_area_level_1':
                        data.state = component.short_name;
                        break;
                    case 'postal_code':
                        data.postcode = component.long_name;
                        break;
                    case 'country':
                        data.country = component.short_name;
                        break;
                }
            }

            // Build address line (Greek format: Street Number)
            if (data.route && data.street_number) {
                data.address1 = data.route + ' ' + data.street_number;
            } else if (data.route) {
                data.address1 = data.route;
            } else {
                // Fallback to formatted address, cleaned
                data.address1 = this.cleanAddress(place.formatted_address, data);
            }

            return data;
        },

        cleanAddress: function(formatted, data) {
            var clean = formatted;

            // Remove city, postcode, state, country
            if (data.city) clean = clean.replace(new RegExp(',?\\s*' + this.escapeRegex(data.city), 'gi'), '');
            if (data.postcode) clean = clean.replace(new RegExp(',?\\s*' + this.escapeRegex(data.postcode), 'gi'), '');
            if (data.state) clean = clean.replace(new RegExp(',?\\s*' + this.escapeRegex(data.state), 'gi'), '');
            if (data.country) clean = clean.replace(new RegExp(',?\\s*' + this.escapeRegex(data.country), 'gi'), '');

            // Clean up
            return clean.replace(/,\s*,/g, ',').replace(/,\s*$/g, '').replace(/^\s*,/g, '').trim();
        },

        escapeRegex: function(str) {
            return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
        },

        populateFields: function(address, type) {
            var self = this;
            var prefix = '#' + type + '_';

            // Set flag to prevent cascading updates from individual change events
            self.isPopulating = true;

            // Address line 1 - set value without triggering change
            if (address.address1) {
                $(prefix + 'address_1').val(address.address1);
            }

            // City - set value without triggering change
            if (address.city) {
                $(prefix + 'city').val(address.city);
            }

            // Postcode - set value without triggering change
            if (address.postcode) {
                $(prefix + 'postcode').val(address.postcode);
            }

            // State (if select)
            if (address.state) {
                var $state = $(prefix + 'state');
                if ($state.is('select')) {
                    // Try to match option
                    $state.find('option').each(function() {
                        if ($(this).val() === address.state || $(this).text() === address.state) {
                            $state.val($(this).val());
                            return false;
                        }
                    });
                } else {
                    $state.val(address.state);
                }
            }

            // Country - set value without triggering change
            if (address.country) {
                $(prefix + 'country').val(address.country);
            }

            // Clear the search field
            $(prefix + 'address_search').val('');

            // Reset flag after a brief delay to allow DOM to settle
            setTimeout(function() {
                self.isPopulating = false;
            }, 50);
        }
    };

    $(document).ready(function() {
        omAutocomplete.init();
    });

})(jQuery);
