import { ComputedRef } from 'vue';
import { DefineSetupFnComponent } from 'vue';
import { InputHTMLAttributes } from 'vue';
import { PublicProps } from 'vue';
import { Ref } from 'vue';
import { SlotsType } from 'vue';
import { WritableComputedRef } from 'vue';

declare const ErrorComp: <T extends Record<string, any> = Record<string, any>>() => DefineSetupFnComponent<    {
errorFor: GetKeys<T>;
}, {}, SlotsType<{
default: {
error: any;
};
}>, {
errorFor: GetKeys<T>;
} & {}, PublicProps>;

declare type ExtractValue<T, K extends string> = K extends `${infer Root}.${infer Rest}` ? Root extends keyof T ? ExtractValue<T[Root], Rest> : Root extends `${infer ArrayRoot}[${number}]` ? ArrayRoot extends keyof T ? T[ArrayRoot] extends (infer U)[] ? ExtractValue<U, Rest> : never : never : never : K extends `${infer Root}[${number}]` ? Root extends keyof T ? T[Root] extends (infer U) ? UnwrapArray<U> : never : never : K extends keyof T ? UnwrapArray<T[K]> : never;

declare const FieldArrayComp: <T extends Record<string, any> = Record<string, any>>() => DefineSetupFnComponent<FieldArrayType<T> extends infer T_1 ? { [K in keyof T_1]: FieldArrayType<T>[K]; } : never, any, SlotsType<{
default: {
fields: {
id: number;
}[];
add: () => void;
remove: (idx: number) => void;
error: any;
};
}>, (FieldArrayType<T> extends infer T_2 ? { [K in keyof T_2]: FieldArrayType<T>[K]; } : never) & ({} | {
[x: `on${Capitalize<any>}`]: ((...args: any[]) => any) | undefined;
} | {
[x: `on${Capitalize<string>}`]: ((...args: any[] | unknown[]) => any) | undefined;
}), PublicProps>;

declare type FieldArrayType<T extends Record<string, any>> = {
    [K in GetKeys<T>]: {
        name: K;
        default?: ExtractValue<T, K>;
        error?: any;
        ignore?: boolean;
        modelValue?: any;
        preserve?: boolean;
        rule?: StandardSchemaV1;
    } & InputHTMLAttributes;
}[GetKeys<T>];

declare const FieldComp: <T extends Record<string, any> = Record<string, any>>() => DefineSetupFnComponent<FieldType<T> extends infer T_1 ? { [K in keyof T_1]: FieldType<T>[K]; } : never, any, SlotsType<{
default: {
field: {
value: any;
modelValue: any;
isValid: boolean;
error: any;
};
};
}>, (FieldType<T> extends infer T_2 ? { [K in keyof T_2]: FieldType<T>[K]; } : never) & ({} | {
[x: `on${Capitalize<any>}`]: ((...args: any[]) => any) | undefined;
} | {
[x: `on${Capitalize<string>}`]: ((...args: any[] | unknown[]) => any) | undefined;
}), PublicProps>;

declare type FieldType<T extends Record<string, any>> = {
    [K in GetKeys<T>]: {
        name: K;
        default?: ExtractValue<T, K>;
        error?: any;
        ignore?: boolean;
        trueValue?: any;
        modelValue?: any;
        falseValue?: any;
        preserve?: boolean;
        as?: 'input' | 'select';
        rule?: StandardSchemaV1;
    } & InputHTMLAttributes;
}[GetKeys<T>];

