// Reference implementation: packages/shadcn/ui/switch/switch.marko
// Guide: /docs/creating-components · Authoring rules: v2 pattern
import * as avatarMachine from "@zag-js/avatar";
import type { MachineInput } from "marko-zag";
import { cn } from "#lib/utils.ts";
import { stripOwnProps } from "#lib/native-attrs.ts";
import { avatar as styles } from "./classes.ts";

export type Input = MachineInput<"span", avatarMachine.Props> & {
  src?: string;
  alt?: string;
  fallback?: string;
  content?: Marko.Body;
  /** Renders an `AvatarBadge` (or any markup) as a root-level sibling of the image/fallback, per upstream's Composition tree — never inside the fallback span. */
  badge?: Marko.AttrTag<{ content: Marko.Body }>;
  statusChange?: (status: avatarMachine.LoadStatus) => void;
  /** Size variant — also exposed as `data-size` for group/badge styling. */
  size?: "default" | "sm" | "lg";
};

// <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=() => avatarMachine from=input/>

// Whatever is neither machine-owned (splitProps) nor component-owned
// (class, src, alt, fallback, content, statusChange, size) passes through
// to the root span: aria-*, data-*...
<const/nativeAttrs=() =>
  stripOwnProps(
    avatarMachine.splitProps(input)[1],
    "class",
    "src",
    "alt",
    "fallback",
    "content",
    "badge",
    "statusChange",
    "size",
  )
>
<const/size=(input.size ?? "default")>

<span
  data-slot="avatar"
  data-size=size
  ...nativeAttrs()
  ...api().getRootProps()
  class=cn(styles.root, input.class)
>
  <if=input.src>
    <img
      ...api().getImageProps()
      src=input.src
      alt=input.alt
      data-slot="avatar-image"
      class=styles.image
    />
  </if>
  <span
    ...api().getFallbackProps()
    data-slot="avatar-fallback"
    class=styles.fallback
  >
    <if=input.content>
      <${input.content}/>
    </if>
    <else>
      ${input.fallback}
    </else>
  </span>
  <if=input.badge>
    <${input.badge.content}/>
  </if>
</span>

// Parents can receive the api getter: <Avatar/avatarApi/> then
// `avatarApi().loaded` — it stays live across machine updates.
<return=api>
