"use client";

import { useEffect, useMemo, useState } from "react";
import type { KeyboardEvent } from "react";
import clsx from "clsx";
import type { Contact } from "@/lib/types";
import { ContactAvatar } from "./contact-avatar";

type ShareRecipientAutocompleteProps = {
  value: string;
  onChange: (value: string) => void;
  contacts: Contact[];
  label: string;
  placeholder?: string;
  autoFocus?: boolean;
  disabled?: boolean;
};

export function ShareRecipientAutocomplete({
  value,
  onChange,
  contacts,
  label,
  placeholder = "person@example.com",
  autoFocus = false,
  disabled = false,
}: ShareRecipientAutocompleteProps) {
  const [activeIndex, setActiveIndex] = useState(0);
  const [open, setOpen] = useState(false);
  const token = value.trim().toLowerCase();
  const suggestions = useMemo(() => {
    if (!open || !token) return [];
    const seen = new Set<string>();
    return contacts
      .filter((contact) => {
        const email = contact.email.trim();
        if (!email) return false;
        const haystack = [contact.email, contact.full_name, contact.company].join(" ").toLowerCase();
        return haystack.includes(token);
      })
      .filter((contact) => {
        const key = contact.email.trim().toLowerCase();
        if (seen.has(key)) return false;
        seen.add(key);
        return true;
      })
      .slice(0, 6);
  }, [contacts, token]);

  useEffect(() => {
    setActiveIndex(0);
  }, [suggestions.length, token]);

  function choose(email: string) {
    onChange(email.trim());
    setActiveIndex(0);
    setOpen(false);
  }

  function onKeyDown(event: KeyboardEvent<HTMLInputElement>) {
    if (!suggestions.length) return;
    if (event.key === "ArrowDown") {
      event.preventDefault();
      setActiveIndex((current) => (current + 1) % suggestions.length);
      return;
    }
    if (event.key === "ArrowUp") {
      event.preventDefault();
      setActiveIndex((current) => (current - 1 + suggestions.length) % suggestions.length);
      return;
    }
    if (event.key === "Enter" || event.key === "Tab") {
      event.preventDefault();
      choose(suggestions[activeIndex]?.email || suggestions[0].email);
      return;
    }
    if (event.key === "Escape") {
      setActiveIndex(0);
      setOpen(false);
    }
  }

  return (
    <div className="relative grid gap-2">
      <label className="text-sm font-bold text-slate-600">{label}</label>
      <input
        value={value}
        onChange={(event) => {
          onChange(event.target.value);
          setOpen(true);
        }}
        onFocus={() => {
          if (value.trim()) setOpen(true);
        }}
        onBlur={() => setOpen(false)}
        onKeyDown={onKeyDown}
        className="field h-11 w-full"
        placeholder={placeholder}
        autoFocus={autoFocus}
        autoComplete="off"
        disabled={disabled}
        role="combobox"
        aria-expanded={suggestions.length > 0}
        aria-autocomplete="list"
      />
      {suggestions.length ? (
        <div role="listbox" className="absolute left-0 right-0 top-full z-30 mt-1 overflow-hidden rounded-xl border border-slate-200 bg-white shadow-soft">
          {suggestions.map((contact, index) => (
            <button
              key={`${contact.id || contact.email}-${contact.email}`}
              type="button"
              role="option"
              aria-selected={index === activeIndex}
              onMouseDown={(event) => event.preventDefault()}
              onClick={() => choose(contact.email)}
              className={clsx("flex w-full items-center justify-between gap-3 px-3 py-2 text-left text-sm transition hover:bg-slate-50", index === activeIndex && "bg-slate-50")}
            >
              <ContactAvatar value={contact.full_name || contact.email} photoUrl={contact.photo_url} />
              <span className="min-w-0">
                <strong className="block truncate text-slate-800">{contact.full_name || contact.email}</strong>
                {contact.full_name ? <span className="block truncate text-xs font-semibold text-slate-500">{contact.email}</span> : null}
              </span>
            </button>
          ))}
        </div>
      ) : null}
    </div>
  );
}
