"use client" import { useState, useEffect, useRef } from "react" import Image from "next/image" import { SearchIcon, XIcon, Gamepad2Icon } from "lucide-react" interface SearchResult { id: string appId: number | null title: string image: string | null source: string } interface GameSelectorProps { selectedGames: SearchResult[] onSelect: (game: SearchResult) => void onRemove: (gameId: string) => void maxSelections?: number } export function GameSelector({ selectedGames, onSelect, onRemove, maxSelections = 4 }: GameSelectorProps) { const [query, setQuery] = useState("") const [results, setResults] = useState([]) const [loading, setLoading] = useState(false) const [open, setOpen] = useState(false) const wrapperRef = useRef(null) useEffect(() => { if (query.length < 2) { setResults([]) return } let cancelled = false const timeout = setTimeout(async () => { setLoading(true) try { const res = await fetch(`/api/search/unified?q=${encodeURIComponent(query)}`) if (!res.ok) throw new Error("Search failed") const data = await res.json() if (!cancelled) { setResults( (data.results || []) .filter((r: any) => !selectedGames.some(sg => sg.id === (r.id || `steam-${r.appId}`))) .slice(0, 8) .map((r: any) => ({ id: r.id || `steam-${r.appId}`, appId: r.appId, title: r.title, image: r.image, source: r.source, })) ) } } catch { if (!cancelled) setResults([]) } finally { if (!cancelled) setLoading(false) } }, 300) return () => { cancelled = true clearTimeout(timeout) } }, [query, selectedGames]) // Close dropdown on outside click useEffect(() => { function handleClick(e: MouseEvent) { if (wrapperRef.current && !wrapperRef.current.contains(e.target as Node)) { setOpen(false) } } document.addEventListener("mousedown", handleClick) return () => document.removeEventListener("mousedown", handleClick) }, []) const canAdd = selectedGames.length < maxSelections return (
{/* Selected games chips */} {selectedGames.length > 0 && (
{selectedGames.map(game => (
{game.image ? ( {game.title} ) : ( )} {game.title}
))}
)} {/* Search input */} {canAdd && (
{ setQuery(e.target.value); setOpen(true) }} onFocus={() => setOpen(true)} placeholder="Search for games to compare..." className="flex-1 bg-transparent text-sm text-text outline-none placeholder:text-text/40" />
{/* Dropdown results */} {open && (query.length >= 2) && (
{loading && (
Searching...
)} {!loading && results.length === 0 && (
No results found
)} {!loading && results.map(game => ( ))}
)}
)} {!canAdd && (

Maximum {maxSelections} games can be compared

)}
) }