"use client"

import {
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
  type KeyboardEvent,
} from "react"
import { useRouter, useSearchParams, usePathname } from "next/navigation"
import {
  Search,
  SlidersHorizontal,
  X,
  Paperclip,
  Clock,
  User,
} from "lucide-react"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Checkbox } from "@/components/ui/checkbox"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
import { cn } from "@/lib/utils"
import { emails } from "@/lib/email-data"
import { useContactsStore } from "@/lib/contacts/contacts-store"
import { useActiveAccount } from "@/lib/stores/account-store"
import { useMailSearchStore } from "@/lib/stores/mail-search-store"
import {
  matchContacts,
  matchEmails,
  bestCompletion,
  type SearchSuggestion,
} from "@/lib/mail-search/search-engine"
import {
  buildSearchUrl,
  parseSearchParams,
  EMPTY_SEARCH_PARAMS,
  DATE_RANGE_OPTIONS,
  SEARCH_IN_OPTIONS,
  type SearchParams,
} from "@/lib/mail-search/search-params"
import {
  buildQuickSearchParams,
  submitMailSearch,
} from "@/lib/mail-search/navigate"
import {
  MAIL_SEARCH_ADVANCED_PANEL_CLASS,
  MAIL_SEARCH_CHECKBOX_CLASS,
  MAIL_SEARCH_FIELD_CLASS,
  MAIL_SEARCH_SECTION_DIVIDER_CLASS,
  MAIL_SEARCH_SUGGESTIONS_DROPDOWN_CLASS,
} from "@/lib/mail-chrome-classes"
import { avatarColor, senderInitial } from "@/lib/sender-display"

interface MailSearchBarProps {
  className?: string
  compact?: boolean
}

// ─── Advanced Search Panel ───────────────────────────────────────────────────

