// Reference implementation: packages/shadcn/ui/switch/switch.marko
// Guide: /docs/creating-components · Authoring rules: v2 pattern
import * as qrCodeMachine from "@zag-js/qr-code";
import type { MachineInput } from "marko-zag";
import { cn } from "#lib/utils.ts";
import { stripOwnProps } from "#lib/native-attrs.ts";
import { qrCodeVariants, qrCodePixelSizeBySize, type QrCodeVariants } from "./variants.ts";
import { qrCode as styles } from "./classes.ts";

// `size` is chrome-only sugar: it sets the box (variants.ts) AND feeds the
// machine's own `pixelSize` prop (module size in px) unless the caller
// passes `pixelSize` explicitly, which always wins.
export type Input = MachineInput<"div", qrCodeMachine.Props> &
  QrCodeVariants & {
    /** Rendered centered over the code (logo overlay slot). */
    overlay?: Marko.AttrTag<{ content: Marko.Body }>;
    valueChange?: (value: string) => void;
  };

// <zag> wires the machine in one tag and returns `api` as a GETTER —
// call it at every use site. Getters are the serializable currency of
// Marko's resumability: the api object itself must never become reactive
// state. See /docs/creating-components.
<zag/api=() => qrCodeMachine from=input
  pixelSize=input.pixelSize ?? qrCodePixelSizeBySize[input.size ?? "default"]
/>

// Whatever is neither machine-owned (splitProps) nor component-owned
// (class, size, overlay, valueChange) passes through to the root div.
<const/nativeAttrs=() =>
  stripOwnProps(
    qrCodeMachine.splitProps(input)[1],
    "class",
    "size",
    "overlay",
    "valueChange",
    // `pixelSize` is a machine prop, so `splitProps` has already removed it
    // from this leftover object — stripping it again is a no-op and, since it
    // is not a key of the remaining type, a type error.
  )
>

<div
  ...nativeAttrs()
  ...api().getRootProps()
  data-slot="qr-code"
  class=cn(qrCodeVariants({ size: input.size }), input.class)
>
  <svg ...api().getFrameProps() data-slot="qr-code-frame" class=styles.frame>
    <path ...api().getPatternProps() data-slot="qr-code-pattern" class=styles.pattern/>
  </svg>
  <if=input.overlay>
    <div
      ...api().getOverlayProps()
      data-slot="qr-code-overlay"
      class=styles.overlay
    >
      <${input.overlay.content}/>
    </div>
  </if>
</div>

// Parents can receive the api getter: <QrCode/qrCodeApi/> then
// `qrCodeApi().getDataUrl("image/png")` — it stays live across machine
// updates. Used by the download demo to build a downloadable data URL.
<return=api>
