/**
 * Search Results Keyboard Navigation
 * Handles Arrow Up/Down, Enter, and Escape keys for accessible search
 *
 * This module enhances search inputs with keyboard navigation for WCAG compliance:
 * - Arrow Down: Navigate to next search result
 * - Arrow Up: Navigate to previous search result (or back to input)
 * - Enter: Select current result (navigate to link)
 * - Escape: Close search results and blur input
 *
 * Usage:
 *   The script automatically initializes on DOMContentLoaded for all search inputs
 *   with hx-target attribute pointing to a results container.
 *
 * HTMX Integration:
 *   Results should include role="option" on each selectable item.
 *   The script listens for htmx:afterSwap to reinitialize when results change.
 */

(function() {
    'use strict';

    /**
     * Initialize keyboard navigation for a search input
     * @param {HTMLInputElement} input - The search input element
     */
    function initSearchAccessibility(input) {
        const targetSelector = input.getAttribute('hx-target');
        if (!targetSelector) return;

        const resultsContainer = document.querySelector(targetSelector);
        if (!resultsContainer) return;

        // Track if we've already initialized this input
        if (input.dataset.searchAccessibilityInit) return;
        input.dataset.searchAccessibilityInit = 'true';

        let currentIndex = -1;

        /**
         * Update visual and ARIA selection state for results
         * @param {NodeList} results - List of result option elements
         * @param {number} index - Index of currently selected item (-1 for none)
         */
        function updateSelection(results, index) {
            results.forEach((result, i) => {
                if (i === index) {
                    result.setAttribute('aria-selected', 'true');
                    result.classList.add('bg-accent');
                    result.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
                } else {
                    result.setAttribute('aria-selected', 'false');
                    result.classList.remove('bg-accent');
                }
            });

            // Update aria-activedescendant on the input
            if (index >= 0 && results[index]) {
                const resultId = results[index].id || `search-result-${index}`;
                if (!results[index].id) {
                    results[index].id = resultId;
                }
                input.setAttribute('aria-activedescendant', resultId);
            } else {
                input.removeAttribute('aria-activedescendant');
            }
        }

        /**
         * Announce result count to screen readers
         * @param {number} count - Number of results found
         */
        function announceResults(count) {
            const statusId = input.getAttribute('aria-describedby');
            if (statusId) {
                const statusEl = document.getElementById(statusId);
                if (statusEl) {
                    if (count === 0) {
                        statusEl.textContent = 'No results found';
                    } else if (count === 1) {
                        statusEl.textContent = '1 result found. Use arrow keys to navigate.';
                    } else {
                        statusEl.textContent = `${count} results found. Use arrow keys to navigate.`;
                    }
                    // Clear after a delay to allow re-announcement on new searches
                    setTimeout(() => {
                        statusEl.textContent = '';
                    }, 1500);
                }
            }
        }

        /**
         * Handle keydown events for navigation
         * @param {KeyboardEvent} e - The keyboard event
         */
        function handleKeydown(e) {
            const results = resultsContainer.querySelectorAll('[role="option"]');

            // If no results and not escape, let default behavior happen
            if (results.length === 0 && e.key !== 'Escape') {
                return;
            }

            switch(e.key) {
                case 'ArrowDown':
                    e.preventDefault();
                    if (results.length > 0) {
                        currentIndex = Math.min(currentIndex + 1, results.length - 1);
                        updateSelection(results, currentIndex);
                    }
                    break;

                case 'ArrowUp':
                    e.preventDefault();
                    if (currentIndex > 0) {
                        currentIndex = currentIndex - 1;
                        updateSelection(results, currentIndex);
                    } else if (currentIndex === 0) {
                        // Move back to input
                        currentIndex = -1;
                        updateSelection(results, currentIndex);
                        input.focus();
                    }
                    break;

                case 'Enter':
                    if (currentIndex >= 0 && results[currentIndex]) {
                        e.preventDefault();
                        const link = results[currentIndex].querySelector('a');
                        if (link) {
                            link.click();
                        } else if (results[currentIndex].tagName === 'A') {
                            results[currentIndex].click();
                        }
                    }
                    break;

                case 'Escape':
                    e.preventDefault();
                    // Clear results and reset
                    resultsContainer.innerHTML = '';
                    currentIndex = -1;
                    input.blur();
                    break;

                case 'Home':
                    if (results.length > 0) {
                        e.preventDefault();
                        currentIndex = 0;
                        updateSelection(results, currentIndex);
                    }
                    break;

                case 'End':
                    if (results.length > 0) {
                        e.preventDefault();
                        currentIndex = results.length - 1;
                        updateSelection(results, currentIndex);
                    }
                    break;
            }
        }

        // Add keydown listener
        input.addEventListener('keydown', handleKeydown);

        // Reset index when input changes
        input.addEventListener('input', function() {
            currentIndex = -1;
        });

        // Reset on focus
        input.addEventListener('focus', function() {
            currentIndex = -1;
        });

        // Listen for HTMX swap events to announce results
        resultsContainer.addEventListener('htmx:afterSwap', function() {
            currentIndex = -1;
            const results = resultsContainer.querySelectorAll('[role="option"]');
            announceResults(results.length);
        });
    }

    /**
     * Initialize all search inputs on the page
     */
    function initAllSearchInputs() {
        const searchInputs = document.querySelectorAll('input[type="search"][hx-target], input[type="text"][hx-target][name="q"]');
        searchInputs.forEach(initSearchAccessibility);
    }

    // Initialize on DOMContentLoaded
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initAllSearchInputs);
    } else {
        initAllSearchInputs();
    }

    // Re-initialize after HTMX swaps that might add new search inputs
    document.body.addEventListener('htmx:afterSettle', function(evt) {
        // Only reinitialize if new search inputs were added
        if (evt.target.querySelector && evt.target.querySelector('input[type="search"], input[name="q"]')) {
            initAllSearchInputs();
        }
    });

    // Also listen for status announcements from HTMX responses
    document.body.addEventListener('announceStatus', function(evt) {
        const announcer = document.getElementById('status-announcer');
        if (announcer && evt.detail && evt.detail.message) {
            announcer.textContent = evt.detail.message;
            setTimeout(() => {
                announcer.textContent = '';
            }, 1500);
        }
    });

})();
