import { useRef, useState } from 'react';
import { Search } from 'lucide-react';

import { Input } from '@/components/ui/input';
import { useOnClickOutside } from '@/hooks/useOnClickOutside';
import type { TopBarSearchResult } from '@/business/top-bar/search';

interface TopBarSearchProps {
  readonly value: string;
  readonly results: readonly TopBarSearchResult[];
  readonly onChange: (value: string) => void;
  readonly onSelect: (result: TopBarSearchResult) => void;
}

export function TopBarSearch({ value, results, onChange, onSelect }: TopBarSearchProps) {
  const containerRef = useRef<HTMLDivElement>(null);
  const [isOpen, setIsOpen] = useState(false);
  const [highlightIndex, setHighlightIndex] = useState(0);

  useOnClickOutside(containerRef, () => setIsOpen(false), isOpen);

  const showDropdown = isOpen && value.trim().length > 0;

  const handleChange = (next: string) => {
    onChange(next);
    setIsOpen(true);
    setHighlightIndex(0);
  };

  const select = (result: TopBarSearchResult) => {
    onSelect(result);
    setIsOpen(false);
  };

  const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
    if (!showDropdown) {
      return;
    }
    if (event.key === 'ArrowDown') {
      event.preventDefault();
      setHighlightIndex((index) => Math.min(index + 1, results.length - 1));
    } else if (event.key === 'ArrowUp') {
      event.preventDefault();
      setHighlightIndex((index) => Math.max(index - 1, 0));
    } else if (event.key === 'Enter') {
      const result = results[highlightIndex];
      if (result) {
        event.preventDefault();
        select(result);
      }
    } else if (event.key === 'Escape') {
      setIsOpen(false);
    }
  };

  return (
    <div ref={containerRef} className="hidden md:flex relative">
      <Search size={16} className="absolute left-3 top-1/2 -translate-y-1/2 text-slate-500" />
      <Input
        type="text"
        role="combobox"
        aria-expanded={showDropdown}
        aria-controls="top-bar-search-results"
        value={value}
        onChange={(event) => handleChange(event.target.value)}
        onFocus={() => setIsOpen(true)}
        onKeyDown={handleKeyDown}
        placeholder="Search modules, strategies, signs..."
        className="pl-9 pr-4 py-2 w-72 bg-slate-800/80 border-slate-700/50 rounded-xl text-sm text-white placeholder-slate-500 focus-visible:ring-violet-500/50 focus-visible:border-violet-500/50"
      />
      {showDropdown && (
        <div
          id="top-bar-search-results"
          role="listbox"
          className="absolute left-0 top-full mt-2 w-72 bg-slate-800 rounded-xl shadow-2xl shadow-black/40 border border-slate-700/50 z-40 overflow-hidden max-h-80 overflow-y-auto"
        >
          {results.length === 0 ? (
            <div className="px-4 py-3 text-sm text-slate-400">No matches found.</div>
          ) : (
            results.map((result, index) => (
              <button
                key={result.id}
                type="button"
                role="option"
                aria-selected={index === highlightIndex}
                onMouseEnter={() => setHighlightIndex(index)}
                onClick={() => select(result)}
                className={`w-full text-left px-4 py-2.5 border-b border-slate-700/30 last:border-b-0 transition-colors ${
                  index === highlightIndex ? 'bg-slate-700/40' : 'hover:bg-slate-700/30'
                }`}
              >
                <span className="block text-sm text-slate-200">{result.label}</span>
                <span className="block text-[10px] text-slate-500 mt-0.5">{result.sublabel}</span>
              </button>
            ))
          )}
        </div>
      )}
    </div>
  );
}
