"use client";

import { useEffect, useRef, useState } from "react";
import { ChevronDown } from "lucide-react";
import { type EditorComponentProps, type HeadingOption } from "./types";
import { usePopoverPosition, PopoverPortal } from "./usePopoverPosition";

const HEADING_OPTIONS: HeadingOption[] = [
  { label: "Paragraph", level: 0 },
  { label: "Heading 1", level: 1 },
  { label: "Heading 2", level: 2 },
  { label: "Heading 3", level: 3 },
  { label: "Heading 4", level: 4 },
];

/**
 * Dropdown for switching the current block between paragraph and heading
 * levels 1-4. Closes on outside click and Escape.
 *
 * Portaled to `document.body` with auto-flip positioning so it's never
 * clipped by a parent modal's overflow.
 */
export default function HeadingDropdown({ editor }: EditorComponentProps) {
  const [open, setOpen] = useState(false);

  const triggerRef = useRef<HTMLButtonElement>(null);
  const popoverRef = useRef<HTMLDivElement>(null);

  const position = usePopoverPosition(triggerRef, open, popoverRef, {
    estimatedWidth: 160,
    estimatedHeight: 190,
  });

  useEffect(() => {
    function handleClickOutside(e: MouseEvent) {
      const target = e.target as Node;
      if (
        triggerRef.current &&
        !triggerRef.current.contains(target) &&
        popoverRef.current &&
        !popoverRef.current.contains(target)
      ) {
        setOpen(false);
      }
    }
    function handleEscape(e: KeyboardEvent) {
      if (e.key === "Escape") setOpen(false);
    }
    document.addEventListener("mousedown", handleClickOutside);
    document.addEventListener("keydown", handleEscape);
    return () => {
      document.removeEventListener("mousedown", handleClickOutside);
      document.removeEventListener("keydown", handleEscape);
    };
  }, []);

  if (!editor) return null;

  const currentOption =
    HEADING_OPTIONS.find((opt) =>
      opt.level === 0
        ? editor.isActive("paragraph")
        : editor.isActive("heading", { level: opt.level })
    ) ?? HEADING_OPTIONS[0];

  const handleSelect = (level: HeadingOption["level"]) => {
    if (level === 0) {
      editor.chain().focus().setParagraph().run();
    } else {
      editor
        .chain()
        .focus()
        .toggleHeading({ level })
        .run();
    }
    setOpen(false);
  };

  return (
    <div className="relative shrink-0">
      <button
        ref={triggerRef}
        type="button"
        onClick={() => setOpen((o) => !o)}
        aria-haspopup="listbox"
        aria-expanded={open}
        className="
          flex h-8 sm:h-9 items-center gap-1 rounded-md border border-zinc-200
          bg-white px-2 text-xs sm:text-sm font-medium text-zinc-700
          transition-colors hover:bg-zinc-100
           
          min-w-[88px] sm:min-w-[112px] justify-between
        "
      >
        <span className="truncate">{currentOption.label}</span>
        <ChevronDown className="h-3.5 w-3.5 opacity-60" />
      </button>

      <PopoverPortal open={open} position={position} popoverRef={popoverRef}>
        <div
          role="listbox"
          className="
            w-40 overflow-hidden rounded-md border border-zinc-200 bg-white
            py-1 shadow-lg 
          "
        >
          {HEADING_OPTIONS.map((opt) => {
            const isActive = opt.level === currentOption.level;
            return (
              <button
                key={opt.level}
                type="button"
                role="option"
                aria-selected={isActive}
                onClick={() => handleSelect(opt.level)}
                className={`
                  flex w-full items-center px-3 py-1.5 text-left text-sm
                  hover:bg-zinc-100 
                  ${
                    isActive
                      ? "bg-indigo-50 text-indigo-700 "
                      : "text-zinc-700 "
                  }
                  ${opt.level === 1 ? "text-base font-bold" : ""}
                  ${opt.level === 2 ? "text-[15px] font-semibold" : ""}
                  ${opt.level === 3 ? "text-sm font-semibold" : ""}
                `}
              >
                {opt.label}
              </button>
            );
          })}
        </div>
      </PopoverPortal>
    </div>
  );
}
