import type { ActionCallback, ActionSetInterface, ActionSetOptions, AnyAction, Dispatch, ErrorSubscriber, MetaAction, Unsubscribe } from '../actions/types';
import { Group } from '../actions/types';
import type { Handler, MessageTransport } from '../MessageTransport';
import { Context } from '../MessageTransport';
/**
 * @public
 */
export interface AppConfigV2 {
    apiKey: string;
    host: string;
    forceRedirect?: boolean;
}
/**
 * @public
 */
export interface AppConfigV1 {
    apiKey: string;
    shopOrigin: string;
    forceRedirect?: boolean;
}
/**
 * @public
 */
export declare type AppConfig = AppConfigV2 | AppConfigV1;
/**
 * @internal
 * @param config
 */
export declare function isV1Config(config: AppConfig): config is AppConfigV1;
/**
 * @internal
 */
export declare enum PermissionType {
    Dispatch = "Dispatch",
    Subscribe = "Subscribe"
}
/**
 * @internal
 */
export declare type FeaturePermission = {
    [key in PermissionType]: boolean;
};
/**
 * @internal
 */
export interface FeaturesAction {
    [key: string]: FeaturePermission;
}
/**
 * @internal
 */
export declare type FeaturesAvailable<T extends Group = Group> = Record<T, FeaturesAction>;
/**
 * @internal
 */
export declare type FeaturesState<T = FeaturesAvailable> = {
    [key in Context]?: T;
};
/**
 * Application instance, required for use with actions.
 * @public
 */
export interface ClientApplication<S> {
    dispatch: Dispatch<AnyAction>;
    localOrigin: string;
    error: ErrorSubscriber;
    hooks?: HooksInterface;
    getState(query?: string): Promise<S>;
    featuresAvailable(): Promise<FeaturesAvailable<Group>>;
    featuresAvailable<T extends Group[]>(...features: T): Promise<FeaturesAvailable<typeof features[number]>>;
    subscribe(callback: ActionCallback): Unsubscribe;
    subscribe(eventNameSpace: string, callback: ActionCallback, id?: string): Unsubscribe;
}
/**
 * @public
 */
export interface ClientApplicationCreator {
    <S>(config: AppConfigV2): ClientApplication<S>;
}
/**
 * @internalremarks
 * TODO: Generalize—pramaterize return type
 * @internal
 */
export interface ClientApplicationTransportInjector {
    (transport: MessageTransport, middleware?: AppMiddleware[]): ClientApplicationCreator;
}
/**
 * @internal
 */
export interface Dispatcher {
    (type: MessageType, payload?: AnyAction | undefined): void;
}
/**
 * @internal
 */
export declare enum MessageType {
    GetState = "getState",
    Dispatch = "dispatch",
    Subscribe = "subscribe",
    Unsubscribe = "unsubscribe"
}
/**
 * @internal
 */
export interface TransportDispatch {
    type: MessageType;
    source: AppConfigV2;
    payload?: AnyAction;
}
/**
 * @internal
 */
export interface TransportSubscription {
    id?: string;
    type: string;
}
/**
 * @deprecated Not to be used, there is no replacement.
 * @internal
 */
export interface Params {
    [key: string]: string;
}
/**
 *
 * There are two types of hooks: `LifecycleHook.DispatchAction` and `LifecycleHook.UpdateAction`.
 *
 * @remarks
 * `DispatchAction` hooks are run when an action is dispatched with the `.dispatch()` function:
 *
 * ```js
 * const toastNotice = Toast.create(app, {message: 'Product saved'});
 * toastNotice.dispatch(Toast.Action.SHOW);
 * ```
 *
 * `UpdateAction` hooks are run when an action is updated, using the `.set()` function:
 *
 * ```js
 * toastNotice.set({message: 'Product could not be saved', isError: true});
 * ```
 *
 * @public
 */
export declare enum LifecycleHook {
    UpdateAction = "UpdateAction",
    DispatchAction = "DispatchAction"
}
/**
 * @internal
 */
export interface Hook {
    handler: LifecycleHandler;
    remove: Unsubscribe;
}
/**
 * @internal
 */
export interface HookMap {
    [key: string]: Hook[];
}
/**
 * @internal
 */
export interface HooksInterface {
    set(hook: LifecycleHook.UpdateAction, handler: UpdateActionHook): any;
    set(hook: LifecycleHook.DispatchAction, handler: DispatchActionHook): any;
    set(hook: LifecycleHook, handler: LifecycleHandler): any;
    get(hook: LifecycleHook): LifecycleHandler[] | undefined;
    run<C>(hook: LifecycleHook, final: Function, context: C, ...arg: any[]): any;
}
/**
 * @internal
 */
export interface AppMiddleware {
    (hooks: HooksInterface, app: ClientApplication<any>): void;
}
/**
 * @internal
 */
export interface LifecycleHandler {
    (next: Function): (...args: any[]) => any;
}
/**
 * @internal
 */
export interface UpdateActionHandler {
    <O>(this: ActionSetInterface & ActionSetOptions<O>, options: O): any;
}
/**
 * @internal
 */
export interface UpdateActionHook {
    (next: Function): UpdateActionHandler;
}
/**
 * @internal
 */
export interface DispatchActionHandler {
    <A extends MetaAction>(this: ClientApplication<any>, action: A): any;
}
/**
 * @internal
 */
export interface DispatchActionHook {
    (next: Function): DispatchActionHandler;
}
export { Dispatch, Handler, Unsubscribe };
