/**
 * QuerySuggestionsDropdown Component
 *
 * Classic dropdown variant with:
 * - Highlighted matches
 * - Keyboard navigation
 * - Recent searches
 * - Customizable styling
 * - Analytics tracking
 * - Accessibility support
 */
import React, { useState, useEffect, useRef, useCallback, useMemo, forwardRef, useImperativeHandle, } from 'react';
import { useSearchContext } from './SearchProvider';
import { useQuerySuggestionsEnhanced } from '../hooks/useQuerySuggestionsEnhanced';
import { clsx } from 'clsx';
// ============================================================================
// Constants
// ============================================================================
const TRANSITIONS = {
    fast: '150ms ease-in-out',
    normal: '200ms ease-in-out',
    slow: '300ms ease-in-out',
};
const BORDER_RADIUS = {
    sm: 4,
    md: 6,
    lg: 8,
    full: 9999,
};
// ============================================================================
// Styles
// ============================================================================
const defaultStyles = {
    container: {
        backgroundColor: 'var(--seekora-bg-surface, transparent)',
        border: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
        borderRadius: `var(--seekora-border-radius, ${BORDER_RADIUS.lg}px)`,
        boxShadow: 'var(--seekora-shadow-lg, 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05))',
        maxHeight: '400px',
        overflowY: 'auto',
        overflowX: 'hidden',
    },
    section: {
        padding: '8px 0',
    },
    sectionTitle: {
        fontSize: '12px',
        fontWeight: 600,
        color: 'var(--seekora-text-secondary, inherit)',
        textTransform: 'uppercase',
        letterSpacing: '0.05em',
        padding: '8px 16px 4px',
        margin: 0,
    },
    suggestionItem: {
        display: 'flex',
        alignItems: 'center',
        padding: '10px 16px',
        cursor: 'pointer',
        transition: `background-color ${TRANSITIONS.fast}`,
        fontSize: '14px',
        color: 'var(--seekora-text-primary, inherit)',
        gap: '12px',
    },
    suggestionItemActive: {
        backgroundColor: 'var(--seekora-bg-hover, #f3f4f6)',
    },
    suggestionQuery: {
        flex: 1,
        overflow: 'hidden',
        textOverflow: 'ellipsis',
        whiteSpace: 'nowrap',
    },
    suggestionCount: {
        fontSize: '12px',
        color: 'var(--seekora-text-secondary, #9ca3af)',
        marginLeft: 'auto',
        flexShrink: 0,
    },
    highlight: {
        fontWeight: 600,
        color: 'var(--seekora-text-primary, inherit)',
        backgroundColor: 'var(--seekora-highlight-bg, #fef3c7)',
        padding: '0 2px',
        borderRadius: `${BORDER_RADIUS.sm / 2}px`,
    },
    recentIcon: {
        width: '16px',
        height: '16px',
        color: 'var(--seekora-text-secondary, #9ca3af)',
        flexShrink: 0,
    },
    removeButton: {
        padding: '4px',
        borderRadius: `${BORDER_RADIUS.sm}px`,
        border: 'none',
        background: 'transparent',
        cursor: 'pointer',
        color: 'var(--seekora-text-secondary, #9ca3af)',
        opacity: 0,
        transition: `opacity ${TRANSITIONS.fast}, color ${TRANSITIONS.fast}`,
    },
    removeButtonVisible: {
        opacity: 1,
    },
    emptyState: {
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'center',
        padding: '24px 16px',
        color: 'var(--seekora-text-secondary, inherit)',
        fontSize: '14px',
        textAlign: 'center',
    },
    divider: {
        height: '1px',
        backgroundColor: 'var(--seekora-border-color, rgba(128,128,128,0.2))',
        margin: '4px 0',
    },
    footer: {
        borderTop: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
        padding: '8px 16px',
        fontSize: '12px',
        color: 'var(--seekora-text-secondary, inherit)',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'space-between',
    },
    keyboardHint: {
        display: 'flex',
        alignItems: 'center',
        gap: '8px',
        fontSize: '11px',
    },
    keyboardKey: {
        display: 'inline-flex',
        alignItems: 'center',
        justifyContent: 'center',
        minWidth: '20px',
        height: '18px',
        padding: '0 4px',
        borderRadius: `${BORDER_RADIUS.sm - 1}px`,
        backgroundColor: 'var(--seekora-bg-secondary, rgba(255, 255, 255, 0.1))',
        border: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
        fontSize: '10px',
        fontWeight: 500,
    },
};
// ============================================================================
// Icons
// ============================================================================
const SearchIcon = ({ className, style }) => (React.createElement("svg", { className: className, style: style, viewBox: "0 0 20 20", fill: "currentColor", width: "16", height: "16" },
    React.createElement("path", { fillRule: "evenodd", d: "M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z", clipRule: "evenodd" })));
