import { Signal } from '@tempots/dom';
import { Path, PathSegment } from './path';
import { ControllerError, ControllerValidation } from './controller-validation';
import { ValidationMode } from './union-controller';
/**
 * Reactive form field controller that manages value, validation state, touched/dirty tracking, and disabled state.
 * Provides the foundation for type-safe form handling with fine-grained reactivity.
 *
 * @template T - The type of the value managed by this controller
 *
 * @example
 * ```typescript
 * import { prop } from '@tempots/dom'
 * import { Controller } from '@tempots/beatui'
 * import { Validation } from '@tempots/std'
 *
 * const valueSignal = prop('initial')
 * const statusSignal = prop(Validation.valid)
 * const disabledSignal = prop(false)
 *
 * const controller = new Controller(
 *   ['email'],
 *   (value) => { valueSignal.set(value) },
 *   valueSignal,
 *   statusSignal,
 *   { disabled: disabledSignal }
 * )
 *
 * // Access reactive properties
 * controller.signal.value // Current value
 * controller.hasError.value // Boolean error state
 * controller.touched.value // User interaction tracking
 * controller.dirty.value // Differs from baseline
 * ```
 */
export declare class Controller<T> {
    #private;
    /** The path segments identifying this controller's position in the form hierarchy (e.g., ['user', 'email']). */
    readonly path: Path;
    /** Callback to propagate value changes up to the parent form. */
    readonly change: (value: T) => void;
    /** Reactive signal containing the current field value. */
    readonly signal: Signal<T>;
    /** Reactive signal containing the current validation state (valid, pending, or invalid with errors). */
    readonly status: Signal<ControllerValidation>;
    /** Reactive signal containing the current error message string, or undefined if valid. */
    readonly error: Signal<undefined | string>;
    /** Reactive signal indicating whether this field has any errors. */
    readonly hasError: Signal<boolean>;
    /** Reactive signal tracking whether the user has interacted with this field. */
    readonly touched: Signal<boolean>;
    /** Reactive signal indicating whether errors should be shown (respects validation mode and touched state). */
    readonly errorVisible: Signal<boolean>;
    /** Reactive signal tracking whether the current value differs from the baseline. */
    readonly dirty: Signal<boolean>;
    /** Reactive signal containing nested field errors for child controllers. */
    readonly dependencyErrors: Signal<undefined | Record<string | number, ControllerError>>;
    /** Parent controller context providing disabled state and optional validation mode. */
    protected readonly parent: {
        disabled: Signal<boolean>;
        validationMode?: Signal<ValidationMode>;
    };
    /** Reactive signal indicating whether this field is disabled (combines local and parent disabled state). */
    readonly disabled: Signal<boolean>;
    /** Reactive signal indicating whether this field is disabled OR has errors (useful for submit button state). */
    readonly disabledOrHasErrors: Signal<boolean>;
    /**
     * Creates a new Controller instance.
     *
     * @param path - Field path segments in the form hierarchy
     * @param change - Callback to propagate value changes
     * @param signal - Reactive signal holding the field value
     * @param status - Reactive signal holding validation state
     * @param parent - Parent context with disabled state and optional validation mode
     * @param equals - Equality function for dirty tracking (defaults to strictEqual)
     */
    constructor(path: Path, change: (value: T) => void, signal: Signal<T>, status: Signal<ControllerValidation>, parent: {
        disabled: Signal<boolean>;
        validationMode?: Signal<ValidationMode>;
    }, equals?: (a: T, b: T) => boolean);
    /**
     * Returns the field name as a dot-separated string (e.g., "user.email").
     */
    get name(): string;
    /**
     * Registers a callback to be executed when this controller is disposed.
     *
     * @param callback - Function to execute on disposal
     */
    readonly onDispose: (callback: () => void) => void;
    /**
     * Disposes all internal resources and registered callbacks.
     * Should be called when the controller is no longer needed to prevent memory leaks.
     */
    readonly dispose: () => void;
    /**
     * Sets the disabled state for this field.
     *
     * @param disabled - Whether the field should be disabled
     */
    readonly setDisabled: (disabled: boolean) => void;
    /**
     * Disables this field.
     */
    readonly disable: () => void;
    /**
     * Enables this field.
     */
    readonly enable: () => void;
    /**
     * Marks this field as touched (user has interacted with it).
     */
    readonly markTouched: () => void;
    /**
     * Resets the touched state to false.
     */
    readonly resetTouched: () => void;
    /**
     * Marks the current value as the new baseline for dirty tracking.
     */
    readonly markPristine: () => void;
    /**
     * Resets the field value to the baseline value.
     */
    readonly reset: () => void;
    /**
     * Casts this controller to an ArrayController for managing array values.
     *
     * @param equals - Equality function for array comparison (defaults to strictEqual)
     * @returns An ArrayController instance
     */
    readonly array: (equals?: (a: T, b: T) => boolean) => ArrayController<T extends any[] ? T : never>;
    /**
     * Casts this controller to an ObjectController for managing object values with field access.
     *
     * @param equals - Equality function for object comparison (defaults to strictEqual)
     * @returns An ObjectController instance
     */
    readonly object: (equals?: (a: T, b: T) => boolean) => ObjectController<T extends Record<string, any> ? T : never>;
    /**
     * Creates a transformed controller that maps values bidirectionally.
     * Useful for converting between internal and display representations.
     *
     * @template Out - The transformed value type
     * @param transform - Function to convert from T to Out
     * @param untransform - Function to convert from Out back to T
     * @param subpath - Optional path segments to append
     * @param equals - Equality function for the transformed type
     * @returns A new Controller instance managing the transformed value
     *
     * @example
     * ```typescript
     * // Transform number to string for text input
     * const stringController = numberController.transform(
     *   (n) => n.toString(),
     *   (s) => parseFloat(s) || 0
     * )
     * ```
     */
    readonly transform: <Out>(transform: (value: T) => Out, untransform: (value: Out) => T, subpath?: PathSegment[], equals?: (a: Out, b: Out) => boolean) => Controller<Out>;
    /**
     * Creates a transformed controller with async bidirectional mapping.
     * Useful for async operations like fetching related data or formatting.
     *
     * @template Out - The transformed value type
     * @param transform - Async function to convert from T to Out
     * @param untransform - Async function to convert from Out back to T
     * @param alt - Fallback value while async transform is pending
     * @param subpath - Optional path segments to append
     * @param equals - Equality function for the transformed type
     * @returns A new Controller instance managing the async-transformed value
     */
    readonly asyncTransform: <Out>(transform: (value: T) => Promise<Out>, untransform: (value: Out) => Promise<T>, alt: Out, subpath?: PathSegment[], equals?: (a: Out, b: Out) => boolean) => Controller<Out>;
}
/**
 * Controller specialized for object values that provides field-level access via the `.field()` method.
 * Automatically tracks deep touched and dirty states by monitoring all child field controllers.
 *
 * @template T - The object type managed by this controller
 *
 * @example
 * ```typescript
 * import { prop } from '@tempots/dom'
 * import { ObjectController } from '@tempots/beatui'
 * import { Validation } from '@tempots/std'
 *
 * const valueSignal = prop({ email: '', password: '' })
 * const statusSignal = prop(Validation.valid)
 * const disabledSignal = prop(false)
 *
 * const controller = new ObjectController(
 *   [],
 *   (value) => { valueSignal.set(value) },
 *   valueSignal,
 *   statusSignal,
 *   { disabled: disabledSignal }
 * )
 *
 * // Access field controllers
 * const emailController = controller.field('email')
 * const passwordController = controller.field('password')
 *
 * // Deep state tracking
 * controller.touchedDeep.value // True if any field is touched
 * controller.dirtyDeep.value // True if any field is dirty
 * ```
 */
