/**
 * SearchBar Component
 *
 * Interactive search input component with query suggestions support
 */
import React, { useState, useRef, useEffect, useCallback } from 'react';
import { useSearchContext } from './SearchProvider';
import { useSearchState } from '../hooks/useSearchState';
import { useQuerySuggestions } from '../hooks/useQuerySuggestions';
import { log } from '@seekora-ai/ui-sdk-core';
import { clsx } from 'clsx';
// Z-index scale for consistent layering
const Z_INDEX = {
    dropdown: 100,
    modal: 200,
    overlay: 300,
    tooltip: 50,
};
const SIZE_CONFIG = {
    small: {
        padding: '0.375rem 0.5rem',
        fontSize: '0.875rem',
        iconSize: 14,
        iconPaddingLeft: '1.75rem',
        iconPaddingRight: '1.75rem',
        iconLeft: '0.5rem',
        iconRight: '0.5rem',
    },
    medium: {
        padding: '0.625rem 1rem',
        fontSize: '1rem',
        iconSize: 18,
        iconPaddingLeft: '2.25rem',
        iconPaddingRight: '2.25rem',
        iconLeft: '0.625rem',
        iconRight: '0.625rem',
    },
    large: {
        padding: '0.875rem 1.25rem',
        fontSize: '1.25rem',
        iconSize: 22,
        iconPaddingLeft: '2.75rem',
        iconPaddingRight: '2.75rem',
        iconLeft: '0.75rem',
        iconRight: '0.75rem',
    },
};
const DefaultSearchIcon = ({ size = 18 }) => (React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" },
    React.createElement("circle", { cx: "11", cy: "11", r: "8" }),
    React.createElement("line", { x1: "21", y1: "21", x2: "16.65", y2: "16.65" })));
const DefaultClearIcon = ({ size = 14 }) => (React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" },
    React.createElement("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
    React.createElement("line", { x1: "6", y1: "6", x2: "18", y2: "18" })));
