import { useCallback, useEffect, useRef, useState } from "react";
import { createPortal } from "react-dom";
import { DITHERED_SHADOW } from "@/components/shared/FloatingWindow";
import type { NetworkNode } from "@/api/client";

interface BrowseSearchBarProps {
  filter: string;
  onFilterChange: (value: string) => void;
  onClear: () => void;
  suggestions: NetworkNode[];
  onSelectNode: (node: NetworkNode) => void;
  focusedWinId: string | null;
  windowCount: number;
}

export default function BrowseSearchBar({
  filter, onFilterChange, onClear,
  suggestions, onSelectNode,
  focusedWinId, windowCount,
}: BrowseSearchBarProps) {
  const searchInputRef = useRef<HTMLInputElement>(null);
  const [selectedSuggestion, setSelectedSuggestion] = useState(-1);

  // Reset selection when suggestions change
  useEffect(() => { setSelectedSuggestion(-1); }, [suggestions]);

  // Auto-focus search when no windows open
  useEffect(() => { searchInputRef.current?.focus(); }, []);
  useEffect(() => {
    if (windowCount === 0) searchInputRef.current?.focus();
  }, [windowCount]);

  // Capture typing into search when no window is focused
  useEffect(() => {
    const onKeyDown = (e: KeyboardEvent) => {
      if (focusedWinId) return;
      if (document.activeElement === searchInputRef.current) return;
      if (e.metaKey || e.ctrlKey || e.altKey) return;
      if (e.key.length !== 1) return;
      searchInputRef.current?.focus();
    };
    document.addEventListener("keydown", onKeyDown);
    return () => document.removeEventListener("keydown", onKeyDown);
  }, [focusedWinId]);

  // Draggable position
  const [searchPos, setSearchPos] = useState<{ x: number; y: number } | null>(null);
  const searchDragRef = useRef<{ startX: number; startY: number; origX: number; origY: number } | null>(null);
  useEffect(() => { setSearchPos({ x: Math.round(window.innerWidth / 2 - 200), y: window.innerHeight - 307 }); }, []);

  const onSearchDragStart = useCallback((e: React.MouseEvent) => {
    if ((e.target as HTMLElement).tagName === "INPUT") return;
    e.preventDefault();
    const pos = searchPos ?? { x: 0, y: 0 };
    searchDragRef.current = { startX: e.clientX, startY: e.clientY, origX: pos.x, origY: pos.y };
    const onMove = (ev: MouseEvent) => { if (!searchDragRef.current) return; setSearchPos({ x: searchDragRef.current.origX + (ev.clientX - searchDragRef.current.startX), y: Math.max(0, searchDragRef.current.origY + (ev.clientY - searchDragRef.current.startY)) }); };
    const onUp = () => { searchDragRef.current = null; document.removeEventListener("mousemove", onMove); document.removeEventListener("mouseup", onUp); };
    document.addEventListener("mousemove", onMove); document.addEventListener("mouseup", onUp);
  }, [searchPos]);

  if (!searchPos) return null;

  return createPortal(
    <div onMouseDown={onSearchDragStart}
      className="fixed z-999 flex items-center gap-3 px-3 py-1.5 bg-popover border-2 border-border focus-within:border-primary rounded-lg cursor-grab active:cursor-grabbing transition-[border-color] duration-150"
      style={{ left: searchPos.x, top: searchPos.y, width: 400, boxShadow: DITHERED_SHADOW }}>
      <input ref={searchInputRef} type="text" value={filter}
        onChange={(e) => onFilterChange(e.target.value)}
        onKeyDown={(e) => {
          if (e.key === "Escape") { onClear(); e.currentTarget.blur(); return; }
          if (e.key === "ArrowDown") { e.preventDefault(); setSelectedSuggestion(i => Math.min(i + 1, suggestions.length - 1)); return; }
          if (e.key === "ArrowUp") { e.preventDefault(); setSelectedSuggestion(i => Math.max(i - 1, -1)); return; }
          if (e.key === "Enter") {
            e.preventDefault();
            const entry = selectedSuggestion >= 0 ? suggestions[selectedSuggestion] : suggestions[0];
            if (entry && entry.type !== "interface") { onSelectNode(entry); onClear(); }
            return;
          }
        }}
        placeholder="Search nodes..."
        className="flex-1 h-7 px-2 text-xs bg-background/60 border border-border rounded placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-primary cursor-text" />
      {filter && (
        <button onClick={onClear} className="text-muted-foreground hover:text-foreground transition-colors text-xs leading-none px-1" title="Clear search (Esc)">
          &times;
        </button>
      )}
      {suggestions.length > 0 && (
        <div className="absolute left-0 right-0 top-full mt-1 bg-popover border border-border rounded-lg overflow-hidden"
          style={{ boxShadow: "0 4px 12px rgba(0,0,0,0.4)" }}>
          {suggestions.map((entry, i) => (
            <button
              key={entry.hash}
              onMouseDown={(e) => { e.preventDefault(); if (entry.type !== "interface") { onSelectNode(entry); onClear(); } }}
              onMouseEnter={() => setSelectedSuggestion(i)}
              className={`w-full text-left px-3 py-1.5 text-xs font-mono flex items-center gap-2 transition-colors ${i === selectedSuggestion ? "bg-accent text-accent-foreground" : "text-foreground hover:bg-accent/50"
                }`}
            >
              <span className="w-2 h-2 rounded-full shrink-0" style={{
                backgroundColor: (() => {
                  const age = Date.now() / 1000 - (entry.last_seen ?? 0);
                  if (age < 300) return "var(--primary)";
                  if (age < 3600) return "var(--muted-foreground)";
                  return "var(--border)";
                })(),
              }} />
              <span className="truncate">{entry.name}</span>
              <span className="ml-auto text-[9px] text-muted-foreground uppercase shrink-0">
                {entry.interface ?? "peer"}
              </span>
            </button>
          ))}
        </div>
      )}
    </div>, document.body);
}
