import { Alepha, Static, TArray, TObject, TSchema, TypeBoxError } from "alepha";
import { InputHTMLAttributes, ReactNode } from "react";
//#region ../../src/react/form/services/FormModel.d.ts
/**
 * FormModel is a dynamic form handler that generates form inputs based on a provided TypeBox schema.
 * It manages form state, handles input changes, and processes form submissions with validation.
 *
 * It means to be injected and used within React components to provide a structured way to create and manage forms.
 *
 * @see {@link useForm}
 */
declare class FormModel<T extends TObject> {
  readonly id: string;
  readonly options: FormCtrlOptions<T>;
  protected readonly log: import("alepha/logger").Logger;
  protected readonly alepha: Alepha;
  protected readonly values: Record<string, any>;
  protected readonly initialValues: Record<string, any>;
  protected submitInProgress: boolean;
  input: SchemaToInput<T>;
  constructor(id: string, options: FormCtrlOptions<T>);
  /**
   * Extract default values from a zod object schema.
   * Recursively handles nested objects, unwrapping optional/nullable/default.
   */
  protected extractSchemaDefaults(schema: TObject, prefix?: string): Record<string, any>;
  get currentValues(): Record<string, any>;
  get props(): {
    id: string;
    noValidate: boolean;
    onSubmit: (ev?: FormEventLike) => void;
    onReset: (event: FormEventLike) => void;
  };
  readonly setInitialValues: (values: Record<string, any>) => void;
  readonly reset: (event?: FormEventLike) => void;
  readonly submit: () => Promise<void>;
  /**
   * Restructures flat keys like "address.city" into nested objects like { address: { city: ... } }
   * Values are already typed from onChange, so no conversion is needed.
   */
  protected restructureValues(store: Record<string, any>): Record<string, any>;
  /**
   * Helper to restructure a flat key like "address.city" into nested object structure.
   * The value is already typed, so we just assign it to the nested path.
   */
  protected restructureNestedValue(values: Record<string, any>, key: string, value: any): void;
  protected createProxyFromSchema<T extends TObject>(options: FormCtrlOptions<T>, schema: TSchema, context: {
    parent: string;
    store: Record<string, any>;
  }): SchemaToInput<T>;
  protected createInputFromSchema<T extends TObject>(name: keyof Static<T> & string, options: FormCtrlOptions<T>, schema: TObject, required: boolean, context: {
    parent: string;
    store: Record<string, any>;
  }): BaseInputField;
  /**
   * Convert an input value to the correct type based on the schema.
   * Handles raw DOM values (strings, booleans from checkboxes, Files, etc.)
   */
  protected getValueFromInput(input: any, schema: TSchema): any;
}
type SchemaToInput<T extends TObject> = { [K in keyof T["properties"]]: InputField<T["properties"][K]>; };
interface FormEventLike {
  preventDefault?: () => void;
  stopPropagation?: () => void;
}
type InputField<T extends TSchema> = T extends TObject ? ObjectInputField<T> : T extends TArray<infer U> ? ArrayInputField<U> : BaseInputField;
interface BaseInputField {
  path: string;
  required: boolean;
  initialValue: any;
  props: InputHTMLAttributesLike;
  schema: TSchema;
  set: (value: any) => void;
  form: FormModel<any>;
  items?: any;
}
interface ObjectInputField<T extends TObject> extends BaseInputField {
  items: SchemaToInput<T>;
}
interface ArrayInputField<T extends TSchema> extends BaseInputField {
  items: Array<InputField<T>>;
}
type InputHTMLAttributesLike = Pick<InputHTMLAttributes<unknown>, "id" | "name" | "type" | "value" | "required" | "maxLength" | "minLength" | "aria-label"> & {
  value?: any;
};
type FormCtrlOptions<T extends TObject> = {
  /**
   * The schema defining the structure and validation rules for the form.
   * This should be a TypeBox schema object.
   */
  schema: T;
  /**
   * Callback function to handle form submission.
   * This function will receive the parsed and validated form values.
   */
  handler: (values: Static<T>) => unknown;
  /**
   * Optional initial values for the form fields.
   * This can be used to pre-populate the form with existing data.
   */
  initialValues?: Partial<Static<T>>;
  /**
   * Optional function to create custom field attributes.
   * This can be used to add custom validation, styles, or other attributes.
   */
  onCreateField?: (name: keyof Static<T> & string, schema: TSchema) => InputHTMLAttributes<unknown>;
  /**
   * If defined, this will generate a unique ID for each field, prefixed with this string.
   *
   * > "username" with id="form-123" will become "form-123-username".
   *
   * If omitted, IDs will not be generated.
   */
  id?: string;
  onError?: (error: Error) => void;
  onChange?: (key: string, value: any, store: Record<string, any>) => void;
  onReset?: () => void;
};
//#endregion
//#region ../../src/react/form/components/FormState.d.ts
declare const FormState: <T extends TObject>(props: {
  form: FormModel<T>;
  children: (state: {
    loading: boolean;
    dirty: boolean;
  }) => ReactNode;
}) => ReactNode;
//#endregion
//#region ../../src/react/form/errors/FormValidationError.d.ts
declare class FormValidationError extends TypeBoxError {
  readonly name = "ValidationError";
  constructor(options: {
    message: string;
    path: string;
  });
}
//#endregion
//#region ../../src/react/form/hooks/useFieldValue.d.ts
/**
 * Hook to subscribe to a single form field's value.
 * Only re-renders when this specific field changes.
 *
 * @returns A tuple of [value, setValue] similar to useState.
 */