declare const FormComponent: <T extends Record<string, any> = Record<string, any>>(opt?: FormOptions<T>) => {
    cmp: DefineSetupFnComponent<    {
    enctype?: "application/x-www-form-urlencoded" | "multipart/form-data" | undefined;
    action?: string | undefined;
    initialValues?: RecursivePartial<T> | undefined;
    name?: string | undefined;
    onValueChange?: ((value?: any) => void) | undefined;
    onSubmit?: ((value?: any, $event?: SubmitEvent) => void | Promise<any>) | undefined;
    }, ("submit" | "value-change")[], SlotsType<{
    default: {
    values: T;
    getError: (name: GetKeys<T>) => string;
    isDirty: boolean;
    isValid: boolean;
    };
    }>, {
    enctype?: "application/x-www-form-urlencoded" | "multipart/form-data" | undefined;
    action?: string | undefined;
    initialValues?: RecursivePartial<T> | undefined;
    name?: string | undefined;
    onValueChange?: ((value?: any) => void) | undefined;
    onSubmit?: ((value?: any, $event?: SubmitEvent) => void | Promise<any>) | undefined;
    } & {
    onSubmit?: ((...args: any[]) => any) | undefined;
    "onValue-change"?: ((...args: any[]) => any) | undefined;
    }, PublicProps>;
    values: WritableComputedRef<T, T>;
    isSubmitting: Ref<boolean, boolean>;
    reset: (force?: boolean) => void;
    setInitialValues: (initials: Partial<T>) => void;
    setValue: (name: GetKeys<T>, value: any) => void;
    setValues: (values: Partial<T>) => void;
    setError: (name: GetKeys<T>, error: any) => void;
    handleSubmit: (cb?: (data?: T) => void | Promise<any>) => () => Promise<void>;
};

declare type FormOptions<T extends Record<string, any>> = {
    initialValues?: T extends Record<string, any> ? RecursivePartial<T> : Record<string, any>;
    schema?: StandardSchemaV1<any, T>;
    name?: string;
    preserve?: boolean;
    mode?: 'onChange' | 'onSubmit';
};

export declare type FormType<T extends Record<string, any> = Record<string, any>> = {
    values: T;
    errors: T;
    isSubmitting: boolean;
    setError: (name: GetKeys<T>, error: any) => void;
    updateField: (name: GetKeys<T>, value: any) => void;
    reset: () => void;
    flush: () => void;
};

declare type GetKeys<T extends Record<string, any>> = keyof {
    [K in keyof T as (T[K] extends (infer U)[] ? U extends object ? IsPlainObject<U> extends true ? `${K & string}` | `${K & string}[]` | `${K & string}[${number}]` | `${K & string}[].${GetNestedArray<U>}` | `${K & string}[${number}].${GetNestedArray<U>}` : `${K & string}` | `${K & string}[]` | `${K & string}[${number}]` : `${K & string}` | `${K & string}[]` | `${K & string}[${number}]` : T[K] extends object ? IsPlainObject<T[K]> extends true ? `${K & string}` | `${K & string}.${GetNestedArray<T[K]>}` : `${K & string}` : `${K & string}`)]: any;
};

declare type GetNestedArray<T> = T extends object ? IsPlainObject<T> extends true ? {
    [K in keyof T]: T[K] extends (infer U)[] ? U extends object ? IsPlainObject<U> extends true ? `${K & string}[]` | `${K & string}[${number}]` | `${K & string}[].${GetNestedArray<U>}` | `${K & string}[${number}].${GetNestedArray<U>}` : `${K & string}[]` | `${K & string}[${number}]` : `${K & string}[]` | `${K & string}[${number}]` : T[K] extends object ? IsPlainObject<T[K]> extends true ? `${K & string}` | `${K & string}.${GetNestedArray<T[K]>}` : `${K & string}` : `${K & string}`;
}[keyof T] : '' : '';

export declare type InputProps<T extends Record<string, any> = Record<string, any>> = {
    name?: GetKeys<T>;
    default?: any;
    error?: any;
    ignore?: boolean;
    trueValue?: any;
    modelValue?: any;
    falseValue?: any;
    preserve?: boolean;
    as?: 'input' | 'select';
    rule?: StandardSchemaV1;
    onInput?: (evt: any) => void;
    onChange?: (evt: any) => void;
    onFocus?: () => void;
    onBlur?: () => void;
};

