import { AXPExecuteCommandResult, AXPViewDefinition, AXPMetaData } from '@acorex/platform/core';
import * as i0 from '@angular/core';
import { InjectionToken, Type, EnvironmentProviders, Provider } from '@angular/core';
import { AXComponent } from '@acorex/cdk/common';

type AXPExecuteCommandResultPromise<TResult = any> = Promise<AXPExecuteCommandResult<TResult>>;
interface AXPCommand<TInput = any, TResult = any> {
    execute(input: TInput): AXPExecuteCommandResultPromise<TResult>;
}

/**
 * Represents a middleware function in the command execution pipeline.
 */
type AXPCommandMiddleware<TInput = any, TResult = any> = (input: TInput, next: (input: TInput) => Promise<AXPExecuteCommandResult<TResult>>) => Promise<AXPExecuteCommandResult<TResult>>;
/**
 * Creates a composed handler by chaining the provided command middlewares.
 */
declare function composeCommandMiddlewares<TInput, TResult>(middlewares: AXPCommandMiddleware<TInput, TResult>[]): (handler: (input: TInput) => Promise<AXPExecuteCommandResult<TResult>>) => (input: TInput) => Promise<AXPExecuteCommandResult<TResult>>;

declare class AXPCommandRegistry {
    private registry;
    private middlewares;
    register(key: string, loader: () => Promise<AXPCommand>): void;
    unregister(key: string): boolean;
    use(middleware: AXPCommandMiddleware): void;
    exists(key: string): boolean;
    getLoader(key: string): (() => Promise<AXPCommand>) | undefined;
    getMiddlewares(): readonly AXPCommandMiddleware[];
    getRegisteredKeys(): string[];
    clear(): void;
    static ɵfac: i0.ɵɵFactoryDeclaration<AXPCommandRegistry, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<AXPCommandRegistry>;
}

declare class AXPCommandExecutor {
    private readonly injector;
    private readonly registry;
    private readonly extensions;
    private readonly commandEvents;
    execute<TInput = any, TResult = any>(key: string, input: TInput): Promise<AXPExecuteCommandResult<TResult> | null>;
    private getPluginMiddlewares;
    static ɵfac: i0.ɵɵFactoryDeclaration<AXPCommandExecutor, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<AXPCommandExecutor>;
}

declare class AXPCommandService {
    private readonly registry;
    private readonly executor;
    register(key: string, loader: () => Promise<AXPCommand>): void;
    unregister(key: string): boolean;
    use(middleware: AXPCommandMiddleware): void;
    exists(key: string): boolean;
    getRegisteredKeys(): string[];
    clear(): void;
    execute<TInput = any, TResult = any>(key: string, input: TInput): Promise<AXPExecuteCommandResult<TResult> | null>;
    static ɵfac: i0.ɵɵFactoryDeclaration<AXPCommandService, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<AXPCommandService>;
}

interface AXPCommandExtension {
    target: string | RegExp;
    middleware: AXPCommandMiddleware;
}
declare const AXP_COMMAND_EXTENSION: InjectionToken<AXPCommandExtension[]>;

declare const AXP_COMMAND_SETUP: InjectionToken<void>;
type AXPCommandLoader = {
    key: string;
    command: () => Type<AXPCommand> | Promise<Type<AXPCommand>>;
};
declare function provideCommandSetups(entries: AXPCommandLoader[]): EnvironmentProviders;
declare function provideCommand(key: string, loader: () => Type<AXPCommand> | Promise<Type<AXPCommand>>): EnvironmentProviders;

declare const AXP_COMMAND_MIDDLEWARE_SETUP: InjectionToken<void>;
type AXPCommandMiddlewareEntry = (AXPCommandMiddleware | {
    target: string | RegExp;
    middleware: AXPCommandMiddleware;
})[];
declare function provideCommandMiddleware(entries: AXPCommandMiddlewareEntry): EnvironmentProviders;

type AXPCommandExecutionStage = 'before' | 'after';
interface AXPCommandExecutionEvent<TInput = unknown, TResult = unknown> {
    stage: AXPCommandExecutionStage;
    key: string;
    input: TInput;
    success?: boolean;
    result?: AXPExecuteCommandResult<TResult> | null;
    error?: unknown;
}
type CommandExecutionHandler<TInput, TResult> = (event: AXPCommandExecutionEvent<TInput, TResult>) => void;
declare class AXPCommandEventsService {
    private readonly broadcast;
    private readonly distributedEvents;
    listen<TInput = unknown, TResult = unknown>(handler: CommandExecutionHandler<TInput, TResult>): () => void;
    emit<TInput = unknown, TResult = unknown>(event: AXPCommandExecutionEvent<TInput, TResult>): Promise<void>;
    static ɵfac: i0.ɵɵFactoryDeclaration<AXPCommandEventsService, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<AXPCommandEventsService>;
}

interface AXPQuery<TInput = any, TResult = any> {
    fetch(input: TInput): Promise<TResult>;
}

