export type FormSchemaDependency = {
  id: string;
  values?: (string | number | boolean)[];
};

/**
 * Fields shared by every `hb-form` JSON row and by serialized `schemaentry` passed to input-* hosts.
 */
export type FormSchemaEntryShared = {
  id: string;
  /**
   * Discriminator for `hb-form` rows (`row`, `text`, `number`, …). May be omitted on a standalone
   * `schemaentry` when implied by the host tag.
   */
  type?: string;
  label?: string;
  value?: unknown;
  dependencies?: FormSchemaDependency[];
  readonly?: boolean;
  disabled?: boolean;
  required?: boolean;
  validationRegex?: string;
  validationTip?: string;
  placeholder?: string;
  /**
   * For `type: "arraytags"` only: forwarded to `hb-input-array-tags` as the host `array_style`
   * attribute (`"pills"` | `"area"` string). When omitted, **`hb-form` defaults to `"area"`**.
   */
  array_style?: string;
  params?: Record<string, unknown>;
};

export type FormSchemaEntry = FormSchemaEntryShared & {
  type: string;
  params?: Record<string, unknown> & {
    columns?: FormSchemaEntry[];
  };
};

export type IComponentName =
  | "hb-input-select"
  | "hb-input-date"
  | "hb-input-datetime"
  | "hb-input-text"
  | "hb-input-file"
  | "hb-input-number"
  | "hb-input-email"
  | "hb-input-area"
  | "hb-input-checkbox"
  | "hb-input-color"
  | "hb-input-radio"
  | "hb-input-range"
  | "hb-input-array-objects"
  | "hb-input-array-tags"
  | "hb-input-coords";

export interface ISchemaOption {
  labelIsHandledByComponent?: boolean;
  row?: boolean;
}
export interface IComponent {
  options?: ISchemaOption;
  component?: IComponentName;
}
export interface IRegisterComponent {
  [k: string]: IComponent;
}
export interface IControl {
  entry: FormSchemaEntry;
  component?: IComponentName;
  options?: ISchemaOption;
  columns?: IControl[];
}

export type FormSchema = FormSchemaEntry[];

export type FormRendererProps = {
  schema: FormSchema;
};

/** Live / submitted values keyed by field id (plus metadata keys on dispatch payloads). */
export type FormValues = Record<string, unknown>;

export type Component = {
  id?: string;
  style?: string;
  /** From HTML: JSON string parsed in `$effect`; may be an object when set from JavaScript. */
  schema: string | FormSchema;

  values?: FormValues;

  isInvalid?: boolean;
  submitted?: "yes" | "no" | null;
  getvals?: "yes" | "no" | null;
  show_validation?: "yes" | "no";

  hide_submit?: boolean;
  /** When `"yes"`, the default submit control uses Bulma `is-outlined` (still `is-primary`). */
  buttons_outlined?: "yes" | "no" | string;
  i18nlang?: string;
};

/** `submit` / `getValues`: flat merge of `{ _valid }` and field ids → values. */
export type FormSubmitLikeDetail = { _valid: boolean } & FormValues;

export type Events = {
  /** Fired when validation fails after a submit attempt (including `submitted="yes"`). */
  submitinvalid: Record<string, never>;
  submit: FormSubmitLikeDetail;
  getValues: FormSubmitLikeDetail;
  update: { _valid: boolean; _id: string } & FormValues;
};
