"use client";

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

const FONT_SIZES: FontSizeOption[] = [
  { label: "Small", value: "12px" },
  { label: "Normal", value: "16px" },
  { label: "Medium", value: "18px" },
  { label: "Large", value: "24px" },
  { label: "X-Large", value: "32px" },
  { label: "Huge", value: "48px" },
];

/**
 * Font size dropdown. Reads/writes the `fontSize` attribute via the
 * official `FontSize` extension from @tiptap/extension-text-style/font-size
 * (registered in TextEditor.tsx).
 *
 * Portaled to `document.body` with auto-flip positioning so it's never
 * clipped by a parent modal's overflow.
 */
export default function FontSizeDropdown({ editor }: EditorComponentProps) {
  const [open, setOpen] = useState(false);

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

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

  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 currentSize: string =
    editor.getAttributes("textStyle").fontSize ?? "16px";
  const currentLabel =
    FONT_SIZES.find((f) => f.value === currentSize)?.label ?? "Normal";

  const handleSelect = (value: string) => {
    editor.chain().focus().setFontSize(value).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-[76px] sm:min-w-[96px] justify-between
        "
      >
        <span className="truncate">{currentLabel}</span>
        <ChevronDown className="h-3.5 w-3.5 opacity-60" />
      </button>

      <PopoverPortal open={open} position={position} popoverRef={popoverRef}>
        <div
          role="listbox"
          className="
            w-36 overflow-hidden rounded-md border border-zinc-200 bg-white
            py-1 shadow-lg 
          "
        >
          {FONT_SIZES.map((opt) => {
            const isActive = opt.value === currentSize;
            return (
              <button
                key={opt.value}
                type="button"
                role="option"
                aria-selected={isActive}
                onClick={() => handleSelect(opt.value)}
                className={`
                  flex w-full items-center justify-between px-3 py-1.5 text-left text-sm
                  hover:bg-zinc-100 
                  ${
                    isActive
                      ? "bg-indigo-50 text-indigo-700 "
                      : "text-zinc-700 "
                  }
                `}
              >
                <span>{opt.label}</span>
                <span className="text-xs text-zinc-400">{opt.value}</span>
              </button>
            );
          })}
        </div>
      </PopoverPortal>
    </div>
  );
}