export declare class ObjectController<T extends object> extends Controller<T> {
    #private;
    /** Reactive signal indicating whether this field or any child field is touched. */
    readonly touchedDeep: Signal<boolean>;
    /** Reactive signal indicating whether this field or any child field is dirty. */
    readonly dirtyDeep: Signal<boolean>;
    constructor(path: Path, change: (value: T) => void, signal: Signal<T>, status: Signal<ControllerValidation>, parent: {
        disabled: Signal<boolean>;
    }, equals: (a: T, b: T) => boolean);
    /**
     * Gets or creates a controller for a specific field in the object.
     * Controllers are cached and reused for the same field name.
     *
     * @template K - The field key type
     * @param field - The field name to access
     * @returns A Controller instance for the specified field
     *
     * @example
     * ```typescript
     * const emailController = userController.field('email')
     * const nameController = userController.field('name')
     * ```
     */
    readonly field: <K extends keyof T & string>(field: K) => Controller<T[K]>;
    /**
     * Marks this field and all child fields as touched recursively.
     * Useful for showing all validation errors when a form is submitted.
     */
    readonly markAllTouched: () => void;
    /**
     * Marks this field and all child fields as pristine (resets baseline) recursively.
     */
    readonly markAllPristine: () => void;
}
/**
 * Controller specialized for array values that provides item-level access and array manipulation methods.
 * Automatically tracks deep touched and dirty states by monitoring all child item controllers.
 *
 * @template T - The array type managed by this controller
 *
 * @example
 * ```typescript
 * import { prop } from '@tempots/dom'
 * import { ArrayController } from '@tempots/beatui'
 * import { Validation } from '@tempots/std'
 *
 * const valueSignal = prop(['task 1', 'task 2'])
 * const statusSignal = prop(Validation.valid)
 * const disabledSignal = prop(false)
 *
 * const controller = new ArrayController(
 *   [],
 *   (value) => { valueSignal.set(value) },
 *   valueSignal,
 *   statusSignal,
 *   { disabled: disabledSignal }
 * )
 *
 * // Access item controllers
 * const firstItemController = controller.item(0)
 *
 * // Array operations
 * controller.push('new task')
 * controller.removeAt(1)
 * controller.move(0, 2) // Move first item to third position
 * controller.length.value // Reactive array length
 * ```
 */
