import type { JSX } from "solid-js";
import { Show, createEffect, onCleanup, splitProps } from "solid-js";
import { createDismiss } from "../../utilities/dismiss/create-dismiss";
import { useInternalContextMenuContext } from "./context-menu-context";

export interface ContextMenuContentProps extends JSX.HTMLAttributes<HTMLDivElement> {
  /** Keep mounted when closed. @default false */
  forceMount?: boolean | undefined;
  children?: JSX.Element;
}

/**
 * Floating content panel for ContextMenu. Contains the menu items.
 * Handles dismiss (outside click) and keyboard navigation.
 */
export function ContextMenuContent(props: ContextMenuContentProps): JSX.Element {
  const [local, rest] = splitProps(props, ["children", "forceMount"]);
  const ctx = useInternalContextMenuContext();

  const dismiss = createDismiss({
    getContainer: () => ctx.contentRef(),
    onDismiss: () => ctx.close(),
    dismissOnEscape: false,
  });

  createEffect(() => {
    if (ctx.isOpen()) {
      dismiss.attach();
      queueMicrotask(() => ctx.contentRef()?.focus());
    } else {
      dismiss.detach();
    }
    onCleanup(() => dismiss.detach());
  });

  const handleKeyDown: JSX.EventHandler<HTMLDivElement, KeyboardEvent> = (e) => {
    if (e.key === "Escape") {
      e.preventDefault();
      ctx.close();
      return;
    }
    if (e.key === "Tab") {
      ctx.close();
      return;
    }
    ctx.navigation.containerProps.onKeyDown(e);
  };

  return (
    <Show when={local.forceMount || ctx.isOpen()}>
      <div
        ref={(el) => ctx.setContentRef(el)}
        id={ctx.contentId}
        role="menu"
        aria-orientation="vertical"
        aria-activedescendant={ctx.navigation.containerProps["aria-activedescendant"]}
        data-state={ctx.isOpen() ? "open" : "closed"}
        style={ctx.floatingStyle()}
        tabIndex={-1}
        onKeyDown={handleKeyDown}
        onPointerLeave={() => ctx.navigation.clearHighlight()}
        {...rest}
      >
        {local.children}
      </div>
    </Show>
  );
}
