import * as editableMachine from "@zag-js/editable";
import type { MachineInput } from "marko-zag";
import Icon from "../icon/icon.marko";
import { cn } from "#lib/utils.ts";
import { stripOwnProps } from "#lib/native-attrs.ts";
import { editable as styles } from "./classes.ts";

export type Input = MachineInput<"input", editableMachine.Props> & {
  valueChange?: (value: string) => void;
  editChange?: (editing: boolean) => void;
  valueCommit?: (value: string) => void;
  valueRevert?: (value: string) => void;
  placeholder?: string | { edit: string; preview: string };
  trigger?: Marko.AttrTag<{ content: Marko.Body<[Record<string, unknown>]> }>;
};

<zag/api=() => editableMachine from=input
  onValueCommit(details: editableMachine.ValueChangeDetails) {
    input.onValueCommit?.(details);
    input.valueCommit?.(details.value);
  }
  onValueRevert(details: editableMachine.ValueChangeDetails) {
    input.onValueRevert?.(details);
    input.valueRevert?.(details.value);
  }
/>

<const/nativeAttrs=() =>
  stripOwnProps(
    editableMachine.splitProps(input)[1],
    "class",
    "valueChange",
    "editChange",
    "valueCommit",
    "valueRevert",
    "trigger",
  )
>

// Zag's aria-label="edit" on the preview span is inert naming on a role-less
// element (html-validate aria-label-misuse) — the preview's own text is its
// name. Strip it; Marko does not dedupe spread attrs.
<const/previewProps=() => {
  const props = api().getPreviewProps() as Record<string, unknown>;
  delete props["aria-label"];
  return props;
}/>

<div ...api().getRootProps() data-slot="editable-root" class=cn(styles.root, input.class)>
  <div ...api().getAreaProps() data-slot="editable-area" class=styles.area>
    <input
      ...nativeAttrs()
      ...api().getInputProps()
      type="text"
      data-slot="editable-input"
      class=styles.input
    />
    // Zag's aria-label="edit" on the preview span is inert naming on a
    // role-less element (html-validate aria-label-misuse) — the preview's
    // own text is its name. Strip it; Marko does not dedupe spread attrs.
    <span
      ...previewProps()
      data-slot="editable-preview"
      class=styles.preview
    >
      ${api().valueText}
    </span>
  </div>
  <div ...api().getControlProps() data-slot="editable-control" class=styles.control>
    <button
      ...api().getSubmitTriggerProps()
      data-slot="editable-submit-trigger"
      type="button"
      class=styles.submitTrigger
    >
      <Icon name="Check"/>
      <span class=styles.srOnly>Submit</span>
    </button>
    <button
      ...api().getCancelTriggerProps()
      data-slot="editable-cancel-trigger"
      type="button"
      class=styles.cancelTrigger
    >
      <Icon name="X"/>
      <span class=styles.srOnly>Cancel</span>
    </button>
    <if=input.trigger>
      <${input.trigger.content}({ ...api().getEditTriggerProps(), "data-slot": "editable-trigger" })/>
    </if>
    <else>
      <button
        ...api().getEditTriggerProps()
        data-slot="editable-edit-trigger"
        type="button"
        class=styles.editTrigger
      >
        <Icon name="PencilIcon"/>
        <span class=styles.srOnly>Edit</span>
      </button>
    </else>
  </div>
</div>

<return=api>
