declare enum ValidationCode {
    FIELD_UNKNOWN = "FIELD_UNKNOWN",
    UNEXPECTED = "UNEXPECTED"
}

/**
 * NonEmptyArray<T>
 *
 * A tuple-based type that ensures the array contains at least one element.
 *
 * - The first element is required: [T, ...]
 * - Any number of additional elements of type T can follow: [...T[]]
 *
 * This is useful for enforcing non-empty arrays at the type level,
 * such as when you want to guarantee at least one item in a list.
 *
 * Example:
 * const valid: NonEmptyArray<number> = [1, 2, 3]; // ✅ OK
 * const invalid: NonEmptyArray<number> = [];      // ❌ Error: must have at least one element
 */
type NonEmptyArray<T> = [T, ...T[]];
/**
 * Defines the structure of a single field error.
 */
type FieldError = {
    /**
     * The field path that caused the error (e.g. "email", "user.name").
     */
    path: string;
    /**
     * A machine-readable error code (e.g. "REQUIRED", "INVALID_FORMAT").
     */
    code: string;
    /**
     * An optional default error message. This message can be used as a fallback
     * if no translation is found for the `code`, or for simpler cases where i18n
     * isn't strictly necessary or for quick debugging. When `code` is provided
     * and i18n is used, this message typically serves as a last resort.
     */
    message?: string;
    origin?: string;
    /**
     * Additional parameters for i18n or dynamic formatting.
     */
    params?: Record<string, unknown>;
};
type SchemaInput<O> = Partial<O>;
type ValidationRule<O> = {
    /**
     * The path to the field(s) affected by this rule.
     * Can be a single field name (string) or an array for nested fields or cross-field validation.
     * Examples: 'name', ['address', 'street'], ['password', 'confirmPassword']
     */
    path: keyof O | NonEmptyArray<keyof O>;
    /**
     * A unique error code for this specific rule. This code is **required** and serves as
     * the primary key for Internationalization (i18n) lookup. It enables translating
     * error messages and programmatically handling specific validation failures.
     * Example: 'FORM_AGE_TOO_YOUNG', 'STRING_MIN_LENGTH'.
     */
    code: string;
    /**
     * Optional parameters or context data that can be used to dynamically
     * construct the error message. This is essential for parameterized messages
     * and Internationalization (i18n).
     * Example: `{ min: 5, max: 10 }` for a string length rule, or `{ fieldName: 'Name' }`.
     */
    params?: Partial<Record<string, any>>;
    /**
     * An optional default error message. This message can be used as a fallback
     * if no translation is found for the `code`, or for simpler cases where i18n
     * isn't strictly necessary or for quick debugging. When `code` is provided
     * and i18n is used, this message typically serves as a last resort.
     */
    message?: string;
    check: (data: O) => boolean | Promise<boolean>;
};

/**
 * Interface for the FormErrorManager, responsible for handling validation errors.
 */
interface IFormErrorManager {
    /**
     * Sets all errors at once, replacing any existing errors.
     * @param errors An array of FieldError objects.
     */
    setErrors(errors: FieldError[]): void;
    /**
     * Adds a single error to the current list of errors.
     * @param error The FieldError object to add.
     */
    addError(error: FieldError): void;
    /**
     * Checks if any error exists for a specific field path, or if any error exists in general.
     * @param path Optional. The dot-notation path of the field (e.g., 'name', 'address.street').
     * @returns `true` if an error exists for the specified path or if any error exists, `false` otherwise.
     */
    hasError(path?: string): boolean;
    /**
     * Retrieves the first error message for a specific field.
     * @param path The dot-notation path of the field.
     * @returns The error message string, or `undefined` if the field has no error.
     */
    getFirstFieldError(path: string): string | undefined;
    /**
     * Retrieves all error objects for a specific field.
     * @param path The dot-notation path of the field.
     * @returns An array of `FieldError` objects for the specified field.
     */
    getErrorsForField(path: string): FieldError[];
    /**
     * Retrieves all current error objects.
     * @returns An array of all `FieldError` objects.
     */
    getAllErrors(): FieldError[];
    /**
     * Clears all existing errors.
     */
    clearErrors(): void;
}

/**
 * Manages validation errors for a form.
 */
declare class FormErrorManager implements IFormErrorManager {
    private _errors;
    constructor(initialErrors?: FieldError[]);
    /**
     * Sets all errors at once, replacing any existing errors.
     * @param errors An array of FieldError objects.
     */
    setErrors(errors: FieldError[]): void;
    /**
     * Adds a single error to the current list of errors.
     * @param error The FieldError object to add.
     */
    addError(error: FieldError): void;
    /**
     * Checks if any error exists for a specific field path, or if any error exists in general.
     * @param path Optional. The dot-notation path of the field (e.g., 'name', 'address.street').
     * @returns `true` if an error exists for the specified path or if any error exists, `false` otherwise.
     */
    hasError(path?: string): boolean;
    /**
     * Retrieves the first error message for a specific field.
     * @param path The dot-notation path of the field.
     * @returns The error message string, or `undefined` if the field has no error.
     */
    getFirstFieldError(path: string): string | undefined;
    /**
     * Retrieves all error objects for a specific field.
     * @param path The dot-notation path of the field.
     * @returns An array of `FieldError` objects for the specified field.
     */
    getErrorsForField(path: string): FieldError[];
    /**
     * Retrieves all current error objects.
     * @returns An array of all `FieldError` objects.
     */
    getAllErrors(): FieldError[];
    /**
     * Clears all existing errors.
     */
    clearErrors(): void;
}

