import React, { useState, useRef, useEffect, useMemo } from 'react' import { Search, X, MapPin } from 'lucide-react' import Fuse from 'fuse.js' const ENTITY_ICONS = { startup: '🚀', sme: '🏢', college_ecell: '🎓', incubator: '🧪', accelerator: '⚡' } export default function SearchBar({ value, onChange, onEntitySelect }) { const [focused, setFocused] = useState(false) const [suggestions, setSuggestions] = useState([]) const [localCache, setLocalCache] = useState([]) const inputRef = useRef(null) const debounceRef = useRef(null) // Build fuse index from cached results for instant sub-filtering const fuse = useMemo(() => { if (localCache.length === 0) return null return new Fuse(localCache, { keys: [ { name: 'name', weight: 0.6 }, { name: 'city', weight: 0.2 }, { name: 'description', weight: 0.1 }, { name: 'state', weight: 0.1 }, ], threshold: 0.4, includeScore: true, }) }, [localCache]) useEffect(() => { if (!value || value.length < 2) { setSuggestions([]); return } // Instant client-side fuzzy if we have cached results if (fuse && value.length >= 3) { const results = fuse.search(value).slice(0, 8).map(r => r.item) if (results.length > 0) { setSuggestions(results) } } // Also fetch from server (debounced) for fresh results clearTimeout(debounceRef.current) debounceRef.current = setTimeout(async () => { try { const resp = await fetch(`/api/entities/search?q=${encodeURIComponent(value)}&limit=10`) const data = await resp.json() const results = data.results || [] setSuggestions(results) // Merge into local cache for future fuzzy queries setLocalCache(prev => { const ids = new Set(prev.map(p => p.id)) const newItems = results.filter(r => !ids.has(r.id)) return [...prev, ...newItems].slice(-200) // keep last 200 }) } catch (err) { console.error(err) } }, 250) return () => clearTimeout(debounceRef.current) }, [value, fuse]) const handleSelect = (entity) => { onChange(entity.name) setSuggestions([]) onEntitySelect?.(entity) inputRef.current?.blur() } return (