'use client';

/* ── SearchInput ──
 *
 * Controlled search input with search icon, debounced search,
 * loading spinner, clear button, and keyboard navigation handler.
 */

import { useState, useRef, useEffect, forwardRef, useImperativeHandle } from "react";
import { Search, X, Loader2 } from "lucide-react";

/* ── Types ── */

export interface SearchInputHandle {
  clear: () => void;
  focus: () => void;
  blur: () => void;
}

interface SearchInputProps {
  /** Called (debounced) when the user types */
  onSearch: (query: string) => void;
  /** Keyboard navigation handler (from parent orchestrator) */
  onKeyDown: (e: React.KeyboardEvent) => void;
  /** Called when input receives focus */
  onFocus?: () => void;
  /** Whether a search is in progress */
  loading: boolean;
  /** Whether there are results to show on focus */
  hasResults: boolean;
  /** Placeholder text */
  placeholder?: string;
  /** Auto-focus on mount */
  autoFocus?: boolean;
}

/* ── Component ── */

const SearchInput = forwardRef<SearchInputHandle, SearchInputProps>(function SearchInput(
  { onSearch, onKeyDown, onFocus, loading, hasResults, placeholder = "Search files, CIDs, and content…", autoFocus = false },
  ref,
) {
  const [query, setQuery] = useState("");

  const inputRef = useRef<HTMLInputElement>(null);
  const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  /* Expose clear + focus to parent */
  useImperativeHandle(ref, () => ({
    clear() {
      setQuery("");
    },
    focus() {
      inputRef.current?.focus();
    },
    blur() {
      inputRef.current?.blur();
    },
  }));

  /* ── Debounced input ── */

  function handleChange(value: string) {
    setQuery(value);
    if (debounceRef.current) clearTimeout(debounceRef.current);
    debounceRef.current = setTimeout(() => onSearch(value), 250);
  }

  /* ── Cleanup ── */

  useEffect(() => {
    if (autoFocus) inputRef.current?.focus();
    return () => {
      if (debounceRef.current) clearTimeout(debounceRef.current);
    };
  }, [autoFocus]);

  /* ── Render ── */

  return (
    <div className="relative">
      <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-surface-500 pointer-events-none" />
      <input
        ref={inputRef}
        value={query}
        onChange={(e) => handleChange(e.target.value)}
        onKeyDown={onKeyDown}
        onFocus={() => {
          if (hasResults) onFocus?.();
        }}
        placeholder={placeholder}
        className="w-full pl-10 pr-10 py-2.5 rounded-xl bg-surface-900 border border-surface-700 text-sm text-surface-200 placeholder:text-surface-500 focus:outline-none focus-visible:ring-2 focus-visible:ring-brand-500/50 focus-visible:border-brand-500 transition-colors"
        autoFocus={autoFocus}
        role="combobox"
        aria-expanded={hasResults}
        aria-haspopup="listbox"
        aria-autocomplete="list"
        aria-controls="search-results-listbox"
      />
      {loading && (
        <Loader2 className="absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 text-surface-500 animate-spin" />
      )}
      {!loading && query && (
        <button
          onClick={() => {
            setQuery("");
            if (debounceRef.current) clearTimeout(debounceRef.current);
            inputRef.current?.focus();
          }}
          className="absolute right-3 top-1/2 -translate-y-1/2 p-0.5 rounded hover:bg-surface-700 transition-colors"
        >
          <X className="w-4 h-4 text-surface-500" />
        </button>
      )}
    </div>
  );
});

export default SearchInput;