function AdvancedSearchPanel({
  onClose,
  initialQuery,
  currentParams,
}: {
  onClose: () => void
  initialQuery: string
  currentParams: SearchParams | null
}) {
  const router = useRouter()
  const [from, setFrom] = useState(currentParams?.from ?? "")
  const [to, setTo] = useState(currentParams?.to ?? "")
  const [subject, setSubject] = useState(currentParams?.subject ?? "")
  const [hasWords, setHasWords] = useState(
    currentParams?.hasWords || currentParams?.q || initialQuery
  )
  const [doesNotHave, setDoesNotHave] = useState(currentParams?.doesNotHave ?? "")
  const [sizeVal, setSizeVal] = useState(currentParams?.size ?? "")
  const [sizeOp, setSizeOp] = useState<"gt" | "lt">(currentParams?.sizeOp ?? "gt")
  const [sizeUnit, setSizeUnit] = useState<"Mo" | "Ko">(currentParams?.sizeUnit ?? "Mo")
  const [within, setWithin] = useState(currentParams?.within ?? "")
  const [dateAfter, setDateAfter] = useState(currentParams?.after ?? "")
  const [searchIn, setSearchIn] = useState(currentParams?.in ?? "all")
  const [hasAttachment, setHasAttachment] = useState(
    currentParams?.has?.includes("attachment") ?? false
  )
  const [excludeChats, setExcludeChats] = useState(currentParams?.excludeChats ?? false)

  const handleSubmit = () => {
    const params: Partial<SearchParams> = {
      ...EMPTY_SEARCH_PARAMS,
      q: "",
      from,
      to,
      subject,
      hasWords,
      doesNotHave,
      size: sizeVal,
      sizeOp,
      sizeUnit,
      within,
      after: dateAfter,
      in: searchIn,
      has: hasAttachment ? ["attachment"] : [],
      excludeChats,
    }
    router.push(buildSearchUrl(params))
    onClose()
  }

  return (
    <div className={MAIL_SEARCH_ADVANCED_PANEL_CLASS}>
      <div className="space-y-3 p-4">
        <div className="flex items-center gap-3">
          <Label className="w-36 shrink-0 text-sm text-muted-foreground">De</Label>
          <Input
            value={from}
            onChange={(e) => setFrom(e.target.value)}
            className={cn("h-8 flex-1 px-2 text-sm", MAIL_SEARCH_FIELD_CLASS)}
            autoFocus
          />
        </div>
        <div className="flex items-center gap-3">
          <Label className="w-36 shrink-0 text-sm text-muted-foreground">À</Label>
          <Input
            value={to}
            onChange={(e) => setTo(e.target.value)}
            className={cn("h-8 flex-1 px-2 text-sm", MAIL_SEARCH_FIELD_CLASS)}
          />
        </div>
        <div className="flex items-center gap-3">
          <Label className="w-36 shrink-0 text-sm text-muted-foreground">Objet</Label>
          <Input
            value={subject}
            onChange={(e) => setSubject(e.target.value)}
            className={cn("h-8 flex-1 px-2 text-sm", MAIL_SEARCH_FIELD_CLASS)}
          />
        </div>
        <div className="flex items-center gap-3">
          <Label className="w-36 shrink-0 text-sm text-muted-foreground">
            Contient les mots
          </Label>
          <Input
            value={hasWords}
            onChange={(e) => setHasWords(e.target.value)}
            className={cn("h-8 flex-1 px-2 text-sm", MAIL_SEARCH_FIELD_CLASS)}
          />
        </div>
        <div className="flex items-center gap-3">
          <Label className="w-36 shrink-0 text-sm text-muted-foreground">
            Ne contient pas
          </Label>
          <Input
            value={doesNotHave}
            onChange={(e) => setDoesNotHave(e.target.value)}
            className={cn("h-8 flex-1 px-2 text-sm", MAIL_SEARCH_FIELD_CLASS)}
          />
        </div>

        <div className="flex items-center gap-3">
          <Label className="w-36 shrink-0 text-sm text-muted-foreground">Taille</Label>
          <div className="flex min-w-0 flex-1 flex-wrap items-center gap-2">
            <Select value={sizeOp} onValueChange={(v) => setSizeOp(v as "gt" | "lt")}>
              <SelectTrigger className={cn("h-8 w-32 text-sm", MAIL_SEARCH_FIELD_CLASS)}>
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="gt">supérieure à</SelectItem>
                <SelectItem value="lt">inférieure à</SelectItem>
              </SelectContent>
            </Select>
            <Input
              type="number"
              value={sizeVal}
              onChange={(e) => setSizeVal(e.target.value)}
              className={cn("h-8 w-20 px-2 text-sm", MAIL_SEARCH_FIELD_CLASS)}
            />
            <Select value={sizeUnit} onValueChange={(v) => setSizeUnit(v as "Mo" | "Ko")}>
              <SelectTrigger className={cn("h-8 w-20 text-sm", MAIL_SEARCH_FIELD_CLASS)}>
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="Mo">Mo</SelectItem>
                <SelectItem value="Ko">Ko</SelectItem>
              </SelectContent>
            </Select>
          </div>
        </div>

        <div className="flex items-center gap-3">
          <Label className="w-36 shrink-0 text-sm text-muted-foreground">
            Plage de dates
          </Label>
          <div className="flex min-w-0 flex-1 flex-wrap items-center gap-2">
            <Select value={within} onValueChange={setWithin}>
              <SelectTrigger className={cn("h-8 w-32 text-sm", MAIL_SEARCH_FIELD_CLASS)}>
                <SelectValue placeholder="Sélectionner" />
              </SelectTrigger>
              <SelectContent>
                {DATE_RANGE_OPTIONS.map((opt) => (
                  <SelectItem key={opt.value} value={opt.value}>
                    {opt.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <Input
              type="date"
              value={dateAfter}
              onChange={(e) => setDateAfter(e.target.value)}
              className={cn("h-8 min-w-0 flex-1 px-2 text-sm", MAIL_SEARCH_FIELD_CLASS)}
            />
          </div>
        </div>

        <div className="flex items-center gap-3">
          <Label className="w-36 shrink-0 text-sm text-muted-foreground">
            Rechercher
          </Label>
          <Select value={searchIn} onValueChange={setSearchIn}>
            <SelectTrigger className={cn("h-8 flex-1 text-sm", MAIL_SEARCH_FIELD_CLASS)}>
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              {SEARCH_IN_OPTIONS.map((opt) => (
                <SelectItem key={opt.value} value={opt.value}>
                  {opt.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>

        <div className="flex items-center gap-6 pt-1">
          <label className="flex items-center gap-2 text-sm text-foreground">
            <Checkbox
              className={MAIL_SEARCH_CHECKBOX_CLASS}
              checked={hasAttachment}
              onCheckedChange={(v) => setHasAttachment(v === true)}
            />
            Contenant une pièce jointe
          </label>
          <label className="flex items-center gap-2 text-sm text-foreground">
            <Checkbox
              className={MAIL_SEARCH_CHECKBOX_CLASS}
              checked={excludeChats}
              onCheckedChange={(v) => setExcludeChats(v === true)}
            />
            Ne pas inclure les chats
          </label>
        </div>

        <div
          className={cn(
            "flex items-center justify-end gap-3 border-t pt-3",
            MAIL_SEARCH_SECTION_DIVIDER_CLASS
          )}
        >
          <Button variant="ghost" className="text-sm text-blue-600" disabled>
            Créer un filtre
          </Button>
          <Button
            className="bg-[#1a73e8] text-sm text-white hover:bg-[#1765cc]"
            onClick={handleSubmit}
          >
            Rechercher
          </Button>
        </div>
      </div>
    </div>
  )
}

// ─── Main Search Bar ─────────────────────────────────────────────────────────

export function MailSearchBar({
  className,
  compact = false,
}: MailSearchBarProps) {
  const router = useRouter()
  const pathname = usePathname()
  const isOnSearchPage = pathname?.includes("/mail/search") ?? false
  const urlSearchParams = useSearchParams()
  const currentSearchParams = useMemo(
    () => parseSearchParams(urlSearchParams),
    [urlSearchParams]
  )
  const account = useActiveAccount()
  const contacts = useContactsStore((s) => s.contacts)

  const inputValue = useMailSearchStore((s) => s.inputValue)
  const dropdownOpen = useMailSearchStore((s) => s.dropdownOpen)
  const selectedIndex = useMailSearchStore((s) => s.selectedIndex)
  const advancedOpen = useMailSearchStore((s) => s.advancedOpen)
  const chipAttachment = useMailSearchStore((s) => s.chipAttachment)
  const chipLast7Days = useMailSearchStore((s) => s.chipLast7Days)
  const chipFromMe = useMailSearchStore((s) => s.chipFromMe)

  const {
    setInputValue,
    setDropdownOpen,
    setSelectedIndex,
    setAdvancedOpen,
    toggleChipAttachment,
    toggleChipLast7Days,
    toggleChipFromMe,
    reset,
  } = useMailSearchStore.getState()

  const inputRef = useRef<HTMLInputElement>(null)
  const containerRef = useRef<HTMLDivElement>(null)
  const [focused, setFocused] = useState(false)

  useEffect(() => {
    const q = currentSearchParams?.q ?? ""
    if (q && !inputValue) {
      setInputValue(q)
    }
  }, [currentSearchParams?.q])

  const suggestions = useMemo<SearchSuggestion[]>(() => {
    if (!inputValue.trim()) return []
    const contactHits = matchContacts(inputValue, contacts, 5)
    const emailHits = matchEmails(inputValue, emails, 5)
    const seen = new Set(contactHits.map((c) => c.email))
    const unique = emailHits.filter((e) => !seen.has(e.email))
    return [...contactHits, ...unique]
  }, [inputValue, contacts])

  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: () => {
          setDropdownOpen(false)
          inputRef.current?.blur()
        },
      })
    },
    [inputValue, chipAttachment, chipLast7Days, chipFromMe, account.email, router]
  )

  const selectSuggestion = useCallback(
    (s: SearchSuggestion) => {
      const params = buildQuickSearchParams(s.email, {
        chipAttachment,
        chipLast7Days,
        chipFromMe,
        fromEmail: account.email,
      })
      submitMailSearch(router, params, {
        onAfter: () => {
          setInputValue(s.email)
          setDropdownOpen(false)
          inputRef.current?.blur()
        },
      })
    },
    [chipAttachment, chipLast7Days, chipFromMe, account.email, router]
  )

  const handleKeyDown = useCallback(
    (e: KeyboardEvent<HTMLInputElement>) => {
      if (!dropdownOpen && e.key !== "Enter") return

      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()
          setDropdownOpen(false)
          setAdvancedOpen(false)
          inputRef.current?.blur()
          break
      }
    },
    [
      dropdownOpen,
      selectedIndex,
      totalItems,
      suggestions,
      ghostText,
      inputValue,
      submitSearch,
      selectSuggestion,
    ]
  )

  useEffect(() => {
    const handleClickOutside = (e: MouseEvent) => {
      const target = e.target as HTMLElement | null
      if (!target) return
      if (containerRef.current?.contains(target)) return
      if (target.closest("[data-radix-popper-content-wrapper]")) return
      setDropdownOpen(false)
      setAdvancedOpen(false)
    }
    document.addEventListener("mousedown", handleClickOutside)
    return () => document.removeEventListener("mousedown", handleClickOutside)
  }, [])

  const showDropdown = dropdownOpen && inputValue.trim().length > 0 && focused

  return (
    <div
      ref={containerRef}
      className={cn("relative flex w-full min-w-0 flex-col overflow-visible", className)}
    >
      {/* Input row */}
      <div className="relative flex w-full min-w-0 items-center">
        <div
          className={cn(
            "pointer-events-none absolute flex items-center text-gray-500",
            compact ? "left-4" : "left-3.5"
          )}
        >
          <Search className="size-5 shrink-0" />
        </div>

        {/* Ghost text overlay */}
        {ghostText && focused && (
          <div
            className={cn(
              "pointer-events-none absolute flex items-center text-sm text-gray-400",
              compact ? "left-[44px]" : "left-[44px]"
            )}
            aria-hidden
          >
            <span className="invisible">{inputValue}</span>
            <span>{ghostText}</span>
          </div>
        )}

        <input
          ref={inputRef}
          type="text"
          placeholder="Rechercher dans les messages"
          value={inputValue}
          onChange={(e) => setInputValue(e.target.value)}
          onFocus={() => {
            setFocused(true)
            if (inputValue.trim()) setDropdownOpen(true)
          }}
          onBlur={() => setFocused(false)}
          onKeyDown={handleKeyDown}
          className={cn(
            "h-12 w-full rounded-full border-0 bg-muted text-sm outline-none placeholder:text-gray-500",
            focused || advancedOpen
              ? "bg-white shadow-md ring-1 ring-gray-300 dark:bg-gray-900 dark:ring-gray-600"
              : "",
            compact ? "pl-11 pr-20" : "pl-11 pr-20"
          )}
          role="combobox"
          aria-expanded={showDropdown}
          aria-autocomplete="list"
          aria-controls="search-suggestions"
          autoComplete="off"
        />

        {/* Clear button */}
        {inputValue && (
          <Button
            variant="ghost"
            size="icon"
            className="absolute right-10 text-gray-600"
            onClick={() => {
              reset()
              if (isOnSearchPage) {
                router.push("/mail/inbox")
              } else {
                inputRef.current?.focus()
              }
            }}
            aria-label="Effacer la recherche"
          >
            <X className="h-5 w-5" />
          </Button>
        )}

        {/* Advanced settings button */}
        <Button
          variant="ghost"
          size="icon"
          className={cn(
            "absolute text-gray-600",
            compact ? "right-3" : "right-2"
          )}
          aria-label="Filtres de recherche"
          onMouseDown={(e) => e.preventDefault()}
          onClick={() => {
            const current = useMailSearchStore.getState().advancedOpen
            setAdvancedOpen(!current)
          }}
        >
          <SlidersHorizontal className="h-5 w-5" />
        </Button>
      </div>

      {/* Dropdown */}
      {showDropdown && !advancedOpen && (
        <div
          id="search-suggestions"
          role="listbox"
          className={MAIL_SEARCH_SUGGESTIONS_DROPDOWN_CLASS}
        >
          {/* Filter chips */}
          <div className="flex items-center gap-2 overflow-x-auto border-b border-gray-100 px-4 py-2 whitespace-nowrap dark:border-gray-800">
            <button
              type="button"
              onClick={(e) => {
                e.preventDefault()
                toggleChipAttachment()
              }}
              onMouseDown={(e) => e.preventDefault()}
              className={cn(
                "flex items-center gap-1.5 rounded-full border px-3 py-1 text-xs transition-colors",
                chipAttachment
                  ? "border-blue-200 bg-blue-50 text-blue-700 dark:border-blue-700 dark:bg-blue-900/30 dark:text-blue-300"
                  : "border-gray-200 text-gray-600 hover:bg-gray-50 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-800"
              )}
            >
              <Paperclip className="size-3.5" />
              Contient une pièce jointe
            </button>
            <button
              type="button"
              onClick={(e) => {
                e.preventDefault()
                toggleChipLast7Days()
              }}
              onMouseDown={(e) => e.preventDefault()}
              className={cn(
                "flex items-center gap-1.5 rounded-full border px-3 py-1 text-xs transition-colors",
                chipLast7Days
                  ? "border-blue-200 bg-blue-50 text-blue-700 dark:border-blue-700 dark:bg-blue-900/30 dark:text-blue-300"
                  : "border-gray-200 text-gray-600 hover:bg-gray-50 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-800"
              )}
            >
              <Clock className="size-3.5" />
              7 derniers jours
            </button>
            <button
              type="button"
              onClick={(e) => {
                e.preventDefault()
                toggleChipFromMe()
              }}
              onMouseDown={(e) => e.preventDefault()}
              className={cn(
                "flex items-center gap-1.5 rounded-full border px-3 py-1 text-xs transition-colors",
                chipFromMe
                  ? "border-blue-200 bg-blue-50 text-blue-700 dark:border-blue-700 dark:bg-blue-900/30 dark:text-blue-300"
                  : "border-gray-200 text-gray-600 hover:bg-gray-50 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-800"
              )}
            >
              <User className="size-3.5" />
              De moi
            </button>
          </div>

          {/* Suggestions */}
          {suggestions.map((s, i) => {
            const isSelected = i === selectedIndex
            if (s.kind === "contact") {
              const initial = senderInitial(s.displayName)
              const color = avatarColor(s.displayName)
              return (
                <button
                  key={`c-${s.contact.id}-${s.email}`}
                  type="button"
                  role="option"
                  aria-selected={isSelected}
                  className={cn(
                    "flex w-full items-center gap-3 px-4 py-2.5 text-left text-sm transition-colors",
                    isSelected
                      ? "bg-gray-100 dark:bg-gray-800"
                      : "hover:bg-gray-50 dark:hover:bg-gray-800/50"
                  )}
                  onMouseDown={(e) => e.preventDefault()}
                  onClick={() => selectSuggestion(s)}
                  onMouseEnter={() => setSelectedIndex(i)}
                >
                  <div
                    className="flex size-8 shrink-0 items-center justify-center rounded-full text-xs font-medium text-white"
                    style={{ backgroundColor: color }}
                  >
                    {initial}
                  </div>
                  <div className="min-w-0 flex-1">
                    <div className="truncate font-medium text-gray-900 dark:text-gray-100">
                      {s.displayName}
                    </div>
                    <div className="truncate text-xs text-gray-500">
                      {s.email}
                    </div>
                  </div>
                </button>
              )
            }
            return (
              <button
                key={`e-${s.email}`}
                type="button"
                role="option"
                aria-selected={isSelected}
                className={cn(
                  "flex w-full items-center gap-3 px-4 py-2.5 text-left text-sm transition-colors",
                  isSelected
                    ? "bg-gray-100 dark:bg-gray-800"
                    : "hover:bg-gray-50 dark:hover:bg-gray-800/50"
                )}
                onMouseDown={(e) => e.preventDefault()}
                onClick={() => selectSuggestion(s)}
                onMouseEnter={() => setSelectedIndex(i)}
              >
                <div className="flex size-8 shrink-0 items-center justify-center rounded-full bg-gray-200 text-gray-500 dark:bg-gray-700">
                  <User className="size-4" />
                </div>
                <div className="min-w-0 flex-1">
                  <div className="truncate text-gray-700 dark:text-gray-300">
                    {s.email}
                  </div>
                </div>
              </button>
            )
          })}

          {/* "All results" row */}
          <button
            type="button"
            role="option"
            aria-selected={selectedIndex === suggestions.length}
            className={cn(
              "flex w-full items-center gap-3 border-t border-gray-100 px-4 py-2.5 text-left text-sm transition-colors dark:border-gray-800",
              selectedIndex === suggestions.length
                ? "bg-gray-100 dark:bg-gray-800"
                : "hover:bg-gray-50 dark:hover:bg-gray-800/50"
            )}
            onMouseDown={(e) => e.preventDefault()}
            onClick={() => submitSearch()}
            onMouseEnter={() => setSelectedIndex(suggestions.length)}
          >
            <div className="flex size-8 shrink-0 items-center justify-center">
              <Search className="size-5 text-gray-400" />
            </div>
            <span className="text-gray-600 dark:text-gray-400">
              Tous les résultats de recherche pour &laquo;&nbsp;
              <span className="font-medium text-gray-900 dark:text-gray-100">
                {inputValue}
              </span>
              &nbsp;&raquo;
            </span>
            <span className="ml-auto text-xs text-gray-400">
              Appuyer sur ENTRÉE
            </span>
          </button>
        </div>
      )}

      {/* Advanced search panel */}
      {advancedOpen && (
        <AdvancedSearchPanel
          onClose={() => setAdvancedOpen(false)}
          initialQuery={inputValue}
          currentParams={currentSearchParams}
        />
      )}
    </div>
  )
}