/**
 * Custom error class for validation failures.
 * It provides structured access to field-specific errors.
 */
declare class ValidationError extends Error {
    fields: FieldError[];
    /**
     * Optionally store the original error (e.g., ZodError) for debugging
     */
    originalError?: unknown;
    /**
     * Creates an instance of ValidationError.
     * @param fields An array of FieldError objects.
     * @param originalError The original error object from the validator (optional).
     * @param message A custom error message (optional). If not provided, a default message is generated.
     */
    constructor(fields: FieldError[], originalError?: unknown, message?: string);
}

/**
 * Interface defining the structure of the object returned by the `useFormSchema` hook.
 * @template O - Represents the inferred output type of the schema.
 */
interface UseFormSchemaReturn<O> {
    /**
     * The current raw (unvalidated and untransformed) input values of the form.
     */
    rawInput: SchemaInput<O>;
    /**
     * Indicates whether the entire form is currently valid (has no validation errors).
     */
    isValid: boolean;
    /**
     * An object providing comprehensive error management utilities.
     * It includes methods like `hasError`, `getFirstFieldError`, `getErrorsForField`, `getAllErrors`, and `clearErrors`.
     */
    errors: {
        /**
         * Checks if any error exists for a specific field path, or if any error exists in general.
         * @param path Optional. The dot-notation path of the field.
         */
        hasError: IFormErrorManager['hasError'];
        /**
         * Retrieves the first error message for a specific field.
         * @param path The dot-notation path of the field.
         */
        getFirstFieldError: IFormErrorManager['getFirstFieldError'];
        /**
         * Retrieves all error objects for a specific field.
         * @param path The dot-notation path of the field.
         */
        getErrorsForField: IFormErrorManager['getErrorsForField'];
        /**
         * Retrieves all current error objects.
         */
        getAllErrors: IFormErrorManager['getAllErrors'];
        /**
         * Clears all existing errors.
         */
        clearErrors: IFormErrorManager['clearErrors'];
    };
    /**
     * A higher-order function that returns an `onSubmit` handler for HTML forms.
     * It performs full form validation and calls either `onSubmitValid` or `onSubmitInvalid` based on the validation result.
     * @param onSubmitValid A callback function executed when the form is valid and submitted. Receives the parsed and validated data.
     * @param onSubmitInvalid An optional callback function executed when the form is invalid. Receives an array of `FieldError` objects.
     * @returns An event handler function suitable for the `onSubmit` prop of a `<form>` element.
     */
    handleSubmit: (onSubmitValid: (data: O) => void, onSubmitInvalid?: (errors: FieldError[]) => void) => (event: React.FormEvent) => void;
    /**
     * Resets the form's internal raw input state to its initial state or an empty state.
     * This clears current values and errors.
     * @param initialValues Optional. New initial values to reset the form to. If not provided, resets to empty.
     */
    reset: (initialValues?: SchemaInput<O>) => void;
    /**
     * Returns a memoized setter function for a specific form field.
     * This setter updates the form's internal raw input state and triggers field-specific validation.
     * @param field The name of the field for which to create a setter.
     * @returns A function that takes a value (of Input type) and updates the corresponding field.
     */
    setValueFor: <F extends keyof O>(field: F) => (value: SchemaInput<O>[F]) => void;
    /**
     * Overwrites the entire raw input state of the form with the new values.
     * Triggers a full form validation.
     * @param newValues The new raw input values to set.
     */
    /**
     * Overwrites the entire raw input state of the form with the new values.
     * Triggers a full form validation.
     * @param newValues The new raw input values to set.
     */
    setRawValue: (newValues: SchemaInput<O>) => void;
    /**
     * Merges the provided partial values into the existing raw input state.
     * Existing fields not present in `partialValues` will be retained. Triggers a full form validation.
     * @param partialValues The partial raw input values to merge.
     */
    mergeRawValue: (partialValues: SchemaInput<O>) => void;
    /**
     * Manually triggers validation for the entire form or a specific field.
     * Updates the internal error state and notifies subscribers.
     * @param field Optional. The name of the field to validate, or a partial input object for external validation.
     * @param value Optional. The value for a specific field when `field` is a field name.
     * @returns A Promise that resolves to `undefined` if validation passes, or an `Error` instance if validation fails.
     */
    validate: (field?: keyof O | SchemaInput<O>, value?: SchemaInput<O>[keyof O]) => Promise<undefined | Error>;
}

export { FormErrorManager as F, type SchemaInput as S, type UseFormSchemaReturn as U, type ValidationRule as V, ValidationError as a, type FieldError as b, ValidationCode as c };
