import * as hoverCardMachine from "@zag-js/hover-card";
import type { MachineInput } from "marko-zag";
import { positionerStyle } from "marko-zag";
import { cn } from "#lib/utils.ts";
import { hoverCard as styles } from "./classes.ts";

// MachineInput = native <span> attributes ∩ the machine's full Props, with
// `id` made optional (generated below, overridable). `openChange` is
// additive sugar enabling Marko's two-way bind shorthand
// (<HoverCard open:=myState/>); Zag's own `onOpenChange` also works and
// receives the details object.
export type Input = MachineInput<"span", hoverCardMachine.Props> & {
  /** Trigger render-prop — typically a link. */
  trigger: Marko.AttrTag<{ content: Marko.Body<[Record<string, unknown>]> }>;
  /** Card content shown when open. */
  content: Marko.Body;
  /** Extra class for the content panel. */
  class?: string;
  /** Fires when the open state changes; receives the plain open value. */
  openChange?: (open: boolean) => void;
};

<zag/api=() => hoverCardMachine from=input/>

<span data-slot="hover-card">
  <${input.trigger.content}({ ...api().getTriggerProps(), "data-slot": "hover-card-trigger" })/>
</span>
// NOTE: upstream shadcn sets data-slot="hover-card-portal" on Radix's Portal,
// which renders a real element. marko-zag's <zag-portal> renders a
// `display:contents` host and does not forward attributes, so the
// marker never reached the DOM — it was inert, and nothing in this
// repo's CSS, tests or tooling reads it. Dropped rather than left as
// dead markup; restore it if <zag-portal> gains attribute forwarding.
// The portal lives OUTSIDE the span root: its host element is not valid
// phrasing content inside <span> (html-validate element-permitted-content),
// and the positioned content does not care about its DOM parent.
<zag-portal>
  <if=api().open>
    <div ...api().getPositionerProps() style=positionerStyle data-slot="hover-card-positioner">
      <div
        ...api().getContentProps()
        data-slot="hover-card-content"
        class=cn(styles.content, input.class)
      >
        <${input.content}/>
      </div>
    </div>
  </if>
</zag-portal>

<return=api>
