"use client" import { useCallback, useEffect, useMemo, useRef, useState, type KeyboardEvent, } from "react" import { useRouter } from "next/navigation" import { ArrowLeft, Search, X, Paperclip, Clock, User, SlidersHorizontal, } from "lucide-react" import { Button } from "@/components/ui/button" import { Sheet, SheetContent, SheetTitle } from "@/components/ui/sheet" import { cn } from "@/lib/utils" import { useSearchContacts } from "@/lib/api/hooks/use-contact-queries" import { useActiveAccount } from "@/lib/stores/account-store" import { bestCompletion, type SearchSuggestion, type ContactSuggestion, } from "@/lib/mail-search/search-engine" import { buildQuickSearchParams, submitMailSearch, } from "@/lib/mail-search/navigate" import { useMailSearchStore } from "@/lib/stores/mail-search-store" import { avatarColor, senderInitial } from "@/lib/sender-display" import { MAIL_MOBILE_SEARCH_SHEET_CLASS, MAIL_SEARCH_CHIP_INACTIVE_CLASS, MAIL_SEARCH_SECTION_DIVIDER_CLASS, MAIL_SEARCH_SUGGESTIONS_SURFACE_CLASS, } from "@/lib/mail-chrome-classes" import { MobileAdvancedSearch } from "@/components/gmail/mail-search/mobile-advanced-search" interface MobileSearchOverlayProps { open: boolean onClose: () => void initialQuery?: string } export function MobileSearchOverlay({ open, onClose, initialQuery = "" }: MobileSearchOverlayProps) { const router = useRouter() const account = useActiveAccount() const inputValue = useMailSearchStore((s) => s.inputValue) const selectedIndex = useMailSearchStore((s) => s.selectedIndex) const chipAttachment = useMailSearchStore((s) => s.chipAttachment) const chipLast7Days = useMailSearchStore((s) => s.chipLast7Days) const chipFromMe = useMailSearchStore((s) => s.chipFromMe) const { data: searchContactResults } = useSearchContacts(inputValue) const { setInputValue, setSelectedIndex, toggleChipAttachment, toggleChipLast7Days, toggleChipFromMe, resetChips, reset, } = useMailSearchStore.getState() const [advancedMode, setAdvancedMode] = useState(false) const inputRef = useRef(null) useEffect(() => { if (open) { setInputValue(initialQuery) setAdvancedMode(false) setTimeout(() => inputRef.current?.focus(), 50) } else { reset() setAdvancedMode(false) } }, [open, initialQuery, setInputValue, reset]) const suggestions = useMemo(() => { if (!inputValue.trim() || !searchContactResults?.length) return [] return searchContactResults.slice(0, 6).map((c) => ({ kind: "contact", contact: { id: c.uid, firstName: c.full_name.split(" ")[0] ?? "", lastName: c.full_name.split(" ").slice(1).join(" "), emails: c.email ? [{ value: c.email, label: "primary" }] : [], phones: [], createdAt: 0, updatedAt: 0, }, email: c.email ?? "", displayName: c.full_name, score: 1, })) }, [inputValue, searchContactResults]) const ghostText = useMemo( () => bestCompletion(inputValue, suggestions), [inputValue, suggestions] ) const totalItems = suggestions.length + 1 const submitSearch = useCallback( (overrideQuery?: string) => { const q = overrideQuery ?? inputValue const params = buildQuickSearchParams(q, { chipAttachment, chipLast7Days, chipFromMe, fromEmail: account?.email ?? "", }) if (!Object.keys(params).length) return submitMailSearch(router, params, { onAfter: onClose }) }, [inputValue, chipAttachment, chipLast7Days, chipFromMe, account?.email, router, onClose] ) const selectSuggestion = useCallback( (s: SearchSuggestion) => { const params = buildQuickSearchParams(s.email, { chipAttachment, chipLast7Days, chipFromMe, fromEmail: account?.email ?? "", }) submitMailSearch(router, params, { onAfter: onClose }) }, [chipAttachment, chipLast7Days, chipFromMe, account?.email, router, onClose] ) const handleKeyDown = useCallback( (e: KeyboardEvent) => { switch (e.key) { case "ArrowDown": e.preventDefault() setSelectedIndex(selectedIndex < totalItems - 1 ? selectedIndex + 1 : 0) break case "ArrowUp": e.preventDefault() setSelectedIndex(selectedIndex > 0 ? selectedIndex - 1 : totalItems - 1) break case "Enter": e.preventDefault() if (selectedIndex >= 0 && selectedIndex < suggestions.length) { selectSuggestion(suggestions[selectedIndex]!) } else { submitSearch() } break case "Tab": if (ghostText) { e.preventDefault() setInputValue(inputValue + ghostText) } break case "Escape": e.preventDefault() onClose() break } }, [selectedIndex, totalItems, suggestions, ghostText, inputValue, submitSearch, selectSuggestion, onClose] ) return ( { if (!isOpen) onClose() }}> Rechercher dans les messages {/* Header */}
{ghostText && !advancedMode && (
{inputValue} {ghostText}
)} { setInputValue(e.target.value) setSelectedIndex(-1) if (advancedMode) setAdvancedMode(false) }} onKeyDown={handleKeyDown} placeholder="Rechercher dans les messages" className="h-10 w-full bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground" autoComplete="off" />
{inputValue && !advancedMode && ( )}
{advancedMode ? ( { router.push(url); onClose() }} /> ) : (
{/* Filter chips */}
{/* Suggestions */}
{inputValue.trim() && ( <> {suggestions.map((s, i) => { const isSelected = i === selectedIndex if (s.kind === "contact") { const initial = senderInitial(s.displayName) const color = avatarColor(s.displayName) return ( ) } return ( ) })} {/* All results row */} )}
)}
) }