// Guide: /docs/creating-components · adapter internals: /docs/zag-adapter
// Authoring rules: notes/component-authoring.md (v2 pattern)
import * as ratingGroupMachine from "@zag-js/rating-group";
import type { MachineInput } from "marko-zag";
import { cn } from "#lib/utils.ts";
import { stripOwnProps } from "#lib/native-attrs.ts";
import { ratingGroup as styles } from "./classes.ts";

// MachineInput = native <div> attributes ∩ the machine's full Props, with
// `id` made optional (generated below, overridable). `valueChange` is
// additive sugar enabling Marko's two-way bind shorthand
// (<RatingGroup value:=myState/>); Zag's own `onValueChange` also works and
// receives the details object.
export type Input = MachineInput<"div", ratingGroupMachine.Props> & {
  label?: string;
  valueChange?: (value: number) => 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=() => ratingGroupMachine from=input/>

// Whatever is neither machine-owned (splitProps) nor component-owned
// (class, valueChange) passes through to the root div.
<const/nativeAttrs=() =>
  stripOwnProps(
    ratingGroupMachine.splitProps(input)[1],
    "class",
    "label",
    "valueChange",
  )
>

<div ...nativeAttrs() ...api().getRootProps() data-slot="rating-group" class=cn(styles.root, input.class)>
  <if=input.label>
    <label ...api().getLabelProps() data-slot="rating-group-label" class=styles.label>
      ${input.label}
    </label>
  </if>
  <div ...api().getControlProps() data-slot="rating-group-control" class=styles.control>
    <for|index| of=api().items>
      <const/itemState=api().getItemState({ index })/>
      <span
        ...api().getItemProps({ index })
        data-slot="rating-group-item"
        class=styles.item
      >
        <if=itemState.half>
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class=styles.halfIcon>
            <defs>
              <clipPath id=`rating-half-${index}`>
                <rect x="0" y="0" width="12" height="24"/>
              </clipPath>
            </defs>
            <path clip-path=`url(#rating-half-${index})` fill="currentColor" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round" d="M12 2.5 15.09 9 22 10l-5 5.14L18.18 22 12 18.5 5.82 22 7 15.14 2 10l6.91-1z"/>
          </svg>
        </if>
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill=(itemState.highlighted && !itemState.half) ? "currentColor" : "none" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round" class=itemState.highlighted && styles.iconHighlighted>
          <path d="M12 2.5 15.09 9 22 10l-5 5.14L18.18 22 12 18.5 5.82 22 7 15.14 2 10l6.91-1z"/>
        </svg>
      </span>
    </for>
  </div>
  <input type="text" ...api().getHiddenInputProps()>
</div>

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