declare type IsPlainObject<T> = T extends object ? T extends Date | RegExp | Map<any, any> | Set<any> | WeakMap<any, any> | WeakSet<any> | any[] ? false : true : false;

declare type RecursivePartial<T> = {
    [P in keyof T]?: T[P] extends Record<string, any> ? RecursivePartial<T[P]> : T[P];
};

/** The Standard Schema interface. */
declare interface StandardSchemaV1<Input = unknown, Output = Input> {
    /** The Standard Schema properties. */
    readonly '~standard': StandardSchemaV1.Props<Input, Output>;
}

declare namespace StandardSchemaV1 {
    /** The Standard Schema properties interface. */
    interface Props<Input = unknown, Output = Input> {
        /** The version number of the standard. */
        readonly version: 1;
        /** The vendor name of the schema library. */
        readonly vendor: string;
        /** Default input values. */
        default?: unknown;
        /** Validates unknown input values. */
        readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>;
        /** Inferred types associated with the schema. */
        readonly types?: Types<Input, Output> | undefined;
    }
    /** The result interface of the validate function. */
    type Result<Output> = SuccessResult<Output> | FailureResult;
    /** The result interface if validation succeeds. */
    interface SuccessResult<Output> {
        /** The typed output value. */
        readonly value: Output;
        /** The non-existent issues. */
        readonly issues?: undefined;
    }
    /** The result interface if validation fails. */
    interface FailureResult {
        /** The issues of failed validation. */
        readonly issues: readonly Issue[];
    }
    /** The issue interface of the failure output. */
    interface Issue {
        /** The error message of the issue. */
        readonly message: string;
        /** The path of the issue, if any. */
        readonly path?: readonly (PropertyKey | PathSegment)[] | undefined;
    }
    /** The path segment interface of the issue. */
    interface PathSegment {
        /** The key representing a path segment. */
        readonly key: PropertyKey;
    }
    /** The Standard Schema types interface. */
    interface Types<Input = unknown, Output = Input> {
        /** The input type of the schema. */
        readonly input: Input;
        /** The output type of the schema. */
        readonly output: Output;
    }
    /** Infers the input type of a Standard Schema. */
    type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['input'];
    /** Infers the output type of a Standard Schema. */
    type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['output'];
}

declare type UnwrapArray<T> = T extends (infer U)[] ? U[] | U : T;

export declare const useForm: <T extends Record<string, any>>(opt?: FormOptions<T>) => UseFormReturn<T>;

declare type UseFormReturn<T extends Record<string, any>> = {
    Form: ReturnType<typeof FormComponent<T>>['cmp'];
    Field: ReturnType<typeof FieldComp<T>>;
    FieldArray: ReturnType<typeof FieldArrayComp<T>>;
    Error: ReturnType<typeof ErrorComp<T>>;
    reset: ReturnType<typeof FormComponent<T>>['reset'];
    setInitialValues: ReturnType<typeof FormComponent<T>>['setInitialValues'];
    setValue: ReturnType<typeof FormComponent<T>>['setValue'];
    setValues: ReturnType<typeof FormComponent<T>>['setValues'];
    setError: ReturnType<typeof FormComponent<T>>['setError'];
    handleSubmit: ReturnType<typeof FormComponent<T>>['handleSubmit'];
    values: ReturnType<typeof FormComponent<T>>['values'];
    isSubmitting: ReturnType<typeof FormComponent<T>>['isSubmitting'];
};

export declare const useInput: <T extends Record<string, any> = InputProps>(props: FieldType<T> | (FieldArrayType<T> & {
    trueValue: any;
    falseValue: any;
}) | InputProps<any>, isArray?: boolean) => {
    value: WritableComputedRef<any, any>;
    isValid: ComputedRef<boolean>;
    isTouched: ComputedRef<boolean>;
    isDirty: ComputedRef<boolean>;
    inputProps: Ref<any, any>;
    getError: () => any;
    setError: (name: string, error: any) => void;
    setArrayValue: (value: any, key?: any) => void;
};

export { }
