import type { Accessor, JSX } from "solid-js";
import { createContext, useContext } from "solid-js";

/** Internal context shared between all HoverCard sub-components. */
export interface InternalHoverCardContextValue {
  isOpen: Accessor<boolean>;
  open: () => void;
  close: () => void;
  triggerRef: Accessor<HTMLElement | null>;
  setTriggerRef: (el: HTMLElement | null) => void;
  contentRef: Accessor<HTMLElement | null>;
  setContentRef: (el: HTMLElement | null) => void;
  contentId: string;
  triggerId: string;
  floatingStyle: Accessor<JSX.CSSProperties>;
  /** Open delay in ms. */
  openDelay: number;
  /** Close delay in ms. */
  closeDelay: number;
  /** Schedule open after openDelay. */
  scheduleOpen: () => void;
  /** Schedule close after closeDelay. */
  scheduleClose: () => void;
  /** Cancel any pending open/close timer. */
  cancelTimers: () => void;
}

const InternalHoverCardContext = createContext<InternalHoverCardContextValue>();

/**
 * Returns the internal HoverCard context. Throws if used outside HoverCard.
 */
export function useInternalHoverCardContext(): InternalHoverCardContextValue {
  const ctx = useContext(InternalHoverCardContext);
  if (!ctx) {
    throw new Error(
      "[PettyUI] HoverCard parts must be used inside <HoverCard>.\n" +
        "  Fix: <HoverCard>\n" +
        "         <HoverCard.Trigger>...</HoverCard.Trigger>\n" +
        "         <HoverCard.Content>...</HoverCard.Content>\n" +
        "       </HoverCard>",
    );
  }
  return ctx;
}

export const InternalHoverCardContextProvider = InternalHoverCardContext.Provider;

/** Public context exposed via HoverCard.useContext(). */
export interface HoverCardContextValue {
  /** Whether the hover card is open. */
  open: Accessor<boolean>;
}

const HoverCardPublicContext = createContext<HoverCardContextValue>();

/**
 * Returns the public HoverCard context. Throws if used outside HoverCard.
 */
export function useHoverCardContext(): HoverCardContextValue {
  const ctx = useContext(HoverCardPublicContext);
  if (!ctx) {
    throw new Error("[PettyUI] HoverCard.useContext() called outside of <HoverCard>.");
  }
  return ctx;
}

export const HoverCardPublicContextProvider = HoverCardPublicContext.Provider;
