<script>
document.addEventListener('alpine:init', () => {
    Alpine.data('rideSearch', () => ({
        init() {
            // Initialize from URL params
            const urlParams = new URLSearchParams(window.location.search);
            this.searchQuery = urlParams.get('search') || '';
            
            // Bind to form reset
            document.querySelector('form').addEventListener('reset', () => {
                this.searchQuery = '';
                this.showSuggestions = false;
                this.selectedIndex = -1;
                this.cleanup();
            });
            
            // Handle clicks outside suggestions
            document.addEventListener('click', (e) => {
                if (!e.target.closest('#search-suggestions') && !e.target.closest('#search')) {
                    this.showSuggestions = false;
                }
            });

            // Handle HTMX errors
            document.body.addEventListener('htmx:error', (evt) => {
                console.error('HTMX Error:', evt.detail.error);
                this.showError('An error occurred while searching. Please try again.');
            });
            
            // Store bound handlers for cleanup
            this.boundHandlers = new Map();
            
            // Create handler functions
            const popstateHandler = () => {
                const urlParams = new URLSearchParams(window.location.search);
                this.searchQuery = urlParams.get('search') || '';
                this.syncFormWithUrl();
            };
            this.boundHandlers.set('popstate', popstateHandler);
            
            const errorHandler = (evt) => {
                console.error('HTMX Error:', evt.detail.error);
                this.showError('An error occurred while searching. Please try again.');
            };
            this.boundHandlers.set('htmx:error', errorHandler);
            
            // Bind event listeners
            window.addEventListener('popstate', popstateHandler);
            document.body.addEventListener('htmx:error', errorHandler);
            
            // Restore filters from localStorage if no URL params exist
            const savedFilters = localStorage.getItem('rideFilters');
            
            // Set up destruction handler
            this.$cleanup = this.performCleanup.bind(this);
            if (savedFilters) {
                const filters = JSON.parse(savedFilters);
                Object.entries(filters).forEach(([key, value]) => {
                    const input = document.querySelector(`[name="${key}"]`);
                    if (input) input.value = value;
                });
                // Trigger search with restored filters
                document.querySelector('form').dispatchEvent(new Event('change'));
            }

            // Set up filter persistence
            document.querySelector('form').addEventListener('change', (e) => {
                this.saveFilters();
            });
        },

        showSuggestions: false,
        loading: false,
        searchQuery: '',
        suggestionTimeout: null,

        // Save current filters to localStorage
        saveFilters() {
            const form = document.querySelector('form');
            const formData = new FormData(form);
            const filters = {};
            for (let [key, value] of formData.entries()) {
                if (value) filters[key] = value;
            }
            localStorage.setItem('rideFilters', JSON.stringify(filters));
        },

        // Clear all filters
        clearFilters() {
            document.querySelectorAll('form select, form input').forEach(el => {
                el.value = '';
            });
            localStorage.removeItem('rideFilters');
            document.querySelector('form').dispatchEvent(new Event('change'));
        },

        // Get search suggestions with request tracking
        lastRequestId: 0,
        currentRequest: null,

        async getSearchSuggestions() {
            if (this.searchQuery.length < 2) {
                this.showSuggestions = false;
                return;
            }

            // Cancel any pending request
            if (this.currentRequest) {
                this.currentRequest.abort();
            }

            const requestId = ++this.lastRequestId;
            const controller = new AbortController();
            this.currentRequest = controller;
            
            const timeoutId = setTimeout(() => controller.abort(), 5000); // 5s timeout

            try {
                const response = await this.fetchSuggestions(controller, requestId);
                await this.handleSuggestionResponse(response, requestId);
            } catch (error) {
                this.handleSuggestionError(error, requestId);
            } finally {
                clearTimeout(timeoutId);
                if (this.currentRequest === controller) {
                    this.currentRequest = null;
                }
            }
        },

        async fetchSuggestions(controller, requestId) {
            const parkSlug = document.querySelector('input[name="park_slug"]')?.value;
            const url = `/rides/search-suggestions/?q=${encodeURIComponent(this.searchQuery)}${parkSlug ? '&park_slug=' + parkSlug : ''}`;

            const response = await fetch(url, {
                signal: controller.signal,
                headers: {
                    'X-Request-ID': requestId.toString()
                }
            });
            
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }
            return response;
        },

        async handleSuggestionResponse(response, requestId) {
            const html = await response.text();
            
            if (requestId === this.lastRequestId && this.searchQuery === document.getElementById('search').value) {
                const suggestionsEl = document.getElementById('search-suggestions');
                suggestionsEl.innerHTML = html;
                this.showSuggestions = Boolean(html.trim());
                
                this.updateAriaAttributes(suggestionsEl);
            }
        },

        updateAriaAttributes(suggestionsEl) {
            const searchInput = document.getElementById('search');
            searchInput.setAttribute('aria-expanded', this.showSuggestions.toString());
            searchInput.setAttribute('aria-controls', 'search-suggestions');
            if (this.showSuggestions) {
                suggestionsEl.setAttribute('role', 'listbox');
                suggestionsEl.querySelectorAll('button').forEach(btn => {
                    btn.setAttribute('role', 'option');
                });
            }
        },

        handleSuggestionError(error, requestId) {
            if (error.name === 'AbortError') {
                console.warn('Search suggestion request timed out or cancelled');
                return;
            }
            
            console.error('Error fetching suggestions:', error);
            if (requestId === this.lastRequestId) {
                const suggestionsEl = document.getElementById('search-suggestions');
                suggestionsEl.innerHTML = `
                    <div class="p-2 text-sm text-red-600 dark:text-red-400" role="alert">
                        Failed to load suggestions. Please try again.
                    </div>`;
                this.showSuggestions = true;
            }
        },

        // Handle input changes with debounce
        async handleInput() {
            clearTimeout(this.suggestionTimeout);
            this.suggestionTimeout = setTimeout(() => {
                this.getSearchSuggestions();
            }, 200);
        },

        // Handle suggestion selection
        // Sync form with URL parameters
        syncFormWithUrl() {
            const urlParams = new URLSearchParams(window.location.search);
            const form = document.querySelector('form');
            
            // Clear existing values
            form.querySelectorAll('input, select').forEach(el => {
                if (el.type !== 'hidden') el.value = '';
            });
            
            // Set values from URL
            urlParams.forEach((value, key) => {
                const input = form.querySelector(`[name="${key}"]`);
                if (input) input.value = value;
            });
            
            // Trigger form update
            form.dispatchEvent(new Event('change'));
        },

        // Cleanup resources
        cleanup() {
            clearTimeout(this.suggestionTimeout);
            this.showSuggestions = false;
            localStorage.removeItem('rideFilters');
        },

        selectSuggestion(text) {
            this.searchQuery = text;
            this.showSuggestions = false;
            document.getElementById('search').value = text;
            
            // Update URL with search parameter
            const url = new URL(window.location);
            url.searchParams.set('search', text);
            window.history.pushState({}, '', url);
            
            document.querySelector('form').dispatchEvent(new Event('change'));
        },

        // Handle keyboard navigation
        // Show error message
        showError(message) {
            const searchInput = document.getElementById('search');
            const errorDiv = document.createElement('div');
            errorDiv.className = 'text-red-600 text-sm mt-1';
            errorDiv.textContent = message;
            searchInput.parentNode.appendChild(errorDiv);
            setTimeout(() => errorDiv.remove(), 3000);
        },

        // Handle keyboard navigation
        handleKeydown(e) {
            const suggestions = document.querySelectorAll('#search-suggestions button');
            if (!suggestions.length) return;

            const currentIndex = Array.from(suggestions).findIndex(el => el === document.activeElement);

            switch(e.key) {
                case 'ArrowDown':
                    e.preventDefault();
                    if (currentIndex < 0) {
                        suggestions[0].focus();
                        this.selectedIndex = 0;
                    } else if (currentIndex < suggestions.length - 1) {
                        suggestions[currentIndex + 1].focus();
                        this.selectedIndex = currentIndex + 1;
                    }
                    break;
                case 'ArrowUp':
                    e.preventDefault();
                    if (currentIndex > 0) {
                        suggestions[currentIndex - 1].focus();
                        this.selectedIndex = currentIndex - 1;
                    } else {
                        document.getElementById('search').focus();
                        this.selectedIndex = -1;
                    }
                    break;
                case 'Escape':
                    this.showSuggestions = false;
                    this.selectedIndex = -1;
                    document.getElementById('search').blur();
                    break;
                case 'Enter':
                    if (document.activeElement.tagName === 'BUTTON') {
                        e.preventDefault();
                        this.selectSuggestion(document.activeElement.dataset.text);
                    }
                    break;
                case 'Tab':
                    this.showSuggestions = false;
                    break;
            }
        }
    }));
});
        },

        performCleanup() {
            // Remove all bound event listeners
            this.boundHandlers.forEach(this.removeEventHandler.bind(this));
            this.boundHandlers.clear();
            
            // Cancel any pending requests
            if (this.currentRequest) {
                this.currentRequest.abort();
                this.currentRequest = null;
            }
            
            // Clear any pending timeouts
            if (this.suggestionTimeout) {
                clearTimeout(this.suggestionTimeout);
            }
        },

        removeEventHandler(handler, event) {
            if (event === 'popstate') {
                window.removeEventListener(event, handler);
            } else {
                document.body.removeEventListener(event, handler);
            }
        }
    }));
});
</script>