export const SearchBar = ({ placeholder = 'Powered by Seekora', showSuggestions = true, debounceMs = 300, minQueryLength = 2, maxSuggestions = 10, onSearch, onQueryChange, onSuggestionSelect, onSearchStateChange, searchOptions, className, style, theme: customTheme, renderSuggestion, renderSearchIcon, showClearButton = true, renderClearIcon, showSubmitButton = false, renderSubmitButton, size = 'medium', searchAsYouType = false, }) => {
    const { client, theme, enableAnalytics, autoTrackSearch } = useSearchContext();
    const { query, setQuery, search: triggerSearch, results, loading: searchLoading, error: searchError } = useSearchState();
    const [isFocused, setIsFocused] = useState(false);
    const [selectedIndex, setSelectedIndex] = useState(-1);
    const inputRef = useRef(null);
    const containerRef = useRef(null);
    const isSearchingRef = useRef(false); // Flag to prevent blur handler from interfering
    const searchAsYouTypeRef = useRef(null);
    // Cleanup searchAsYouType timer on unmount
    useEffect(() => {
        return () => {
            if (searchAsYouTypeRef.current)
                clearTimeout(searchAsYouTypeRef.current);
        };
    }, []);
    const { suggestions, loading: suggestionsLoading } = useQuerySuggestions({
        client,
        query,
        enabled: showSuggestions && query.length >= minQueryLength,
        debounceMs,
        maxSuggestions,
    });
    const displayedSuggestions = suggestions.slice(0, maxSuggestions);
    // Expose search state to parent
    useEffect(() => {
        if (onSearchStateChange) {
            onSearchStateChange({
                results,
                loading: searchLoading,
                error: searchError,
            });
        }
    }, [results, searchLoading, searchError, onSearchStateChange]);
    useEffect(() => {
        if (results && onSearch) {
            onSearch(query, results);
        }
    }, [results, query, onSearch]);
    useEffect(() => {
        if (onQueryChange) {
            onQueryChange(query);
        }
    }, [query, onQueryChange]);
    const handleSearch = useCallback(async (searchQuery) => {
        // Cancel any pending searchAsYouType debounce — user explicitly submitted
        if (searchAsYouTypeRef.current) {
            clearTimeout(searchAsYouTypeRef.current);
            searchAsYouTypeRef.current = null;
        }
        // Allow empty queries - use empty string for search
        const query = searchQuery.trim();
        log.info('SearchBar: Triggering search', { query, originalQuery: searchQuery, isEmpty: !query });
        // Set flag to prevent blur handler from interfering
        isSearchingRef.current = true;
        // Close suggestions first
        setIsFocused(false);
        setSelectedIndex(-1);
        // Update query in state manager (don't trigger search yet - we'll do it explicitly)
        setQuery(query, false);
        // Explicitly trigger search immediately (bypass debounce for Enter key)
        log.info('SearchBar: Calling search() directly');
        await triggerSearch();
        // Blur after a small delay to ensure search is triggered
        setTimeout(() => {
            inputRef.current?.blur();
            // Reset flag after blur
            setTimeout(() => {
                isSearchingRef.current = false;
            }, 50);
        }, 100);
    }, [setQuery, triggerSearch]);
    const handleSuggestionSelect = useCallback((suggestion) => {
        log.verbose('SearchBar: Suggestion selected', { suggestion });
        setSelectedIndex(-1);
        setIsFocused(false);
        inputRef.current?.blur();
        if (onSuggestionSelect) {
            onSuggestionSelect(suggestion);
        }
        // Update query and trigger search
        setQuery(suggestion);
    }, [onSuggestionSelect, setQuery]);
    const handleInputChange = useCallback((e) => {
        const value = e.target.value;
        // Update query in state manager but don't trigger search immediately
        // Search will be triggered on Enter, suggestion select, or after debounce if searchAsYouType
        setQuery(value, false); // false = don't trigger search immediately
        setSelectedIndex(-1);
        if (searchAsYouType) {
            if (searchAsYouTypeRef.current)
                clearTimeout(searchAsYouTypeRef.current);
            searchAsYouTypeRef.current = setTimeout(() => {
                searchAsYouTypeRef.current = null;
                triggerSearch();
            }, debounceMs);
        }
    }, [setQuery, searchAsYouType, debounceMs, triggerSearch]);
    const handleKeyDown = useCallback((e) => {
        switch (e.key) {
            case 'ArrowDown':
                if (showSuggestions && displayedSuggestions.length > 0) {
                    e.preventDefault();
                    setSelectedIndex((prev) => prev < displayedSuggestions.length - 1 ? prev + 1 : prev);
                }
                break;
            case 'ArrowUp':
                if (showSuggestions && displayedSuggestions.length > 0) {
                    e.preventDefault();
                    setSelectedIndex((prev) => (prev > 0 ? prev - 1 : -1));
                }
                break;
            case 'Enter':
                e.preventDefault();
                e.stopPropagation();
                // Only select suggestion if one is explicitly selected (selectedIndex >= 0)
                // Otherwise, search whatever is in the text box
                if (showSuggestions && displayedSuggestions.length > 0 && selectedIndex >= 0 && selectedIndex < displayedSuggestions.length) {
                    // Select suggestion if one is highlighted
                    handleSuggestionSelect(displayedSuggestions[selectedIndex].query);
                }
                else {
                    // Search whatever is in the text box (even if suggestions are shown)
                    // Allow empty search - will use "*" for wildcard
                    const currentValue = inputRef.current?.value || query;
                    handleSearch(currentValue);
                }
                break;
            case 'Escape':
                setIsFocused(false);
                inputRef.current?.blur();
                break;
        }
    }, [displayedSuggestions, selectedIndex, query, showSuggestions, handleSearch, handleSuggestionSelect]);
    const handleFocus = useCallback(() => {
        setIsFocused(true);
    }, []);
    const handleBlur = useCallback((e) => {
        // Don't interfere if we're explicitly triggering a search
        if (isSearchingRef.current) {
            return;
        }
        // Delay to allow click events on suggestions to fire
        setTimeout(() => {
            if (!containerRef.current?.contains(document.activeElement)) {
                setIsFocused(false);
                setSelectedIndex(-1);
            }
        }, 200);
    }, []);
    const defaultRenderSuggestion = (suggestion, index) => (React.createElement("div", { key: index }, suggestion));
    const searchBarTheme = customTheme || {};
    const isLoading = suggestionsLoading || searchLoading;
    // Show list when we have suggestions (including previous while loading) or when loading and showLoadingState
    const hasSuggestions = displayedSuggestions.length > 0;
    const showSuggestionsList = isFocused && showSuggestions && query.length >= minQueryLength && hasSuggestions;
    // Get processing time from results
    const res = results;
    const processingTime = res?.processingTimeMS
        || res?.data?.processingTimeMS
        || res?.data?.data?.processingTimeMS;
    // Size-based configuration
    const sizeConfig = SIZE_CONFIG[size];
    // Determine whether the search icon is shown (always unless renderSearchIcon returns null explicitly — but
    // we always show it; there is no prop to hide the search icon, only to customise it)
    const hasSearchIcon = true;
    const hasClearBtn = showClearButton && query.length > 0;
    // Compute input padding accounting for icons
    const inputPaddingLeft = hasSearchIcon ? sizeConfig.iconPaddingLeft : sizeConfig.padding.split(' ')[1] || sizeConfig.padding;
    const inputPaddingRight = hasClearBtn ? sizeConfig.iconPaddingRight : sizeConfig.padding.split(' ')[1] || sizeConfig.padding;
    const borderRadius = typeof theme.borderRadius === 'string' ? theme.borderRadius : theme.borderRadius.medium;
    const focusBorderColor = isFocused ? `var(--seekora-border-focus, ${theme.colors.focus})` : `var(--seekora-border, ${theme.colors.border})`;
    const focusRingShadow = isFocused
        ? `0 0 0 3px var(--seekora-border-focus-alpha, ${theme.colors.focus}33)`
        : undefined;
    const handleClear = useCallback(() => {
        if (searchAsYouTypeRef.current) {
            clearTimeout(searchAsYouTypeRef.current);
            searchAsYouTypeRef.current = null;
        }
        setQuery('', false);
        setSelectedIndex(-1);
        inputRef.current?.focus();
        if (searchAsYouType) {
            triggerSearch();
        }
    }, [setQuery, searchAsYouType, triggerSearch]);
    const handleSubmit = useCallback(() => {
        const currentValue = inputRef.current?.value || query;
        handleSearch(currentValue);
    }, [query, handleSearch]);
    return (React.createElement("div", { ref: containerRef, className: clsx(searchBarTheme.container, className), style: {
            position: 'relative',
            display: 'flex',
            alignItems: 'center',
            // CSS custom properties for external styling
            '--seekora-searchbar-bg': theme.colors.background,
            '--seekora-searchbar-border': theme.colors.border,
            '--seekora-searchbar-focus-border': theme.colors.focus,
            '--seekora-searchbar-radius': borderRadius,
            '--seekora-searchbar-icon-color': theme.colors.textSecondary,
            ...style,
        } },
        React.createElement("div", { style: { position: 'relative', flex: 1, display: 'flex', alignItems: 'center' } },
            hasSearchIcon && (React.createElement("span", { className: searchBarTheme.searchIcon, "aria-hidden": "true", style: {
                    position: 'absolute',
                    left: sizeConfig.iconLeft,
                    top: '50%',
                    transform: 'translateY(-50%)',
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'center',
                    pointerEvents: 'none',
                    color: 'var(--seekora-searchbar-icon-color)',
                    zIndex: 2,
                } }, renderSearchIcon ? renderSearchIcon() : React.createElement(DefaultSearchIcon, { size: sizeConfig.iconSize }))),
            React.createElement("input", { ref: inputRef, type: "text", value: query, onChange: handleInputChange, onKeyDown: handleKeyDown, onFocus: handleFocus, onBlur: handleBlur, placeholder: placeholder, className: clsx(searchBarTheme.input, isFocused && searchBarTheme.inputFocused), style: {
                    width: '100%',
                    paddingTop: sizeConfig.padding.split(' ')[0],
                    paddingBottom: sizeConfig.padding.split(' ')[0],
                    paddingLeft: inputPaddingLeft,
                    paddingRight: inputPaddingRight,
                    fontSize: sizeConfig.fontSize,
                    fontFamily: theme.typography.fontFamily,
                    backgroundColor: 'var(--seekora-searchbar-bg)',
                    color: theme.colors.text,
                    borderWidth: '1px',
                    borderStyle: 'solid',
                    borderColor: focusBorderColor,
                    borderRadius: 'var(--seekora-searchbar-radius)',
                    outline: 'none',
                    boxShadow: focusRingShadow,
                    transition: theme.transitions?.fast || '150ms ease-in-out',
                    boxSizing: 'border-box',
                } }),
            hasClearBtn && (React.createElement("button", { type: "button", onClick: handleClear, className: searchBarTheme.clearButton, "aria-label": "Clear search", style: {
                    position: 'absolute',
                    right: sizeConfig.iconRight,
                    top: '50%',
                    transform: 'translateY(-50%)',
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'center',
                    background: 'none',
                    border: 'none',
                    cursor: 'pointer',
                    padding: '2px',
                    borderRadius: '50%',
                    color: 'var(--seekora-searchbar-icon-color)',
                    transition: theme.transitions?.fast || '150ms ease-in-out',
                    zIndex: 2,
                }, onMouseDown: (e) => {
                    // Prevent input blur so the clear action doesn't race with blur handler
                    e.preventDefault();
                } }, renderClearIcon ? renderClearIcon() : React.createElement(DefaultClearIcon, { size: sizeConfig.iconSize - 4 })))),
        showSubmitButton && (renderSubmitButton ? (React.createElement("div", { onClick: handleSubmit, style: { marginLeft: theme.spacing.small, cursor: 'pointer' } }, renderSubmitButton())) : (React.createElement("button", { type: "button", onClick: handleSubmit, className: searchBarTheme.submitButton, style: {
                marginLeft: theme.spacing.small,
                padding: sizeConfig.padding,
                fontSize: sizeConfig.fontSize,
                fontFamily: theme.typography.fontFamily,
                fontWeight: theme.typography.fontWeight?.medium ?? 500,
                backgroundColor: `var(--seekora-primary, ${theme.colors.primary})`,
                color: 'var(--seekora-primary-text, #ffffff)',
                border: 'none',
                borderRadius: 'var(--seekora-searchbar-radius)',
                cursor: 'pointer',
                whiteSpace: 'nowrap',
                transition: theme.transitions?.fast || '150ms ease-in-out',
            } }, "Search"))),
        processingTime !== undefined && (React.createElement("span", { style: {
                marginLeft: theme.spacing.small,
                fontSize: theme.typography.fontSize.small,
                color: theme.colors.text,
                opacity: 0.7,
                whiteSpace: 'nowrap',
            } },
            processingTime,
            "ms")),
        showSuggestionsList && (React.createElement("div", { className: searchBarTheme.suggestionsContainer, style: {
                position: 'absolute',
                top: '100%',
                left: 0,
                right: 0,
                marginTop: theme.spacing.small,
                backgroundColor: theme.colors.background,
                border: `1px solid ${theme.colors.border}`,
                borderRadius: typeof theme.borderRadius === 'string' ? theme.borderRadius : theme.borderRadius.medium,
                boxShadow: theme.shadows.medium,
                maxHeight: '400px',
                overflowY: 'auto',
                zIndex: Z_INDEX.dropdown,
                boxSizing: 'border-box',
            } },
            displayedSuggestions.length > 0 && (React.createElement(React.Fragment, null, displayedSuggestions.map((suggestion, index) => {
                const isSelected = index === selectedIndex;
                const renderFn = renderSuggestion || defaultRenderSuggestion;
                return (React.createElement("div", { key: index, className: clsx(searchBarTheme.suggestionItem, isSelected && searchBarTheme.suggestionItemActive), onClick: () => handleSuggestionSelect(suggestion.query), onMouseEnter: () => setSelectedIndex(index), style: {
                        padding: theme.spacing.medium,
                        cursor: 'pointer',
                        backgroundColor: isSelected
                            ? theme.colors.hover
                            : 'transparent',
                        color: theme.colors.text,
                        transition: theme.transitions?.fast || '150ms ease-in-out',
                    } }, renderFn(suggestion.query, index)));
            }))),
            !isLoading && displayedSuggestions.length === 0 && query.length >= minQueryLength && (React.createElement("div", { style: { padding: theme.spacing.medium, textAlign: 'center', color: theme.colors.textSecondary } }, "No suggestions found"))))));
};