const ClockIcon = ({ className, style }) => (React.createElement("svg", { className: className, style: style, viewBox: "0 0 20 20", fill: "currentColor", width: "16", height: "16" },
    React.createElement("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z", clipRule: "evenodd" })));
const CloseIcon = ({ className, style }) => (React.createElement("svg", { className: className, style: style, viewBox: "0 0 20 20", fill: "currentColor", width: "16", height: "16" },
    React.createElement("path", { fillRule: "evenodd", d: "M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z", clipRule: "evenodd" })));
// ============================================================================
// Component
// ============================================================================
export const QuerySuggestionsDropdown = forwardRef(function QuerySuggestionsDropdown(props, ref) {
    const { query, isOpen = true, maxSuggestions = 8, minQueryLength = 1, debounceMs = 200, showRecentSearches = true, maxRecentSearches = 5, showCounts = true, showEmptyState = true, highlight = { enabled: true, preTag: '<mark>', postTag: '</mark>' }, keyboardNav = { enabled: true }, animation = { enabled: true, duration: 150, entrance: 'fade' }, classNames = {}, style, renderSuggestion, renderRecentSearch, renderEmpty, footer, position = 'absolute', width = '100%', zIndex = 1000, closeOnClickOutside = true, closeOnEscape = true, ariaLabel = 'Search suggestions', onSuggestionSelect, onRecentSearchClick, onRecentSearchRemove, onOpen, onClose, onNavigate, } = props;
    const { client, theme } = useSearchContext();
    const containerRef = useRef(null);
    const [activeIndex, setActiveIndex] = useState(-1);
    const [isVisible, setIsVisible] = useState(false);
    // Use enhanced hook
    const { suggestions, loading, error, recentSearches, addRecentSearch, removeRecentSearch, hasContent, } = useQuerySuggestionsEnhanced({
        client,
        query,
        enabled: isOpen && query.length >= minQueryLength,
        debounceMs,
        maxSuggestions,
        minQueryLength,
        enableRecentSearches: showRecentSearches,
        maxRecentSearches,
    });
    // Calculate all navigable items
    const allItems = useMemo(() => {
        const items = [];
        // Add recent searches if query is empty or short
        if (showRecentSearches && query.length === 0 && recentSearches.length > 0) {
            recentSearches.slice(0, maxRecentSearches).forEach(search => {
                items.push({ type: 'recent', data: search });
            });
        }
        // Add suggestions
        suggestions.forEach(suggestion => {
            items.push({ type: 'suggestion', data: suggestion });
        });
        return items;
    }, [suggestions, recentSearches, query, showRecentSearches, maxRecentSearches]);
    // Handle visibility animation
    useEffect(() => {
        if (isOpen && (hasContent || loading)) {
            setIsVisible(true);
            onOpen?.();
        }
        else {
            if (animation.enabled) {
                const timer = setTimeout(() => setIsVisible(false), animation.duration);
                return () => clearTimeout(timer);
            }
            else {
                setIsVisible(false);
            }
            onClose?.();
        }
    }, [isOpen, hasContent, loading, animation.enabled, animation.duration, onOpen, onClose]);
    // Reset active index when items change
    useEffect(() => {
        setActiveIndex(-1);
    }, [allItems.length]);
    // Keyboard navigation
    const navigateNext = useCallback(() => {
        if (!keyboardNav.enabled)
            return;
        setActiveIndex(prev => {
            const next = prev < allItems.length - 1 ? prev + 1 : 0;
            onNavigate?.('down', next);
            return next;
        });
    }, [keyboardNav.enabled, allItems.length, onNavigate]);
    const navigatePrevious = useCallback(() => {
        if (!keyboardNav.enabled)
            return;
        setActiveIndex(prev => {
            const next = prev > 0 ? prev - 1 : allItems.length - 1;
            onNavigate?.('up', next);
            return next;
        });
    }, [keyboardNav.enabled, allItems.length, onNavigate]);
    const selectActive = useCallback(() => {
        if (activeIndex < 0 || activeIndex >= allItems.length)
            return;
        const item = allItems[activeIndex];
        if (item.type === 'recent') {
            const search = item.data;
            onRecentSearchClick?.(search);
        }
        else {
            const suggestion = item.data;
            onSuggestionSelect?.(suggestion);
            addRecentSearch(suggestion.query, suggestion.count);
        }
    }, [activeIndex, allItems, onRecentSearchClick, onSuggestionSelect, addRecentSearch]);
    const resetSelection = useCallback(() => {
        setActiveIndex(-1);
    }, []);
    // Expose methods via ref
    useImperativeHandle(ref, () => ({
        selectActive,
        navigateNext,
        navigatePrevious,
        resetSelection,
        getActiveIndex: () => activeIndex,
        getTotalItems: () => allItems.length,
    }), [selectActive, navigateNext, navigatePrevious, resetSelection, activeIndex, allItems.length]);
    // Click outside handler
    useEffect(() => {
        if (!closeOnClickOutside || !isOpen)
            return;
        const handleClickOutside = (event) => {
            if (containerRef.current && !containerRef.current.contains(event.target)) {
                onClose?.();
            }
        };
        document.addEventListener('mousedown', handleClickOutside);
        return () => document.removeEventListener('mousedown', handleClickOutside);
    }, [closeOnClickOutside, isOpen, onClose]);
    // Highlight text helper
    const highlightText = useCallback((text, searchQuery) => {
        if (!highlight.enabled || !searchQuery) {
            return text;
        }
        const parts = text.split(new RegExp(`(${searchQuery})`, 'gi'));
        return parts.map((part, i) => part.toLowerCase() === searchQuery.toLowerCase() ? (React.createElement("mark", { key: i, className: classNames.suggestionItemHighlight, style: defaultStyles.highlight }, part)) : part);
    }, [highlight.enabled, classNames.suggestionItemHighlight]);
    // Parse highlighted query from API
    const parseHighlightedQuery = useCallback((suggestion) => {
        if (suggestion.highlightedQuery && highlight.enabled) {
            // Parse the highlighted HTML
            return (React.createElement("span", { dangerouslySetInnerHTML: { __html: suggestion.highlightedQuery }, style: { display: 'inline' } }));
        }
        return highlightText(suggestion.query, query);
    }, [highlight.enabled, highlightText, query]);
    // Render helpers
    const renderSuggestionItem = (suggestion, index, isActive) => {
        if (renderSuggestion) {
            return renderSuggestion(suggestion, index, isActive, (text) => highlightText(text, query));
        }
        return (React.createElement("div", { style: {
                ...defaultStyles.suggestionItem,
                ...(isActive ? defaultStyles.suggestionItemActive : {}),
            } },
            React.createElement(SearchIcon, { style: defaultStyles.recentIcon }),
            React.createElement("span", { style: defaultStyles.suggestionQuery }, parseHighlightedQuery(suggestion)),
            showCounts && suggestion.count !== undefined && (React.createElement("span", { style: defaultStyles.suggestionCount }, suggestion.count.toLocaleString()))));
    };
    const renderRecentSearchItem = (search, index, isActive) => {
        if (renderRecentSearch) {
            return renderRecentSearch(search, index, isActive);
        }
        return (React.createElement("div", { style: {
                ...defaultStyles.suggestionItem,
                ...(isActive ? defaultStyles.suggestionItemActive : {}),
            } },
            React.createElement(ClockIcon, { style: defaultStyles.recentIcon }),
            React.createElement("span", { style: defaultStyles.suggestionQuery }, search.query),
            React.createElement("button", { type: "button", onClick: (e) => {
                    e.stopPropagation();
                    removeRecentSearch(search.query);
                    onRecentSearchRemove?.(search);
                }, style: {
                    ...defaultStyles.removeButton,
                    ...(isActive ? defaultStyles.removeButtonVisible : {}),
                }, "aria-label": `Remove ${search.query} from recent searches` },
                React.createElement(CloseIcon, null))));
    };
    // Don't render if not visible
    if (!isVisible && !isOpen) {
        return null;
    }
    // Determine what to show
    const showRecent = showRecentSearches && query.length === 0 && recentSearches.length > 0;
    const showSuggestions = suggestions.length > 0;
    const showEmpty = showEmptyState && !loading && !showRecent && !showSuggestions && query.length >= minQueryLength;
    // Animation styles
    const animationStyle = animation.enabled
        ? {
            opacity: isOpen ? 1 : 0,
            transform: isOpen ? 'translateY(0)' : 'translateY(-8px)',
            transition: `opacity ${animation.duration}ms ease, transform ${animation.duration}ms ease`,
        }
        : {};
    return (React.createElement("div", { ref: containerRef, role: "listbox", "aria-label": ariaLabel, "aria-expanded": isOpen, className: clsx('seekora-suggestions-dropdown', classNames.root, classNames.container), style: {
            position,
            width,
            zIndex,
            ...defaultStyles.container,
            ...animationStyle,
            ...style,
        } },
        showRecent && (React.createElement("div", { className: clsx('seekora-suggestions-section', classNames.section, classNames.recentSearches) },
            React.createElement("div", { className: classNames.sectionTitle, style: defaultStyles.sectionTitle }, "Recent Searches"),
            recentSearches.slice(0, maxRecentSearches).map((search, index) => {
                const isActive = activeIndex === index;
                return (React.createElement("div", { key: `recent-${search.query}-${index}`, role: "option", "aria-selected": isActive, className: clsx(classNames.recentItem, isActive && classNames.suggestionItemActive), onClick: () => {
                        onRecentSearchClick?.(search);
                    }, onMouseEnter: () => setActiveIndex(index) }, renderRecentSearchItem(search, index, isActive)));
            }))),
        showRecent && showSuggestions && (React.createElement("div", { style: defaultStyles.divider })),
        showSuggestions && (React.createElement("div", { className: clsx('seekora-suggestions-section', classNames.section, classNames.suggestionsList) },
            query.length > 0 && (React.createElement("div", { className: classNames.sectionTitle, style: defaultStyles.sectionTitle }, "Suggestions")),
            suggestions.map((suggestion, index) => {
                const itemIndex = showRecent ? recentSearches.length + index : index;
                const isActive = activeIndex === itemIndex;
                return (React.createElement("div", { key: suggestion.objectID || `suggestion-${index}`, role: "option", "aria-selected": isActive, className: clsx(classNames.suggestionItem, isActive && classNames.suggestionItemActive), onClick: () => {
                        onSuggestionSelect?.(suggestion);
                        addRecentSearch(suggestion.query, suggestion.count);
                    }, onMouseEnter: () => setActiveIndex(itemIndex) }, renderSuggestionItem(suggestion, index, isActive)));
            }))),
        showEmpty && (React.createElement("div", { className: classNames.emptyState, style: defaultStyles.emptyState }, renderEmpty ? renderEmpty() : (React.createElement(React.Fragment, null,
            React.createElement(SearchIcon, { style: { width: 24, height: 24, marginBottom: 8, opacity: 0.5 } }),
            React.createElement("span", null,
                "No suggestions found for \"",
                query,
                "\""))))),
        footer || (keyboardNav.enabled && allItems.length > 0) ? (React.createElement("div", { className: classNames.footer, style: defaultStyles.footer }, footer || (React.createElement("div", { style: defaultStyles.keyboardHint },
            React.createElement("span", { style: defaultStyles.keyboardKey }, "\u2191"),
            React.createElement("span", { style: defaultStyles.keyboardKey }, "\u2193"),
            React.createElement("span", null, "to navigate"),
            React.createElement("span", { style: defaultStyles.keyboardKey }, "\u21B5"),
            React.createElement("span", null, "to select"),
            React.createElement("span", { style: defaultStyles.keyboardKey }, "esc"),
            React.createElement("span", null, "to close"))))) : null,
        React.createElement("style", null, `
        @keyframes spin {
          from { transform: rotate(0deg); }
          to { transform: rotate(360deg); }
        }
        .seekora-suggestions-dropdown mark {
          background-color: var(--seekora-highlight-bg, #fef3c7);
          font-weight: 600;
          padding: 0 2px;
          border-radius: 2px;
        }
        .seekora-suggestions-dropdown [role="option"]:hover button {
          opacity: 1;
        }
      `)));
});
export default QuerySuggestionsDropdown;
