"use client"

import {
  useState,
  useRef,
  useEffect,
  useCallback,
  useMemo,
  type RefObject,
} from "react"
import { ChevronDown, X } from "lucide-react"
import {
  type ComposeState,
  type Contact,
  DEFAULT_IDENTITIES,
  MOCK_CONTACTS,
} from "@/lib/compose-context"
import { cn } from "@/lib/utils"
import {
  MAIL_COMPOSE_CONTACT_PILL_CLASS,
  MAIL_COMPOSE_RECIPIENT_DIVIDER,
  MAIL_COMPOSE_SUGGESTION_HOVER,
  MAIL_COMPOSE_SUGGESTION_SELECTED,
} from "@/lib/mail-chrome-classes"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { COMPOSE_PORTAL_Z, EMAIL_REGEX } from "./compose-shared"

function RecipientField({
  label,
  contacts,
  onChange,
  placeholder,
  onActivate,
  autoFocus,
  onAutoFocusDone,
}: {
  label: string
  contacts: Contact[]
  onChange: (contacts: Contact[]) => void
  placeholder?: string
  onActivate?: () => void
  autoFocus?: boolean
  onAutoFocusDone?: () => void
}) {
  const [inputValue, setInputValue] = useState("")
  const [showSuggestions, setShowSuggestions] = useState(false)
  const [selectedSuggestionIdx, setSelectedSuggestionIdx] = useState(0)
  const inputRef = useRef<HTMLInputElement>(null)
  const containerRef = useRef<HTMLDivElement>(null)

  const suggestions = useMemo(() => {
    if (!inputValue.trim()) return []
    const q = inputValue.toLowerCase()
    return MOCK_CONTACTS.filter(
      (c) =>
        !contacts.some((existing) => existing.email === c.email) &&
        (c.name.toLowerCase().includes(q) || c.email.toLowerCase().includes(q))
    ).slice(0, 6)
  }, [inputValue, contacts])

  useEffect(() => {
    setSelectedSuggestionIdx(0)
  }, [suggestions.length])

  useEffect(() => {
    if (!autoFocus) return
    const id = window.requestAnimationFrame(() => {
      inputRef.current?.focus()
      onAutoFocusDone?.()
    })
    return () => window.cancelAnimationFrame(id)
  }, [autoFocus, onAutoFocusDone])

  const addContact = useCallback(
    (contact: Contact) => {
      if (!contacts.some((c) => c.email === contact.email)) {
        onChange([...contacts, contact])
      }
      setInputValue("")
      setShowSuggestions(false)
    },
    [contacts, onChange]
  )

  const tryAddRawEmail = useCallback(
    (raw: string) => {
      const trimmed = raw.trim().replace(/,$/, "")
      if (!trimmed) return
      const matchedContact = MOCK_CONTACTS.find(
        (c) => c.email.toLowerCase() === trimmed.toLowerCase()
      )
      if (matchedContact) {
        addContact(matchedContact)
      } else if (EMAIL_REGEX.test(trimmed)) {
        addContact({ name: trimmed, email: trimmed })
      }
    },
    [addContact]
  )

  const removeContact = useCallback(
    (email: string) => {
      onChange(contacts.filter((c) => c.email !== email))
    },
    [contacts, onChange]
  )

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (
      (e.key === "Enter" || e.key === "Tab" || e.key === "," || e.key === " ") &&
      inputValue.trim()
    ) {
      e.preventDefault()
      if (showSuggestions && suggestions.length > 0) {
        addContact(suggestions[selectedSuggestionIdx])
      } else {
        tryAddRawEmail(inputValue)
      }
      return
    }
    if (e.key === "Backspace" && !inputValue && contacts.length > 0) {
      onChange(contacts.slice(0, -1))
      return
    }
    if (showSuggestions && suggestions.length > 0) {
      if (e.key === "ArrowDown") {
        e.preventDefault()
        setSelectedSuggestionIdx((i) =>
          i < suggestions.length - 1 ? i + 1 : 0
        )
      } else if (e.key === "ArrowUp") {
        e.preventDefault()
        setSelectedSuggestionIdx((i) =>
          i > 0 ? i - 1 : suggestions.length - 1
        )
      }
    }
    if (e.key === "Escape") {
      setShowSuggestions(false)
    }
  }

  const getInitials = (name: string) => {
    const parts = name.split(" ").filter(Boolean)
    return parts.length >= 2
      ? (parts[0][0] + parts[parts.length - 1][0]).toUpperCase()
      : (parts[0]?.[0] ?? "").toUpperCase()
  }

  const pillColors = [
    "bg-blue-600",
    "bg-purple-600",
    "bg-emerald-600",
    "bg-amber-600",
    "bg-rose-600",
    "bg-teal-600",
    "bg-indigo-600",
  ]

  const getColor = (email: string) => {
    let hash = 0
    for (let i = 0; i < email.length; i++) {
      hash = email.charCodeAt(i) + ((hash << 5) - hash)
    }
    return pillColors[Math.abs(hash) % pillColors.length]
  }

  return (
    <div className="relative" ref={containerRef}>
      <div
        className="flex min-h-[32px] cursor-text flex-wrap items-center gap-1 px-3 py-1"
        onClick={() => {
          inputRef.current?.focus()
          onActivate?.()
        }}
      >
        <span className="shrink-0 select-none text-sm text-muted-foreground">{label}</span>
        {contacts.map((c) => (
          <span key={c.email} className={MAIL_COMPOSE_CONTACT_PILL_CLASS}>
            <span
              className={cn(
                "flex h-6 w-6 items-center justify-center rounded-full text-[10px] font-bold text-white",
                getColor(c.email)
              )}
            >
              {getInitials(c.name)}
            </span>
            <span className="max-w-[150px] truncate text-sm">
              {c.name === c.email ? c.email : c.name}
            </span>
            <button
              type="button"
              onClick={() => removeContact(c.email)}
              className="ml-0.5 flex h-4 w-4 items-center justify-center rounded-full hover:bg-black/10"
            >
              <X className="h-3 w-3" />
            </button>
          </span>
        ))}
        <input
          ref={inputRef}
          type="text"
          value={inputValue}
          onChange={(e) => {
            setInputValue(e.target.value)
            setShowSuggestions(true)
          }}
          onKeyDown={handleKeyDown}
          onFocus={() => {
            setShowSuggestions(true)
            onActivate?.()
          }}
          onBlur={() => {
            setTimeout(() => {
              setShowSuggestions(false)
              if (inputValue.trim()) tryAddRawEmail(inputValue)
            }, 200)
          }}
          placeholder={contacts.length === 0 ? placeholder : undefined}
          className="min-w-[120px] flex-1 border-none bg-transparent py-1 text-sm text-foreground outline-none placeholder:text-muted-foreground"
        />
      </div>
      {showSuggestions && suggestions.length > 0 && (
        <div className="absolute left-0 right-0 top-full z-50 mt-1 max-h-[240px] overflow-y-auto rounded-lg border border-border bg-popover py-1 text-popover-foreground shadow-lg">
          {suggestions.map((s, idx) => (
            <button
              key={s.email}
              type="button"
              onMouseDown={(e) => {
                e.preventDefault()
                addContact(s)
              }}
              className={cn(
                "flex w-full items-center gap-3 px-3 py-2 text-left text-sm transition-colors",
                idx === selectedSuggestionIdx
                  ? MAIL_COMPOSE_SUGGESTION_SELECTED
                  : MAIL_COMPOSE_SUGGESTION_HOVER
              )}
            >
              <span
                className={cn(
                  "flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-xs font-bold text-white",
                  getColor(s.email)
                )}
              >
                {getInitials(s.name)}
              </span>
              <div className="min-w-0 flex-1">
                <div className="truncate font-medium text-foreground">{s.name}</div>
                <div className="truncate text-xs text-muted-foreground">{s.email}</div>
              </div>
            </button>
          ))}
        </div>
      )}
    </div>
  )
}