<!-- HTMX Loading Indicator Styles -->
<style>
.htmx-indicator {
    opacity: 0;
    transition: opacity 200ms ease-in;
}
.htmx-request .htmx-indicator {
    opacity: 1
}

/* Enhanced Loading Indicator */
.loading-indicator {
    position: fixed;
    bottom: 1rem;
    right: 1rem;
    z-index: 50;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: white;
    font-size: 0.875rem;
}

.loading-indicator svg {
    width: 1.25rem;
    height: 1.25rem;
    animation: spin 1s linear infinite;
}

@keyframes spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}
</style>

<script>
// Initialize request timeout management
const timeouts = new Map();

// Handle request start
document.addEventListener('htmx:beforeRequest', function(evt) {
    const timestamp = document.querySelector('.loading-timestamp');
    if (timestamp) {
        timestamp.textContent = new Date().toLocaleTimeString();
    }

    // Set timeout for request
    const timeoutId = setTimeout(() => {
        evt.detail.xhr.abort();
        showError('Request timed out. Please try again.');
    }, 10000); // 10s timeout

    timeouts.set(evt.detail.xhr, timeoutId);
});

// Handle request completion
document.addEventListener('htmx:afterRequest', function(evt) {
    const timeoutId = timeouts.get(evt.detail.xhr);
    if (timeoutId) {
        clearTimeout(timeoutId);
        timeouts.delete(evt.detail.xhr);
    }

    if (!evt.detail.successful) {
        showError('Failed to update results. Please try again.');
    }
});

// Handle errors
function showError(message) {
    const indicator = document.querySelector('.loading-indicator');
    if (indicator) {
        indicator.innerHTML = `
            <div class="flex items-center text-red-100">
                <i class="mr-2 fas fa-exclamation-circle"></i>
                <span>${message}</span>
            </div>`;
        setTimeout(() => {
            indicator.innerHTML = originalIndicatorContent;
        }, 3000);
    }
}

// Store original indicator content
const originalIndicatorContent = document.querySelector('.loading-indicator')?.innerHTML;

// Reset loading state when navigating away
window.addEventListener('beforeunload', () => {
    timeouts.forEach(timeoutId => clearTimeout(timeoutId));
    timeouts.clear();
});
</script>