type AXPQueryMiddleware<TInput = any, TResult = any> = (input: TInput, next: (input: TInput) => Promise<TResult>) => Promise<TResult>;
declare function composeQueryMiddlewares<TInput, TResult>(middlewares: AXPQueryMiddleware<TInput, TResult>[]): (handler: (input: TInput) => Promise<TResult>) => (input: TInput) => Promise<TResult>;

declare class AXPQueryRegistry {
    private registry;
    private middlewares;
    register(key: string, loader: () => Promise<AXPQuery>): void;
    unregister(key: string): boolean;
    use(middleware: AXPQueryMiddleware): void;
    exists(key: string): boolean;
    getLoader(key: string): (() => Promise<AXPQuery>) | undefined;
    getMiddlewares(): readonly AXPQueryMiddleware[];
    getRegisteredKeys(): string[];
    clear(): void;
    static ɵfac: i0.ɵɵFactoryDeclaration<AXPQueryRegistry, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<AXPQueryRegistry>;
}

declare class AXPQueryExecutor {
    private readonly injector;
    private readonly registry;
    private readonly extensions;
    fetch<TInput = any, TResult = any>(key: string, input: TInput): Promise<TResult | null>;
    private getPluginMiddlewares;
    static ɵfac: i0.ɵɵFactoryDeclaration<AXPQueryExecutor, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<AXPQueryExecutor>;
}

declare class AXPQueryService {
    private readonly registry;
    private readonly executor;
    register(key: string, loader: () => Promise<AXPQuery>): void;
    unregister(key: string): boolean;
    use(middleware: AXPQueryMiddleware): void;
    exists(key: string): boolean;
    getRegisteredKeys(): string[];
    clear(): void;
    fetch<TInput = any, TResult = any>(key: string, input: TInput): Promise<TResult | null>;
    static ɵfac: i0.ɵɵFactoryDeclaration<AXPQueryService, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<AXPQueryService>;
}

interface AXPQueryExtension {
    target: string | RegExp;
    middleware: AXPQueryMiddleware;
}
declare const AXP_QUERY_EXTENSION: InjectionToken<AXPQueryExtension[]>;

declare const AXP_QUERY_SETUP: InjectionToken<void>;
type AXPQueryLoaderEntry = {
    key: string;
    loader: () => Type<AXPQuery> | Promise<Type<AXPQuery>>;
};
declare function provideQuerySetups(entries: AXPQueryLoaderEntry[]): EnvironmentProviders;

declare const AXP_QUERY_MIDDLEWARE_SETUP: InjectionToken<void>;
type AXPQueryMiddlewareEntry = (AXPQueryMiddleware | {
    key: string;
    middleware: AXPQueryMiddleware;
})[];
declare function provideQueryMiddleware(entries: AXPQueryMiddlewareEntry): EnvironmentProviders;

interface AXPViewProvider<TInput = any> {
    provide(input: TInput): Promise<AXPViewDefinition>;
}

type AXPViewMiddleware<TInput = any> = (input: TInput, next: (input: TInput) => Promise<AXPViewDefinition>) => Promise<AXPViewDefinition>;
declare function composeViewMiddlewares<TInput>(middlewares: AXPViewMiddleware<TInput>[]): (handler: (input: TInput) => Promise<AXPViewDefinition>) => (input: TInput) => Promise<AXPViewDefinition>;

declare class AXPViewRegistry {
    private registry;
    private middlewares;
    register(key: string, loader: () => Promise<AXPViewProvider>): void;
    unregister(key: string): boolean;
    use(middleware: AXPViewMiddleware): void;
    exists(key: string): boolean;
    getLoader(key: string): (() => Promise<AXPViewProvider>) | undefined;
    getMiddlewares(): readonly AXPViewMiddleware[];
    getRegisteredKeys(): string[];
    clear(): void;
    static ɵfac: i0.ɵɵFactoryDeclaration<AXPViewRegistry, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<AXPViewRegistry>;
}

declare class AXPViewExecutor {
    private readonly injector;
    private readonly registry;
    private readonly extensions;
    provide<TInput = any>(key: string, input: TInput): Promise<AXPViewDefinition | null>;
    private getPluginMiddlewares;
    static ɵfac: i0.ɵɵFactoryDeclaration<AXPViewExecutor, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<AXPViewExecutor>;
}

declare class AXPViewService {
    private readonly registry;
    private readonly executor;
    register(key: string, loader: () => Promise<AXPViewProvider>): void;
    unregister(key: string): boolean;
    use(middleware: AXPViewMiddleware): void;
    exists(key: string): boolean;
    getRegisteredKeys(): string[];
    clear(): void;
    provide<TInput = any>(key: string, input: TInput): Promise<AXPViewDefinition | null>;
    static ɵfac: i0.ɵɵFactoryDeclaration<AXPViewService, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<AXPViewService>;
}

interface AXPViewExtension {
    target: string | RegExp;
    middleware: AXPViewMiddleware;
}
declare const AXP_VIEW_EXTENSION: InjectionToken<AXPViewExtension[]>;

declare const AXP_VIEW_SETUP: InjectionToken<void>;
declare function provideViewSetups(providers: Provider[]): EnvironmentProviders;
declare function provideViewSetup(key: string, loader: () => Promise<AXPViewProvider>): Provider;

