import { z } from 'zod';

interface FormState<T extends Record<string, any>> {
    values: Partial<T>;
    errors: Partial<Record<keyof T, string>>;
    touched: Partial<Record<keyof T, boolean>>;
    isSubmitting: boolean;
    isValid: boolean;
    isDirty: boolean;
}
interface UseFormOptions<T extends Record<string, any>> {
    schema: z.ZodSchema<T>;
    initialValues?: Partial<T>;
    onSubmit?: (values: T) => void | Promise<void>;
    validateOnChange?: boolean;
    validateOnBlur?: boolean;
}
interface FieldState {
    isDirty: boolean;
    isTouched: boolean;
    error?: string;
}
interface ResetOptions<T> {
    values?: Partial<T>;
    keepErrors?: boolean;
    keepDirty?: boolean;
    keepTouched?: boolean;
}
interface SetFocusOptions {
    shouldSelect?: boolean;
}
interface UseFormReturn<T extends Record<string, any>> {
    register: (name: string) => {
        name: string;
        onChange: (e: React.ChangeEvent<any>) => void;
        onBlur: (e: React.FocusEvent<any>) => void;
    } & ({
        checked: boolean;
        value?: never;
    } | {
        value: any;
        checked?: never;
    });
    handleSubmit: (onValid: (data: T) => void, onError?: (errors: Record<keyof T, string>) => void) => (e: React.FormEvent) => void;
    formState: FormState<T>;
    reset: (options?: ResetOptions<T>) => void;
    setValue: (path: string, value: any) => void;
    watch: {
        (): Partial<T>;
        <Name extends keyof T>(name: Name): T[Name];
        <Names extends keyof T>(names: Names[]): Pick<T, Names>;
    };
    getFieldState: <Name extends keyof T>(name: Name) => FieldState;
    isDirty: <Name extends keyof T>(name?: Name) => boolean;
    getDirtyFields: () => Partial<Record<keyof T, boolean>>;
    getTouchedFields: () => Partial<Record<keyof T, boolean>>;
    trigger: {
        (): Promise<boolean>;
        <Name extends keyof T>(name: Name): Promise<boolean>;
        <Names extends keyof T>(names: Names[]): Promise<boolean>;
    };
    clearErrors: (name?: keyof T) => void;
    setError: <Name extends keyof T>(name: Name, error: string) => void;
    setFocus: <Name extends keyof T>(name: Name, options?: SetFocusOptions) => void;
    addArrayItem: (path: string, item: any) => void;
    removeArrayItem: (path: string, index: number) => void;
    resetField: <Name extends keyof T>(name: Name) => void;
}
type GridColumns = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
interface AutoFormFieldConfig {
    name: string;
    label?: string;
    type?: FieldType;
    placeholder?: string;
    colSpan?: GridColumns;
    component?: React.ComponentType<AutoFormFieldProps>;
    options?: Array<{
        value: string;
        label: string;
    }>;
    fields?: AutoFormFieldConfig[];
}
interface AutoFormFieldProps {
    name: string;
    label?: string;
    type?: string;
    placeholder?: string;
    value: any;
    onChange: (e: React.ChangeEvent<any>) => void;
    onBlur: (e: React.FocusEvent<any>) => void;
    error?: string;
    touched?: boolean;
    options?: Array<{
        value: string;
        label: string;
    }>;
    fields?: AutoFormFieldConfig[];
    onAddItem?: () => void;
    onRemoveItem?: (index: number) => void;
    arrayPath?: string;
}
interface AutoFormErrorProps {
    errors: Record<string, string>;
    touched: Record<string, boolean>;
}
type FieldType = "text" | "email" | "password" | "number" | "textarea" | "select" | "array" | "checkbox" | "date" | "url";
type ComponentMap = Partial<Record<FieldType, React.ComponentType<AutoFormFieldProps>>>;
interface AutoFormProps<T extends Record<string, any>> {
    schema: z.ZodSchema<T>;
    fields?: AutoFormFieldConfig[];
    initialValues?: Partial<T>;
    layout?: "grid" | "flex";
    columns?: GridColumns;
    onSubmit: (data: T) => void | Promise<void>;
    onError?: (errors: Record<keyof T, string>) => void;
    children?: (formApi: UseFormReturn<T>) => React.ReactNode;
    customErrorComponent?: React.ComponentType<AutoFormErrorProps>;
    componentMap?: ComponentMap;
}

export type { AutoFormProps as A, ComponentMap as C, FieldType as F, UseFormOptions as U, UseFormReturn as a, AutoFormErrorProps as b, AutoFormFieldProps as c, AutoFormFieldConfig as d };
