/**
 * MenuBar — a top-of-window bar of dropdown menus (ticket #16).
 *
 * Replaces the former left sidebar tab strip with a classic IDE-style menu bar:
 * each top-level menu opens a dropdown of items; an item runs its `onSelect`
 * (typically opening a {@link FloatingWindow} or toggling a panel) and closes
 * the menu. One menu is open at a time; Escape or an outside click closes it.
 *
 * Dropdowns use the frozen `menuDropdown` z-index token (40). Menu items are
 * plain `<button>`s (implicit `role="button"`) so callers/tests can target them
 * by accessible name.
 */

import { useEffect, useRef, useState } from "react";

import { cn } from "../lib/cn";
import { zIndex } from "./zIndex";

export interface MenuBarItem {
  id: string;
  label: string;
  onSelect: () => void;
  disabled?: boolean;
  /** Renders a selected/active marker (e.g. the currently-open panel). */
  active?: boolean;
  /**
   * Nested items shown in a side flyout (#26). When present, the item opens its
   * submenu on hover/click instead of running `onSelect`; selecting a leaf item
   * of the submenu runs that leaf's `onSelect` and closes the whole menu.
   */
  submenu?: MenuBarItem[];
}

export interface MenuBarMenu {
  id: string;
  label: string;
  items: MenuBarItem[];
}

export interface MenuBarProps {
  menus: MenuBarMenu[];
  className?: string;
}

export function MenuBar({ menus, className }: MenuBarProps) {
  const [openId, setOpenId] = useState<string | null>(null);
  // Which item's submenu flyout is currently open (at most one, #26). Reset
  // whenever the top-level menu changes or closes.
  const [openSubId, setOpenSubId] = useState<string | null>(null);
  const rootRef = useRef<HTMLDivElement>(null);

  function closeMenus() {
    setOpenId(null);
    setOpenSubId(null);
  }

  // Close on outside click and on Escape while a menu is open.
  useEffect(() => {
    if (openId === null) return;
    function onPointerDown(e: MouseEvent) {
      if (!rootRef.current?.contains(e.target as Node)) closeMenus();
    }
    function onKeyDown(e: KeyboardEvent) {
      if (e.key === "Escape") closeMenus();
    }
    document.addEventListener("mousedown", onPointerDown);
    document.addEventListener("keydown", onKeyDown);
    return () => {
      document.removeEventListener("mousedown", onPointerDown);
      document.removeEventListener("keydown", onKeyDown);
    };
  }, [openId]);

  return (
    <div
      ref={rootRef}
      className={cn(
        "flex shrink-0 items-center gap-0.5 border-b border-border bg-surface px-2 py-1",
        className,
      )}
    >
      {menus.map((menu) => {
        const open = openId === menu.id;
        return (
          <div key={menu.id} className="relative">
            <button
              type="button"
              aria-haspopup="menu"
              aria-expanded={open}
              onClick={() => {
                setOpenSubId(null);
                setOpenId((cur) => (cur === menu.id ? null : menu.id));
              }}
              className={cn(
                "rounded px-2.5 py-1 text-sm transition-colors",
                open
                  ? "bg-raised text-content"
                  : "text-muted hover:bg-raised hover:text-content",
              )}
            >
              {menu.label}
            </button>
            {open && (
              <div
                role="menu"
                aria-label={menu.label}
                style={{ zIndex: zIndex.menuDropdown }}
                className={cn(
                  "absolute left-0 top-full mt-1 min-w-44 rounded-md border border-border",
                  "bg-surface py-1 shadow-xl",
                )}
              >
                {menu.items.map((item) => {
                  const hasSub = (item.submenu?.length ?? 0) > 0;
                  const subOpen = hasSub && openSubId === item.id;
                  return (
                    <div
                      key={item.id}
                      className="relative"
                      onMouseEnter={() =>
                        setOpenSubId(hasSub ? item.id : null)
                      }
                    >
                      <button
                        type="button"
                        disabled={item.disabled}
                        aria-haspopup={hasSub ? "menu" : undefined}
                        aria-expanded={hasSub ? subOpen : undefined}
                        onClick={() => {
                          if (hasSub) {
                            setOpenSubId((cur) =>
                              cur === item.id ? null : item.id,
                            );
                            return;
                          }
                          item.onSelect();
                          closeMenus();
                        }}
                        className={cn(
                          "flex w-full items-center justify-between gap-3 px-3 py-1.5 text-left text-sm transition-colors",
                          "text-content hover:bg-raised",
                          "disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-transparent",
                        )}
                      >
                        <span>{item.label}</span>
                        {hasSub ? (
                          <span aria-hidden className="text-muted">
                            {item.active ? "● ▸" : "▸"}
                          </span>
                        ) : (
                          item.active && (
                            <span aria-hidden className="text-primary">
                              ●
                            </span>
                          )
                        )}
                      </button>
                      {subOpen && (
                        <div
                          role="menu"
                          aria-label={item.label}
                          style={{ zIndex: zIndex.floatingWindowNested }}
                          className={cn(
                            "absolute left-full top-0 ml-1 min-w-44 rounded-md border border-border",
                            "bg-surface py-1 shadow-xl",
                          )}
                        >
                          {item.submenu!.map((sub) => (
                            <button
                              key={sub.id}
                              type="button"
                              disabled={sub.disabled}
                              onClick={() => {
                                sub.onSelect();
                                closeMenus();
                              }}
                              className={cn(
                                "flex w-full items-center justify-between gap-3 px-3 py-1.5 text-left text-sm transition-colors",
                                "text-content hover:bg-raised",
                                "disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-transparent",
                              )}
                            >
                              <span>{sub.label}</span>
                              {sub.active && (
                                <span aria-hidden className="text-primary">
                                  ●
                                </span>
                              )}
                            </button>
                          ))}
                        </div>
                      )}
                    </div>
                  );
                })}
              </div>
            )}
          </div>
        );
      })}
    </div>
  );
}
