import { Synnax as Client } from '@synnaxlabs/client';
import { Destructor, status } from '@synnaxlabs/x';
import { default as z } from 'zod';
import { core } from './core';
import { InitialStatusDetailsContainer, Result, ResultStatus } from './result';
import { state } from '../state';
export interface UpdateParams<Input extends core.Shape, Store extends core.Store, StatusDetails extends z.ZodType = z.ZodNever> {
    data: Input;
    client: Client;
    store: Store;
    rollbacks: Destructor[];
    setStatus: (setter: state.SetArg<ResultStatus<StatusDetails>>) => void;
}
export type CreateUpdateParams<Input extends core.Shape, ScopedStore extends core.Store, Output extends core.Shape = Input, StatusDetails extends z.ZodType = z.ZodNever> = {
    name: string;
    verbs: core.Verbs;
    update: (params: UpdateParams<Input, ScopedStore, StatusDetails>) => Promise<Output | false>;
} & InitialStatusDetailsContainer<StatusDetails>;
export interface UseObservableUpdateReturn<Input extends core.Shape> {
    update: (data: Input, opts?: core.FetchOptions) => void;
    updateAsync: (data: Input, opts?: core.FetchOptions) => Promise<boolean>;
}
export interface UseObservableUpdateParams<Input extends core.Shape, Output extends core.Shape = Input, StatusDetails extends z.ZodType = z.ZodNever> {
    debounce?: number;
    onChange: state.Setter<Result<Input | undefined, StatusDetails>>;
    scope?: string;
    beforeUpdate?: (params: BeforeUpdateParams<Input>) => Promise<Input | boolean> | Input | boolean;
    afterSuccess?: (params: AfterSuccessParams<Output>) => Promise<void> | void;
    afterFailure?: (params: AfterFailureParams<Input>) => Promise<void> | void;
}
export interface BeforeUpdateParams<Data extends core.Shape> {
    rollbacks: Destructor[];
    client: Client;
    data: Data;
}
export interface AfterSuccessParams<Output extends core.Shape> {
    client: Client;
    data: Output;
}
export interface AfterFailureParams<Data extends core.Shape> {
    client: Client;
    status: status.Status<typeof status.exceptionDetailsSchema, "error">;
    data: Data;
}
export interface UseDirectUpdateParams<Input extends core.Shape, Output extends core.Shape = Input, StatusDetails extends z.ZodType = z.ZodNever> extends Omit<UseObservableUpdateParams<Input, Output, StatusDetails>, "onChange"> {
}
export type UseDirectUpdateReturn<Input extends core.Shape, StatusDetails extends z.ZodType = z.ZodNever> = Result<Input | undefined, StatusDetails> & UseObservableUpdateReturn<Input>;
export interface UseObservableUpdate<Input extends core.Shape, Output extends core.Shape = Input, StatusDetails extends z.ZodType = z.ZodNever> {
    (args: UseObservableUpdateParams<Input, Output, StatusDetails>): UseObservableUpdateReturn<Input>;
}
export interface UseUpdate<Input extends core.Shape, Output extends core.Shape = Input, StatusDetails extends z.ZodType = z.ZodNever> {
    (args?: UseDirectUpdateParams<Input, Output, StatusDetails>): UseDirectUpdateReturn<Input, StatusDetails>;
}
export interface CreateUpdateReturn<Input extends core.Shape, Output extends core.Shape = Input, StatusDetails extends z.ZodType = z.ZodNever> {
    useObservableUpdate: UseObservableUpdate<Input, Output, StatusDetails>;
    useUpdate: UseUpdate<Input, Output, StatusDetails>;
}
export declare const createUpdate: <Input extends core.Shape, ScopedStore extends core.Store, Output extends core.Shape = Input, StatusDetails extends z.ZodType = z.ZodNever>(createParams: CreateUpdateParams<Input, ScopedStore, Output, StatusDetails>) => CreateUpdateReturn<Input, Output, StatusDetails>;
//# sourceMappingURL=update.d.ts.map