import type { JSX } from "solid-js";
import { onCleanup, splitProps } from "solid-js";
import { createControllableSignal } from "../../primitives/create-controllable-signal";
import { NavigationMenuContext } from "./navigation-menu-context";
import type { NavigationMenuRootProps } from "./navigation-menu.props";

/**
 * Root container for NavigationMenu. Manages which item is active and
 * provides context to all sub-components.
 */
export function NavigationMenuRoot(props: NavigationMenuRootProps): JSX.Element {
  const [local, rest] = splitProps(props, [
    "value",
    "defaultValue",
    "onValueChange",
    "orientation",
    "delayDuration",
    "children",
  ]);

  const [value, setValue] = createControllableSignal<string>({
    value: () => local.value,
    defaultValue: () => local.defaultValue ?? "",
    onChange: (v) => local.onValueChange?.(v),
  });

  let openTimer: ReturnType<typeof setTimeout> | undefined;
  const delay = () => local.delayDuration ?? 200;

  /** Schedule opening a menu item after the hover delay. */
  const scheduleOpen = (itemValue: string) => {
    if (openTimer !== undefined) {
      clearTimeout(openTimer);
      openTimer = undefined;
    }
    openTimer = setTimeout(() => {
      setValue(itemValue);
      openTimer = undefined;
    }, delay());
  };

  /** Cancel any pending open timer and close the active item. */
  const cancelAndClose = () => {
    if (openTimer !== undefined) {
      clearTimeout(openTimer);
      openTimer = undefined;
    }
    setValue("");
  };

  onCleanup(() => {
    if (openTimer !== undefined) clearTimeout(openTimer);
  });

  const ctx = {
    value: value as () => string,
    setValue,
    orientation: () => local.orientation ?? "horizontal",
    scheduleOpen,
    cancelAndClose,
  };

  return (
    <NavigationMenuContext.Provider value={ctx}>
      <nav
        data-scope="navigation-menu"
        data-part="root"
        data-orientation={local.orientation ?? "horizontal"}
        {...rest}
      >
        {local.children}
      </nav>
    </NavigationMenuContext.Provider>
  );
}