export interface ComposeRecipientFieldsProps {
  compose: ComposeState
  isInline: boolean
  showFromField: boolean
  updateCompose: (id: string, patch: Partial<ComposeState>) => void
  handleIdentityChange: (identity: (typeof DEFAULT_IDENTITIES)[number]) => void
  clearFocusToMount: () => void
  subjectInputRef: RefObject<HTMLInputElement | null>
  onRecipientsActivate: () => void
}

export function ComposeRecipientFields({
  compose,
  isInline,
  showFromField,
  updateCompose,
  handleIdentityChange,
  clearFocusToMount,
  subjectInputRef,
  onRecipientsActivate,
}: ComposeRecipientFieldsProps) {
  const dockNewMessageTabOrder =
    !isInline && !compose.threadEmailId && !compose.threadKind
  const forwardDockSkipSubjectTab =
    !isInline && compose.threadKind === "forward"

  return (
    <>
      {showFromField && (
        <div className="flex min-w-0 items-center gap-2 overflow-hidden px-3 py-1.5">
          <span className="shrink-0 text-sm text-muted-foreground">De</span>
          <DropdownMenu modal={false}>
            <DropdownMenuTrigger asChild>
              <button
                type="button"
                className="flex min-w-0 items-center gap-1 rounded px-1 py-0.5 text-sm text-foreground hover:bg-accent"
              >
                <span className="min-w-0 truncate font-medium">{compose.from.name}</span>
                <span className="min-w-0 shrink truncate text-muted-foreground">
                  &lt;{compose.from.email}&gt;
                </span>
                <ChevronDown className="h-3 w-3 shrink-0 text-muted-foreground" />
              </button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="start" className={cn("min-w-[300px]", COMPOSE_PORTAL_Z)}>
              {DEFAULT_IDENTITIES.map((id) => (
                <DropdownMenuItem
                  key={id.email}
                  onSelect={() => handleIdentityChange(id)}
                >
                  <div className="flex flex-col">
                    <span className="font-medium">{id.name}</span>
                    <span className="text-xs text-muted-foreground">{id.email}</span>
                  </div>
                </DropdownMenuItem>
              ))}
            </DropdownMenuContent>
          </DropdownMenu>
        </div>
      )}
      {showFromField && !isInline && <div className={MAIL_COMPOSE_RECIPIENT_DIVIDER} />}

      <div className="relative flex items-start">
        <div className="min-w-0 flex-1">
          <RecipientField
            label={showFromField || compose.to.length > 0 ? "À" : "Destinataires"}
            contacts={compose.to}
            onChange={(to) => updateCompose(compose.id, { to })}
            onActivate={onRecipientsActivate}
            autoFocus={Boolean(compose.focusToOnMount)}
            onAutoFocusDone={clearFocusToMount}
          />
        </div>
        {showFromField && (!compose.showCc || !compose.showBcc) && (
          <div className="flex shrink-0 items-center gap-1 px-2 py-1.5">
            {!compose.showCc && (
              <button
                type="button"
                tabIndex={dockNewMessageTabOrder ? -1 : undefined}
                onClick={() => updateCompose(compose.id, { showCc: true })}
                className="text-sm text-muted-foreground hover:text-foreground hover:underline"
              >
                Cc
              </button>
            )}
            {!compose.showBcc && (
              <button
                type="button"
                tabIndex={dockNewMessageTabOrder ? -1 : undefined}
                onClick={() => updateCompose(compose.id, { showBcc: true })}
                className="text-sm text-muted-foreground hover:text-foreground hover:underline"
              >
                Cci
              </button>
            )}
          </div>
        )}
      </div>
      {!isInline && <div className={MAIL_COMPOSE_RECIPIENT_DIVIDER} />}

      {compose.showCc && (
        <>
          <RecipientField
            label="Cc"
            contacts={compose.cc}
            onChange={(cc) => updateCompose(compose.id, { cc })}
          />
          {!isInline && <div className={MAIL_COMPOSE_RECIPIENT_DIVIDER} />}
        </>
      )}

      {compose.showBcc && (
        <>
          <RecipientField
            label="Cci"
            contacts={compose.bcc}
            onChange={(bcc) => updateCompose(compose.id, { bcc })}
          />
          {!isInline && <div className={MAIL_COMPOSE_RECIPIENT_DIVIDER} />}
        </>
      )}

      {!isInline && (
        <>
          <input
            ref={subjectInputRef}
            type="text"
            value={compose.subject}
            onChange={(e) =>
              updateCompose(compose.id, { subject: e.target.value })
            }
            placeholder="Objet"
            tabIndex={forwardDockSkipSubjectTab ? -1 : undefined}
            className="h-8 w-full border-none bg-transparent px-3 text-sm text-foreground outline-none placeholder:text-muted-foreground"
          />
          <div className={MAIL_COMPOSE_RECIPIENT_DIVIDER} />
        </>
      )}
    </>
  )
}