declare const useFieldValue: (input: BaseInputField) => [any, (value: any) => void];
//#endregion
//#region ../../src/react/form/hooks/useForm.d.ts
declare const useForm: <T extends TObject>(options: FormCtrlOptions<T>, deps?: any[]) => FormModel<T>;
//#endregion
//#region ../../src/react/form/hooks/useFormQuerySync.d.ts
interface UseFormQuerySyncOptions<TKey extends string> {
  /**
   * Form field keys to mirror to/from the URL query. Fields not listed
   * here stay local to the form and never leak into the address bar.
   */
  keys: readonly TKey[];
}
/**
 * Two-way bind a `useForm` instance to the URL query params, keyed
 * per-field (so the URL stays human-readable: `?status=new&zone=ops`).
 *
 * Direction 1 — URL → form:
 * - On mount AND every time one of the watched query keys changes
 *   (typically via browser back/forward or external `router.push`),
 *   call `form.input[key].set(value)` for each listed key. Missing /
 *   empty params clear the field (set to `undefined`).
 *
 * Direction 2 — form → URL:
 * - Subscribe to the form's `form:change` event for the listed keys.
 *   Each emission writes the current values for all listed keys to the
 *   URL via `router.setQueryParams` (replace-state, no history spam).
 *   Empty values (`undefined` / `""`) are stripped from the URL so the
 *   address bar stays clean.
 *
 * Replaces ad-hoc `localStorage` filter persistence: the URL becomes
 * the canonical store, so the view is shareable via copy-paste and
 * navigable via back/forward.
 *
 * @example
 * const form = useForm({ schema: z.object({ status: z.string(), q: z.string() }) });
 * useFormQuerySync(form, { keys: ["status", "q"] });
 */
declare const useFormQuerySync: <T extends TObject, TKey extends string>(form: FormModel<T>, options: UseFormQuerySyncOptions<TKey>) => void;
//#endregion
//#region ../../src/react/form/hooks/useFormState.d.ts
interface UseFormStateReturn {
  loading: boolean;
  dirty: boolean;
  values?: Record<string, any>;
  error?: Error;
}
declare const useFormState: <T extends TObject, Keys extends keyof UseFormStateReturn>(target: FormModel<T> | {
  form: FormModel<T>;
  path: string;
}, _events?: Keys[]) => Pick<UseFormStateReturn, Keys>;
//#endregion
//#region ../../src/react/form/hooks/useFormValues.d.ts
/**
 * Hook to subscribe to all form values.
 * Re-renders on every field change — use only when needed (debug panels, live previews).
 */
