import { compare, record, status } from '@synnaxlabs/x';
import { z } from 'zod';
import { ContextValue } from './Context';
import { DefaultGetOptions, ExtensionGetOptions, FieldState, GetOptions, OptionalGetOptions, RequiredGetOptions } from './state';
import { state } from '../state';
export type ContextOptions<Z extends z.ZodType = z.ZodType> = {
    ctx?: ContextValue<Z>;
};
export type UseFieldOptions<I, O = I, Z extends z.ZodType = z.ZodType> = ContextOptions<Z> & {
    onChange?: (value: O, extra: ContextValue<Z> & {
        path: string;
    }) => void;
};
/** Return type for the @link useField hook */
export interface UseFieldReturn<I, O = I> extends FieldState<I> {
    onChange: (value: O) => void;
    setStatus: (status: status.Crude) => void;
    status: status.Crude;
    variant?: "preview";
}
interface UseField {
    <I, O = I>(path: string, opts?: RequiredGetOptions & UseFieldOptions<I, O>): UseFieldReturn<I, O>;
    <I, O = I>(path: string, opts?: DefaultGetOptions<I> & UseFieldOptions<I, O>): UseFieldReturn<I, O>;
    <I, O = I>(path: string, opts?: OptionalGetOptions & UseFieldOptions<I, O>): UseFieldReturn<I, O> | null;
    <I, O = I>(path: string, opts?: ExtensionGetOptions<I> & UseFieldOptions<I, O>): UseFieldReturn<I, O>;
}
/**
 * Hook for managing a particular field in a form.
 *
 * @param props - The props for the hook
 * @param props.path - The path to the field in the form.
 */
export declare const useField: UseField;
export interface UseFieldValue {
    <I, O = I, Z extends z.ZodType = z.ZodType>(path: string, opts?: RequiredGetOptions & ContextOptions<Z>): O;
    <I, O = I, Z extends z.ZodType = z.ZodType>(path: string, opts?: OptionalGetOptions & ContextOptions<Z>): O | null;
    <I, O = I, Z extends z.ZodType = z.ZodType>(path: string, opts?: DefaultGetOptions<I> & ContextOptions<Z>): O;
    <I, O = I, Z extends z.ZodType = z.ZodType>(path: string, opts?: ExtensionGetOptions<I> & ContextOptions<Z>): O;
}
export interface UseFieldState {
    <I, O = I, Z extends z.ZodType = z.ZodType>(path: string, opts?: RequiredGetOptions & ContextOptions<Z>): FieldState<O>;
    <I, O = I, Z extends z.ZodType = z.ZodType>(path: string, opts?: OptionalGetOptions & ContextOptions<Z>): FieldState<O> | null;
    <I, O = I, Z extends z.ZodType = z.ZodType>(path: string, opts?: DefaultGetOptions<I> & ContextOptions<Z>): FieldState<O>;
    <I, O = I, Z extends z.ZodType = z.ZodType>(path: string, opts?: ExtensionGetOptions<I> & ContextOptions<Z>): FieldState<O>;
}
export declare const useFieldState: UseFieldState;
export declare const useFieldValue: UseFieldValue;
export declare const useFieldValid: (path: string) => boolean;
export interface FieldListUtils<K extends record.Key, E extends record.Keyed<K>> {
    push: (value: E | E[], sort?: compare.Comparator<E>) => void;
    add: (value: E | E[], start: number) => void;
    remove: (keys: K | K[]) => K[];
    keepOnly: (keys: K | K[]) => K[];
    set: (values: state.SetArg<E[]>) => void;
    value(): E[];
    sort?: (compareFn: compare.Comparator<E>) => void;
}
export declare const fieldListUtils: <K extends record.Key, E extends record.Keyed<K>>(ctx: ContextValue<any>, path: string) => FieldListUtils<K, E>;
export declare const useFieldListUtils: <K extends record.Key, E extends record.Keyed<K>>(path: string, opts?: ContextOptions<z.ZodType>) => FieldListUtils<K, E>;
export interface UseFieldListReturn<K extends record.Key, E extends record.Keyed<K>> extends FieldListUtils<K, E> {
    data: K[];
}
export declare const useFieldList: <K extends record.Key, E extends record.Keyed<K>, Z extends z.ZodType = z.ZodType>(path: string, opts?: ContextOptions<Z> & GetOptions<E[]>) => UseFieldListReturn<K, E>;
export {};
//# sourceMappingURL=useField.d.ts.map