// packages/core/src/components/popover/popover-root.tsx
import type { Middleware, Placement } from "@floating-ui/dom";
import { flip, offset, shift } from "@floating-ui/dom";
import type { Accessor, JSX } from "solid-js";
import { createSignal, createUniqueId } from "solid-js";
import {
  type CreateDisclosureStateOptions,
  createDisclosureState,
} from "../../primitives/create-disclosure-state";
import { createFloating } from "../../primitives/create-floating";
import {
  InternalPopoverContextProvider,
  PopoverPublicContextProvider,
  type InternalPopoverContextValue,
} from "./popover-context";

import type { PopoverRootProps } from "./popover.props";
export type { PopoverRootProps } from "./popover.props";

/**
 * Root component for Popover. Manages open state, floating positioning,
 * and provides context to all Popover parts. Renders no DOM elements.
 */
export function PopoverRoot(props: PopoverRootProps): JSX.Element {
  const disclosure = createDisclosureState({
    get open() {
      return props.open;
    },
    get defaultOpen() {
      return props.defaultOpen;
    },
    get onOpenChange() {
      return props.onOpenChange;
    },
  } as CreateDisclosureStateOptions);

  const contentId = createUniqueId();
  const [triggerRef, setTriggerRef] = createSignal<HTMLElement | null>(null);
  const [contentRef, setContentRef] = createSignal<HTMLElement | null>(null);

  const floating = createFloating({
    anchor: triggerRef,
    floating: contentRef,
    placement: (() => props.placement ?? "bottom") as Accessor<Placement>,
    middleware: (() => [offset(8), flip(), shift({ padding: 8 })]) as Accessor<Middleware[]>,
    open: disclosure.isOpen,
  });

  const internalCtx: InternalPopoverContextValue = {
    isOpen: disclosure.isOpen,
    setOpen: (open) => (open ? disclosure.open() : disclosure.close()),
    modal: () => props.modal ?? false,
    contentId: () => contentId,
    triggerRef,
    setTriggerRef,
    contentRef,
    setContentRef,
    floatingStyle: floating.style,
  };

  return (
    <InternalPopoverContextProvider value={internalCtx}>
      <PopoverPublicContextProvider
        value={{ open: disclosure.isOpen, modal: () => props.modal ?? false }}
      >
        {props.children}
      </PopoverPublicContextProvider>
    </InternalPopoverContextProvider>
  );
}
