// packages/core/src/components/popover/popover-context.ts
import type { Accessor, JSX } from "solid-js";
import { createContext, useContext } from "solid-js";

// ─── Internal Context (used only by Popover parts) ──────────────────────────

/** @internal Shared state between all Popover sub-components. */
export interface InternalPopoverContextValue {
  isOpen: Accessor<boolean>;
  setOpen: (open: boolean) => void;
  modal: Accessor<boolean>;
  /** SSR-safe ID for Popover.Content element. */
  contentId: Accessor<string>;
  triggerRef: Accessor<HTMLElement | null>;
  setTriggerRef: (el: HTMLElement | null) => void;
  contentRef: Accessor<HTMLElement | null>;
  setContentRef: (el: HTMLElement | null) => void;
  /** Computed floating position styles. */
  floatingStyle: Accessor<JSX.CSSProperties>;
}

const InternalPopoverContext = createContext<InternalPopoverContextValue>();

/**
 * Returns the internal Popover context value.
 * Throws if used outside of a Popover root.
 */
export function useInternalPopoverContext(): InternalPopoverContextValue {
  const ctx = useContext(InternalPopoverContext);
  if (!ctx) {
    throw new Error(
      "[PettyUI] Popover parts must be used inside <Popover>.\n" +
        "  Fix: Wrap your Popover.Content, Popover.Trigger, etc. inside <Popover>.\n" +
        "  Docs: https://pettyui.dev/components/popover#composition",
    );
  }
  return ctx;
}

/** @internal Provider for the internal Popover context. */
export const InternalPopoverContextProvider = InternalPopoverContext.Provider;

// ─── Public Context (exported via Popover.useContext) ───────────────────────

/** Public context exposed to consumers via Popover.useContext(). */
export interface PopoverContextValue {
  /** Whether the popover is currently open. */
  open: Accessor<boolean>;
  /** Whether the popover renders as a modal (traps focus, locks scroll). */
  modal: Accessor<boolean>;
}

const PopoverPublicContext = createContext<PopoverContextValue>();

/**
 * Returns the public Popover context value.
 * Throws if used outside of a Popover root.
 */
export function usePopoverContext(): PopoverContextValue {
  const ctx = useContext(PopoverPublicContext);
  if (!ctx) {
    throw new Error(
      "[PettyUI] Popover.useContext() was called outside of a <Popover>.\n" +
        "  Fix: Call Popover.useContext() inside a component rendered within <Popover>.\n" +
        "  Docs: https://pettyui.dev/components/popover#context",
    );
  }
  return ctx;
}

/** @internal Provider for the public Popover context. */
export const PopoverPublicContextProvider = PopoverPublicContext.Provider;