declare const useFormValues: <T extends TObject>(form: FormModel<T>) => Record<string, any>;
//#endregion
//#region ../../src/react/form/services/parseField.d.ts
/**
 * Semantic icon hint derived from schema metadata. UI layers map this
 * to their own icon set — this module is headless and ships no JSX.
 */
type IconHint = "email" | "password" | "phone" | "url" | "number" | "calendar" | "clock" | "list" | "text" | "user" | "file" | "switch";
interface FieldConstraints {
  minLength?: number;
  maxLength?: number;
  minimum?: number;
  maximum?: number;
  pattern?: string;
}
interface FieldMeta {
  id?: string;
  label: string;
  description?: string;
  error?: string;
  required: boolean;
  type?: string;
  format?: string;
  isEnum: boolean;
  isArray: boolean;
  isObject: boolean;
  isArrayOfObjects: boolean;
  enum?: readonly unknown[];
  iconHint?: IconHint;
  constraints: FieldConstraints;
  testId?: string;
  schema: TSchema;
  /**
   * Raw `$control` value from the schema, untyped here. The UI layer
   * (`alepha/react/ui`) provides the strict {@link SchemaControl} type and
   * a `resolveSchemaControl` helper to evaluate the function form.
   */
  control?: unknown;
}
interface ParseFieldOptions {
  label?: string;
  description?: string;
  error?: Error;
}
/**
 * Derives a {@link FieldMeta} from an `InputField` (from `useForm`) plus
 * optional overrides. Pure — no React, no JSX, no UI library coupling.
 *
 * UI components consume this metadata to render labels, descriptions,
 * error messages, icons, and validation constraints.
 */
declare const parseField: (input: BaseInputField, options?: ParseFieldOptions) => FieldMeta;
//#endregion
//#region ../../src/react/form/services/prettyName.d.ts
/**
 * Converts a path or identifier string into a pretty display name.
 * For paths like "/contacts/0/name", extracts just the field name "Name".
 * Handles camelCase and snake_case conversion to Title Case.
 *
 * @example
 * prettyName("/userName") // "User Name"
 * prettyName("/contacts/0/email") // "Email"
 * prettyName("/address/streetName") // "Street Name"
 * prettyName("first_name") // "First Name"
 */
declare const prettyName: (name: string) => string;
//#endregion
//#region ../../src/react/form/index.d.ts
declare module "alepha" {
  interface Hooks {
    "form:change": {
      id: string;
      path: string;
      value: any;
      /**
       * Programmatic reset (e.g. `setInitialValues` after the parent updates
       * its state). Subscribers tracking dirty state should ignore these.
       */
      initial?: boolean;
    };
    "form:submit:begin": {
      id: string;
    };
    "form:submit:success": {
      id: string;
      values: Record<string, any>;
    };
    "form:submit:error": {
      id: string;
      error: Error;
    };
    "form:submit:end": {
      id: string;
    };
    "form:reset": {
      id: string;
    };
  }
}
/**
 * Type-safe forms with validation.
 *
 * **Features:**
 * - Form state management
 * - TypeBox schema validation
 * - Field-level error handling
 * - Submit handling with loading state
 * - Form reset
 *
 * @module alepha.react.form
 */
declare const AlephaReactForm: import("alepha").Service<import("alepha").Module>;
//#endregion
export { AlephaReactForm, ArrayInputField, BaseInputField, FieldConstraints, FieldMeta, FormCtrlOptions, FormEventLike, FormModel, FormState, FormValidationError, IconHint, InputField, InputHTMLAttributesLike, ObjectInputField, ParseFieldOptions, SchemaToInput, UseFormQuerySyncOptions, UseFormStateReturn, parseField, prettyName, useFieldValue, useForm, useFormQuerySync, useFormState, useFormValues };
//# sourceMappingURL=index.d.ts.map