class ZipCodeCityUpdater {
    constructor(zipCodeInputSelector, citySelectSelector, apiUrl) {
        this.zipCodeInput = document.querySelector(zipCodeInputSelector);
        this.citySelect = document.querySelector(citySelectSelector); // Changed to citySelect
        this.apiUrl = apiUrl;
        this.timer = null;
        this.debounceTime = 500; // ms

        // Store initial value from the select element (if any was pre-selected by Twig)
        this.initialCityValue = this.citySelect ? this.citySelect.value : '';

        if (this.zipCodeInput && this.citySelect) {
            this.zipCodeInput.addEventListener('input', this.debounce(this.handleZipCodeChange.bind(this)));
            // Trigger on page load if a zip code is already present
            if (this.zipCodeInput.value) {
                this.handleZipCodeChange();
            }
        }
    }

    debounce(func) {
        return function(...args) {
            const context = this;
            clearTimeout(context.timer);
            context.timer = setTimeout(() => func.apply(context, args), context.debounceTime);
        };
    }

    async handleZipCodeChange() {
        const zipCode = this.zipCodeInput.value.trim();

        // Save current city selection if any, before clearing
        const currentlySelectedCity = this.citySelect.value;

        // Clear existing options, but keep the default placeholder if any
        this.citySelect.innerHTML = '<option value="">Sélectionnez une ville</option>';
        this.citySelect.value = '';
        this.citySelect.disabled = true; // Disable until cities are loaded or cleared

        if (zipCode.length !== 5 || !/^\d+$/.test(zipCode)) {
            // If zip code is invalid or empty, disable and reset select
            this.citySelect.disabled = false; // Re-enable for placeholder
            return;
        }

        try {
            const response = await fetch(this.apiUrl, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({ zipCode: zipCode }),
            });

            if (!response.ok) {
                console.error(`HTTP error! status: ${response.status}`);
                this.citySelect.disabled = false; // Re-enable for placeholder
                return;
            }

            const data = await response.json();

            if (data.cities && data.cities.length > 0) {
                data.cities.forEach(city => {
                    const option = document.createElement('option');
                    option.value = city;
                    option.textContent = city;
                    this.citySelect.appendChild(option);
                });

                // Attempt to re-select the city that was previously selected, or the initial one
                if (data.cities.includes(currentlySelectedCity)) {
                    this.citySelect.value = currentlySelectedCity;
                } else if (data.cities.includes(this.initialCityValue)) {
                    this.citySelect.value = this.initialCityValue;
                } else if (data.cities.length === 1) {
                    // Automatically select if only one city is returned and no previous match
                    this.citySelect.value = data.cities[0];
                }
                this.citySelect.disabled = false; // Enable once options are loaded
            } else {
                // If no cities found, ensure select is enabled but shows only placeholder
                this.citySelect.disabled = false;
            }

        } catch (error) {
            console.error('Error fetching city:', error);
            this.citySelect.disabled = false; // Re-enable on error
        }
    }
}

// Global initialization - run when the DOM is fully loaded or Turbo loads a new page
document.addEventListener('turbo:load', () => {
    // Note: Use CSS selectors for querySelector
    new ZipCodeCityUpdater('input[name="billingZipCode"]', '#billingTownSelect', '/cities/lookup');
    new ZipCodeCityUpdater('input[name="zipCodeEvent"]', '#townEventSelect', '/cities/lookup');
});
