/* ============================================================
   <HoverCard /> — open-on-hover floating preview card.
   Spring entry, configurable side/align/offset, open/close delay.

   Usage:
     <HoverCard openDelay={150} closeDelay={120}>
       <HoverCardTrigger asChild>
         <a href="…">Hover me</a>
       </HoverCardTrigger>
       <HoverCardContent side="bottom" align="center">
         …
       </HoverCardContent>
     </HoverCard>
   ============================================================ */

const HoverCardCtx = React.createContext(null);

function HoverCard({ children, openDelay = 180, closeDelay = 140, className = "" }) {
  const [open, setOpen] = React.useState(false);
  const openTimer  = React.useRef(null);
  const closeTimer = React.useRef(null);
  const wrapRef    = React.useRef(null);

  const cancel = () => {
    if (openTimer.current)  { clearTimeout(openTimer.current);  openTimer.current  = null; }
    if (closeTimer.current) { clearTimeout(closeTimer.current); closeTimer.current = null; }
  };

  const handleEnter = () => {
    cancel();
    openTimer.current = setTimeout(() => setOpen(true), openDelay);
  };

  const handleLeave = () => {
    cancel();
    closeTimer.current = setTimeout(() => setOpen(false), closeDelay);
  };

  React.useEffect(() => () => cancel(), []);

  const ctx = React.useMemo(() => ({
    open, handleEnter, handleLeave,
  }), [open]);

  return (
    <HoverCardCtx.Provider value={ctx}>
      <span
        ref={wrapRef}
        className={`hover-card ${open ? "is-open" : ""} ${className}`}
        onMouseEnter={handleEnter}
        onMouseLeave={handleLeave}
        onFocus={handleEnter}
        onBlur={handleLeave}
      >
        {children}
      </span>
    </HoverCardCtx.Provider>
  );
}

function HoverCardTrigger({ children, asChild = false, ...rest }) {
  const ctx = React.useContext(HoverCardCtx);
  if (asChild && React.isValidElement(children)) {
    // Merge the child's existing handlers with ours.
    const child = children;
    return React.cloneElement(child, {
      ...rest,
      onMouseEnter: (e) => { ctx?.handleEnter(); child.props.onMouseEnter?.(e); },
      onMouseLeave: (e) => { ctx?.handleLeave(); child.props.onMouseLeave?.(e); },
      onFocus:      (e) => { ctx?.handleEnter(); child.props.onFocus?.(e); },
      onBlur:       (e) => { ctx?.handleLeave(); child.props.onBlur?.(e); },
      "aria-expanded": ctx?.open ?? false,
    });
  }
  return <span className="hover-card__trigger" {...rest}>{children}</span>;
}

function HoverCardContent({
  children,
  side = "bottom",
  align = "center",
  sideOffset = 12,
  className = "",
}) {
  const ctx = React.useContext(HoverCardCtx);
  const open = ctx?.open ?? false;

  return (
    <div
      className={`hover-card__content ${open ? "is-open" : ""} ${className}`}
      data-side={side}
      data-align={align}
      style={{ "--hc-offset": `${sideOffset}px` }}
      aria-hidden={!open}
      role="dialog"
    >
      <div className="hover-card__arrow" data-side={side} aria-hidden="true"></div>
      <div className="hover-card__inner">{children}</div>
    </div>
  );
}

Object.assign(window, { HoverCard, HoverCardTrigger, HoverCardContent });
