/**
 * `<tags-input-ui>` — Free-form token input — type a value, press Enter (or the configured
delimiter) to commit it as a chip; Backspace from the empty inline
input removes the last chip. Distinct from <select-ui multiple>
(SPEC-040), which is constrained to a fixed option list — tags-input
is for OPEN sets (labels, email recipients, keyword inputs). Per
ADR-0025 the inline editor is a contenteditable surface (NO native
`<input>` wrap). Form-bearing via UIFormElement + ElementInternals:
the form value is a JSON-serialized string array under `[name]`.
Each rendered chip is a `<tag-ui removable>`; the `remove` event
delegates back to the host. Optional autocompletion: when
`.suggestions` is non-empty, a popover renders below the field and
the host announces as a combobox per WAI-APG.

 *
 * @see https://ui-kit.exe.xyz/site/components/tags-input
 *
 * Type declarations generated by scripts/build/dts-codegen.mjs from
 * the component's `.a2ui.json` sidecar(s). Edit the source `.yaml`,
 * run `npm run build:components`, then `npm run codegen:dts` to
 * regenerate; or hand-author this file fully if rich event types are
 * needed beyond what the yaml `events:` block can express.
 */

import { UIElement } from '../../core/element.js';

export interface TagsInputChangeEventDetail {
  /** Tokens added by this change (`[]` when only removals occurred). */
  added: unknown[];
  /** Tokens removed by this change (`[]` when only additions occurred). */
  removed: unknown[];
  /** Current token list (string array). */
  value: unknown[];
}

export type TagsInputChangeEvent = CustomEvent<TagsInputChangeEventDetail>;
export interface TagsInputCommitEventDetail {
  /** True unless the consumer calls `preventDefault()`. */
  accepted: boolean;
  /** Candidate token text (post-transform). */
  value: string;
}

export type TagsInputCommitEvent = CustomEvent<TagsInputCommitEventDetail>;
export interface TagsInputInputEventDetail {
  /** Current typed text in the inline input. */
  query: string;
}

export type TagsInputInputEvent = CustomEvent<TagsInputInputEventDetail>;
export interface TagsInputInvalidEventDetail {
  /** One of `duplicate` / `too-short` / `too-long` / `validator` / `max`. */
  reason: string;
  /** Rejected token text. */
  value: string;
}

export type TagsInputInvalidEvent = CustomEvent<TagsInputInvalidEventDetail>;

export class UITagsInput extends UIElement {
  /** Required for form validation. Empty array fails `:invalid`. */
  required: boolean;
  /** Inline character that commits the typed value as a chip. The
sentinel `enter` disables in-line commit — only the Enter key
(or programmatic `addToken`) commits. Default is `,`. */
  delimiter: string;
  /** Block all interaction; dim the field. */
  disabled: boolean;
  /** Maximum number of tokens. `0` (default) means unlimited. */
  max: number;
  /** Maximum per-token character count. `0` (default) means unlimited. */
  maxLength: number;
  /** Minimum required tokens for form validity. */
  min: number;
  /** Minimum per-token character count after `transform` is applied. */
  minLength: number;
  /** Form field name. Serializes the token list as JSON under this key. */
  name: string;
  /** Regex character-class fragment matched against pasted text to
split it into multiple tokens. Default `,\n` splits on commas
and newlines. Use `""` to disable paste-splitting entirely. */
  pasteSplit: string;
  /** Placeholder text for the inline input when no chips are committed. */
  placeholder: string;
  /** Block edits; allow inspection (chips render without remove buttons). */
  readonly: boolean;
  /** Sizing scale via universal `[size]` attribute system. Matches
Input + Combobox sizing tokens so a TagsInput rendered alongside
either feels coherent in a form row. */
  size: 'sm' | 'md' | 'lg';
  /** Optional autocomplete strings rendered in a popover below the
field. Suggestions are hints, not gates — the typed value still
wins on commit. JS property only (array reflection skipped). */
  suggestions: string;
  /** Normalize tokens on commit. `lowercase` lowercases, `trim` strips
leading + trailing whitespace, `strip-spaces` removes all
whitespace, `""` (default) preserves the typed value. */
  transform: '' | 'lowercase' | 'trim' | 'strip-spaces';
  /** Reject duplicate tokens silently (no `invalid` event for accidental dups). */
  unique: boolean;
  /** Per-token validator. Sync `(value, index) => boolean` rejects
false synchronously; async `(value, index) => Promise<boolean>`
flips the host into `[validating]` while pending. JS property
only — not serializable in A2UI JSON; wire post-mount. */
  validateFn: Record<string, unknown>;
  /** Current token list (string array). Setting `.value = ['a','b']`
replaces the rendered chips. Reflection skipped — array values
do not round-trip through attribute strings. */
  value: string;

  addEventListener<K extends keyof HTMLElementEventMap>(
    type: K,
    listener: (this: UITagsInput, ev: HTMLElementEventMap[K]) => unknown,
    options?: boolean | AddEventListenerOptions,
  ): void;
  addEventListener(type: 'change', listener: (ev: TagsInputChangeEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
  addEventListener(type: 'commit', listener: (ev: TagsInputCommitEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
  addEventListener(type: 'input', listener: (ev: TagsInputInputEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
  addEventListener(type: 'invalid', listener: (ev: TagsInputInvalidEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
}
