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