/**
 * Shared search autocomplete component.
 *
 * - On focus with empty input: shows popular suggestions from /api/v1/search/suggestions
 * - On 2+ chars: shows debounced typeahead search results (top 5)
 * - Escape / outside-click closes dropdown
 * - Enter submits via onSearch callback
 */

import { useCallback, useEffect, useRef, useState } from "react";
import { Link } from "react-router-dom";
import {
  searchApi,
  fetchSuggestions,
  type SearchResultItem,
  type SuggestionItem,
} from "../api/public-client";

interface SearchAutocompleteProps {
  onSearch: (query: string) => void;
  placeholder?: string;
  /** @deprecated Use variant="hero" instead */
  heroSize?: boolean;
  variant?: 'hero' | 'inline' | 'nav';
  initialQuery?: string;
  autoFocus?: boolean;
  /** When true, Ctrl+Shift+F focuses the input globally */
  globalShortcut?: boolean;
}

export default function SearchAutocomplete({
  onSearch,
  placeholder = "Search techniques…",
  heroSize = false,
  variant: variantProp,
  initialQuery = "",
  autoFocus = false,
  globalShortcut = false,
}: SearchAutocompleteProps) {
  // Resolve variant: explicit prop wins, then legacy heroSize, then default 'inline'
  const variant = variantProp ?? (heroSize ? 'hero' : 'inline');
  const [query, setQuery] = useState(initialQuery);
  const [searchResults, setSearchResults] = useState<SearchResultItem[]>([]);
  const [popularSuggestions, setPopularSuggestions] = useState<SuggestionItem[]>([]);
  const [showDropdown, setShowDropdown] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);
  const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const dropdownRef = useRef<HTMLDivElement>(null);
  const suggestionsLoadedRef = useRef(false);

  // Sync initialQuery when URL changes (e.g. SearchResults page)
  useEffect(() => {
    setQuery(initialQuery);
  }, [initialQuery]);

  // Fetch popular suggestions once on mount
  useEffect(() => {
    if (suggestionsLoadedRef.current) return;
    suggestionsLoadedRef.current = true;
    void (async () => {
      try {
        const res = await fetchSuggestions();
        setPopularSuggestions(res.suggestions);
      } catch {
        // Non-critical — autocomplete still works without popular suggestions
      }
    })();
  }, []);

  // Auto-focus
  useEffect(() => {
    if (autoFocus) inputRef.current?.focus();
  }, [autoFocus]);

  // Global Ctrl+Shift+F shortcut to focus input
  useEffect(() => {
    if (!globalShortcut) return;
    function handleGlobalKey(e: KeyboardEvent) {
      if (e.key === "F" && e.ctrlKey && e.shiftKey) {
        e.preventDefault();
        inputRef.current?.focus();
      }
    }
    document.addEventListener("keydown", handleGlobalKey);
    return () => document.removeEventListener("keydown", handleGlobalKey);
  }, [globalShortcut]);

  // Close dropdown on outside click
  useEffect(() => {
    function handleClick(e: MouseEvent) {
      if (dropdownRef.current && !dropdownRef.current.contains(e.target as Node)) {
        setShowDropdown(false);
      }
    }
    document.addEventListener("mousedown", handleClick);
    return () => document.removeEventListener("mousedown", handleClick);
  }, []);

  // Debounced typeahead search
  const handleInputChange = useCallback((value: string) => {
    setQuery(value);
    if (debounceRef.current) clearTimeout(debounceRef.current);

    if (value.length < 2) {
      setSearchResults([]);
      // Show popular suggestions if input is empty and we have them
      if (value.length === 0 && popularSuggestions.length > 0) {
        setShowDropdown(true);
      } else {
        setShowDropdown(false);
      }
      return;
    }

    debounceRef.current = setTimeout(() => {
      void (async () => {
        try {
          const res = await searchApi(value, undefined, 5);
          setSearchResults(res.items);
          setShowDropdown(res.items.length > 0);
        } catch {
          setSearchResults([]);
          setShowDropdown(false);
        }
      })();
    }, 300);
  }, [popularSuggestions.length]);

  function handleFocus() {
    if (query.length === 0 && popularSuggestions.length > 0) {
      setShowDropdown(true);
    } else if (query.length >= 2 && searchResults.length > 0) {
      setShowDropdown(true);
    }
  }

  function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    if (query.trim()) {
      setShowDropdown(false);
      onSearch(query.trim());
    }
  }

  function handleKeyDown(e: React.KeyboardEvent) {
    if (e.key === "Escape") {
      setShowDropdown(false);
    }
  }

  function handleSuggestionClick(text: string) {
    setShowDropdown(false);
    setQuery(text);
    onSearch(text);
  }

  const showPopular = query.length < 2 && popularSuggestions.length > 0;
  const showSearch = query.length >= 2 && searchResults.length > 0;

  const typeLabel: Record<string, string> = {
    technique: "Technique",
    topic: "Topic",
    creator: "Creator",
    technique_page: "Technique",
    key_moment: "Key Moment",
  };

  return (
    <div className={`search-container${variant === 'nav' ? ' search-container--nav' : ''}`} ref={dropdownRef}>
      <form
        onSubmit={handleSubmit}
        className={`search-form search-form--${variant}`}
      >
        <input
          ref={inputRef}
          type="search"
          className={`search-input search-input--${variant}`}
          placeholder={placeholder}
          value={query}
          onChange={(e) => handleInputChange(e.target.value)}
          onFocus={handleFocus}
          onKeyDown={handleKeyDown}
          aria-label="Search techniques"
        />
        {variant !== 'nav' && (
          <button type="submit" className="btn btn--search">
            Search
          </button>
        )}
        {variant === 'nav' && (
          <kbd className="search-nav__shortcut">Ctrl⇧F</kbd>
        )}
      </form>

      {showDropdown && (showPopular || showSearch) && (
        <div className="typeahead-dropdown">
          {showPopular && (
            <>
              <div className="typeahead-suggestions-header">Popular</div>
              {popularSuggestions.map((item) => (
                <button
                  key={`${item.type}-${item.text}`}
                  className="typeahead-suggestion"
                  onClick={() => handleSuggestionClick(item.text)}
                  type="button"
                >
                  <span className="typeahead-suggestion__text">{item.text}</span>
                  <span className={`typeahead-item__type typeahead-item__type--${item.type}`}>
                    {typeLabel[item.type] ?? item.type}
                  </span>
                </button>
              ))}
            </>
          )}

          {showSearch && (
            <>
              {searchResults.map((item) => (
                <Link
                  key={`${item.type}-${item.slug}`}
                  to={`/techniques/${item.slug}`}
                  className="typeahead-item"
                  onClick={() => setShowDropdown(false)}
                >
                  <span className="typeahead-item__title">{item.title}</span>
                  <span className="typeahead-item__meta">
                    <span className={`typeahead-item__type typeahead-item__type--${item.type}`}>
                      {typeLabel[item.type] ?? item.type}
                    </span>
                    {item.creator_name && (
                      <span className="typeahead-item__creator">
                        {item.creator_name}
                      </span>
                    )}
                  </span>
                </Link>
              ))}
              <Link
                to={`/search?q=${encodeURIComponent(query)}`}
                className="typeahead-see-all"
                onClick={() => setShowDropdown(false)}
              >
                See all results for &ldquo;{query}&rdquo;
              </Link>
            </>
          )}
        </div>
      )}
    </div>
  );
}