type AXPPolicyOptions = {
    id: string;
    sender: HTMLElement | AXComponent | AXPMetaData;
    policies?: string[];
};

interface AXPPolicy {
    apply(context: AXPPolicyEngineContext): Promise<void>;
}
declare class AXPPolicyEngineContext {
    private _id;
    private _sender;
    private _visible;
    private _enabled;
    constructor(options: AXPPolicyOptions);
    get sender(): AXPPolicyOptions['sender'];
    get id(): string;
    get visible(): boolean;
    get enabled(): boolean;
    setVisible(visible: boolean): this;
    setEnabled(enabled: boolean): this;
}

type AXPPolicyEngineMiddleware = (context: AXPPolicyEngineContext, next: (context: AXPPolicyEngineContext) => Promise<void>) => Promise<void>;
declare function composePolicyEngineMiddlewares(middlewares: AXPPolicyEngineMiddleware[]): (handler: (context: AXPPolicyEngineContext) => Promise<void>) => (context: AXPPolicyEngineContext) => Promise<void>;

declare class AXPPolicyEngineRegistry {
    private registry;
    private middlewares;
    private extensions;
    private injector;
    use(mw: AXPPolicyEngineMiddleware): void;
    exists(key: string): boolean;
    getPolicies(): string[];
    register(key: string, loader: () => Promise<AXPPolicy>): void;
    private getPluginMiddlewares;
    execute(policy: string, instance: AXPPolicyOptions): Promise<AXPPolicyEngineContext>;
    static ɵfac: i0.ɵɵFactoryDeclaration<AXPPolicyEngineRegistry, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<AXPPolicyEngineRegistry>;
}

declare class AXPPolicyEngineService {
    private registry;
    apply(options: AXPPolicyOptions): Promise<void>;
    static ɵfac: i0.ɵɵFactoryDeclaration<AXPPolicyEngineService, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<AXPPolicyEngineService>;
}

declare class AXPPolicyEngineDirective {
    #private;
    policy: i0.InputSignal<string | null | undefined>;
    private service;
    private elementRef;
    static ɵfac: i0.ɵɵFactoryDeclaration<AXPPolicyEngineDirective, never>;
    static ɵdir: i0.ɵɵDirectiveDeclaration<AXPPolicyEngineDirective, "[axp-apply-policy]", never, { "policy": { "alias": "axp-apply-policy"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
}

interface AXPPolicyExtension {
    key: string;
    middleware: AXPPolicyEngineMiddleware;
}
declare const AXP_POLICY_EXTENSION: InjectionToken<AXPPolicyExtension[]>;

declare const AXP_POLICY_ENGINE_MIDDLEWARE_SETUP: InjectionToken<void>;
type AXPPolicyLoader = {
    key: string;
    policy: () => Type<AXPPolicy> | Promise<Type<AXPPolicy>>;
};
declare function providePolicySetups(entries: AXPPolicyLoader[]): EnvironmentProviders;

declare class AXPRuntimeModule {
    private _commandSetup;
    private _commandMiddlewareSetup;
    private _querySetup;
    private _queryMiddlewareSetup;
    private _viewSetup;
    private _viewMiddlewareSetup;
    private _policyEngineSetup;
    constructor();
    static ɵfac: i0.ɵɵFactoryDeclaration<AXPRuntimeModule, never>;
    static ɵmod: i0.ɵɵNgModuleDeclaration<AXPRuntimeModule, never, never, never>;
    static ɵinj: i0.ɵɵInjectorDeclaration<AXPRuntimeModule>;
}

export { AXPCommandEventsService, AXPCommandExecutor, AXPCommandRegistry, AXPCommandService, AXPPolicyEngineContext, AXPPolicyEngineDirective, AXPPolicyEngineRegistry, AXPPolicyEngineService, AXPQueryExecutor, AXPQueryRegistry, AXPQueryService, AXPRuntimeModule, AXPViewExecutor, AXPViewRegistry, AXPViewService, AXP_COMMAND_EXTENSION, AXP_COMMAND_MIDDLEWARE_SETUP, AXP_COMMAND_SETUP, AXP_POLICY_ENGINE_MIDDLEWARE_SETUP, AXP_POLICY_EXTENSION, AXP_QUERY_EXTENSION, AXP_QUERY_MIDDLEWARE_SETUP, AXP_QUERY_SETUP, AXP_VIEW_EXTENSION, AXP_VIEW_SETUP, composeCommandMiddlewares, composePolicyEngineMiddlewares, composeQueryMiddlewares, composeViewMiddlewares, provideCommand, provideCommandMiddleware, provideCommandSetups, providePolicySetups, provideQueryMiddleware, provideQuerySetups, provideViewSetup, provideViewSetups };
export type { AXPCommand, AXPCommandExecutionEvent, AXPCommandExecutionStage, AXPCommandExtension, AXPCommandMiddleware, AXPExecuteCommandResultPromise, AXPPolicy, AXPPolicyEngineMiddleware, AXPPolicyExtension, AXPQuery, AXPQueryExtension, AXPQueryMiddleware, AXPViewExtension, AXPViewMiddleware, AXPViewProvider };
