'use client'; import { useState, useRef, useEffect, KeyboardEvent } from 'react'; import { useTranslations } from 'next-intl'; import { Search, Loader2, X, Sparkles, ChevronRight, MessageSquareWarning } from 'lucide-react'; import { Button, cn } from '@/components/ui'; import Link from 'next/link'; import { useAnalytics } from '../analytics/useAnalytics'; import { AnalyticsEvents } from '../analytics/analytics-events'; import Image from 'next/image'; interface ProductMatch { id: string; title: string; sku: string; slug: string; } interface AIResponse { answerText: string; products: ProductMatch[]; } interface ComponentProps { isOpen: boolean; onClose: () => void; initialQuery?: string; triggerSearch?: boolean; // If true, immediately searches on mount with initialQuery } export function AISearchResults({ isOpen, onClose, initialQuery = '', triggerSearch = false }: ComponentProps) { const t = useTranslations('Search'); const { trackEvent } = useAnalytics(); const [query, setQuery] = useState(initialQuery); const [honeypot, setHoneypot] = useState(''); const [isLoading, setIsLoading] = useState(false); const [response, setResponse] = useState(null); const [error, setError] = useState(null); const inputRef = useRef(null); const modalRef = useRef(null); useEffect(() => { if (isOpen) { document.body.style.overflow = 'hidden'; // Slight delay to allow animation to start before focus setTimeout(() => inputRef.current?.focus(), 100); if (triggerSearch && initialQuery && !response) { handleSearch(initialQuery); } } else { document.body.style.overflow = 'unset'; } return () => { document.body.style.overflow = 'unset'; }; }, [isOpen, triggerSearch]); useEffect(() => { setQuery(initialQuery); }, [initialQuery]); const handleSearch = async (searchQuery: string = query) => { if (!searchQuery.trim()) return; setIsLoading(true); setError(null); setResponse(null); trackEvent(AnalyticsEvents.FORM_SUBMIT, { type: 'ai_search', query: searchQuery }); try { const res = await fetch('/api/ai-search', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: searchQuery, _honeypot: honeypot }) }); const data = await res.json(); if (!res.ok) { throw new Error(data.error || 'Failed to fetch search results'); } setResponse(data); } catch (err: any) { console.error(err); setError(err.message || 'An error occurred while searching. Please try again.'); } finally { setIsLoading(false); } }; const onKeyDown = (e: KeyboardEvent) => { if (e.key === 'Enter') { e.preventDefault(); handleSearch(); } if (e.key === 'Escape') { onClose(); } }; if (!isOpen) return null; return (