export declare class ArrayController<T extends unknown[]> extends Controller<T> {
    #private;
    /** Reactive signal containing the current array length. */
    readonly length: Signal<number>;
    /** Reactive signal indicating whether this array or any item is touched. */
    readonly touchedDeep: Signal<boolean>;
    /** Reactive signal indicating whether this array or any item is dirty. */
    readonly dirtyDeep: Signal<boolean>;
    constructor(path: Path, change: (value: T) => void, signal: Signal<T>, status: Signal<ControllerValidation>, parent: {
        disabled: Signal<boolean>;
    }, equals: (a: T, b: T) => boolean);
    /**
     * Gets or creates a controller for a specific array item by index.
     * Controllers are cached and reused for the same index.
     *
     * @param index - The zero-based index of the item
     * @returns A Controller instance for the specified item
     *
     * @example
     * ```typescript
     * const firstTaskController = tasksController.item(0)
     * const secondTaskController = tasksController.item(1)
     * ```
     */
    readonly item: (index: number) => Controller<T[number]>;
    /**
     * Appends one or more items to the end of the array.
     *
     * @param value - Items to append
     */
    readonly push: (...value: T[number][]) => void;
    /**
     * Removes the last item from the array.
     */
    readonly pop: () => void;
    /**
     * Removes the first item from the array.
     */
    readonly shift: () => void;
    /**
     * Inserts one or more items at the beginning of the array.
     *
     * @param value - Items to prepend
     */
    readonly unshift: (...value: T) => void;
    /**
     * Removes the item at the specified index.
     *
     * @param index - Zero-based index of the item to remove
     */
    readonly removeAt: (index: number) => void;
    /**
     * Removes items from the array starting at the specified index.
     *
     * @param start - Zero-based index to start removing items
     * @param deleteCount - Number of items to remove (optional)
     */
    readonly splice: (start: number, deleteCount?: number) => void;
    /**
     * Moves one or more items from one index to another within the array.
     *
     * @param from - Source index to move from
     * @param to - Destination index to move to
     * @param length - Number of items to move (defaults to 1)
     *
     * @example
     * ```typescript
     * controller.move(0, 2) // Move first item to third position
     * controller.move(2, 0, 2) // Move items at index 2-3 to the beginning
     * ```
     */
    readonly move: (from: number, to: number, length?: number) => void;
    /**
     * Marks this array and all item controllers as touched recursively.
     * Useful for showing all validation errors when a form is submitted.
     */
    readonly markAllTouched: () => void;
    /**
     * Marks this array and all item controllers as pristine (resets baseline) recursively.
     */
    readonly markAllPristine: () => void;
}
