import { type ReactElement, useMemo, useState } from "react";
import { Braces, Search } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import { cn } from "@/lib/utils";

/**
 * MergeTagReference — WealthX Design System
 *
 * A popover that lists the personalisation tokens ("merge tags") available in
 * an email template, grouped by source (Contact / Company / Broker), each with
 * a human label and a description of what it resolves to. Answers the common
 * "where is the list of merge tags and what do they mean?" question, and lets
 * the author drop a token in via `onSelect`.
 *
 * Pure/presentational: the caller supplies the groups and decides what
 * `onSelect(token)` does (insert into the body, copy to clipboard, etc.).
 */

export interface MergeTagReferenceItem {
  /** The literal token, e.g. "{{contact.first_name}}". */
  token: string;
  /** Human label, e.g. "First name". */
  label: string;
  /** What the token resolves to when the email is sent. */
  description: string;
}

export interface MergeTagReferenceGroup {
  /** Group heading, e.g. "Contact". */
  group: string;
  tags: MergeTagReferenceItem[];
}

export interface MergeTagReferenceProps {
  /** The merge tags to list, grouped by source. */
  groups: MergeTagReferenceGroup[];
  /** Called with the token when a tag is chosen (closes the popover). */
  onSelect?: (token: string) => void;
  /** Trigger button label. */
  triggerLabel?: string;
  /** Popover alignment against the trigger. */
  align?: "start" | "center" | "end";
  className?: string;
}

/** Popover reference of a template's available merge tags, grouped by source. */
export function MergeTagReference({
  groups,
  onSelect,
  triggerLabel = "Merge tags",
  align = "end",
  className,
}: MergeTagReferenceProps): ReactElement {
  const [open, setOpen] = useState(false);
  const [query, setQuery] = useState("");

  const filtered = useMemo(() => {
    const q = query.trim().toLowerCase();
    if (!q) return groups;
    return groups
      .map((g) => ({
        ...g,
        tags: g.tags.filter(
          (t) =>
            t.label.toLowerCase().includes(q) ||
            t.token.toLowerCase().includes(q) ||
            t.description.toLowerCase().includes(q),
        ),
      }))
      .filter((g) => g.tags.length > 0);
  }, [groups, query]);

  const handleSelect = (token: string) => {
    onSelect?.(token);
    setOpen(false);
    setQuery("");
  };

  return (
    <Popover open={open} onOpenChange={setOpen}>
      <PopoverTrigger
        render={
          <Button variant="outline" className={cn("gap-1.5", className)}>
            <Braces className="size-4" />
            {triggerLabel}
          </Button>
        }
      />
      <PopoverContent align={align} className="w-80 p-0">
        <div className="border-b border-border p-2">
          <div className="relative">
            <Search className="pointer-events-none absolute left-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" />
            <Input
              value={query}
              onChange={(e) => setQuery(e.target.value)}
              placeholder="Search merge tags…"
              className="h-8 pl-8"
            />
          </div>
        </div>

        <div className="max-h-72 overflow-y-auto p-1">
          {filtered.length === 0 ? (
            <p className="px-3 py-6 text-center text-caption text-muted-foreground">
              No merge tags match "{query}".
            </p>
          ) : (
            filtered.map((g) => (
              <div key={g.group} className="mb-1 last:mb-0">
                <p className="px-2 pb-1 pt-2 text-overline text-muted-foreground">
                  {g.group}
                </p>
                {g.tags.map((t) => (
                  <button
                    key={t.token}
                    type="button"
                    onClick={() => handleSelect(t.token)}
                    className="flex w-full flex-col gap-0.5 px-2 py-1.5 text-left transition-colors hover:bg-muted focus-visible:bg-muted focus-visible:outline-hidden"
                  >
                    <span className="flex items-center justify-between gap-2">
                      <span className="text-label-small text-foreground">
                        {t.label}
                      </span>
                      <span className="text-code text-muted-foreground">
                        {t.token}
                      </span>
                    </span>
                    <span className="text-caption text-muted-foreground">
                      {t.description}
                    </span>
                  </button>
                ))}
              </div>
            ))
          )}
        </div>
      </PopoverContent>
    </Popover>
  );
}

export default MergeTagReference;
