import { type Message as CMessage } from '@botpress/client';
import { z } from '@botpress/sdk';
import { BotClient } from '@botpress/sdk/dist/bot';
import type { ChannelSpec, Channels } from '../_types/channels';
import type { ConversationDefinitions, ConversationRoutableEvents } from '../_types/conversations';
import { WorkflowDefinitions } from '../_types/workflows';
import { Autonomous } from '../runtime/autonomous';
import { WorkflowCallbackEventType } from '../runtime/events';
import { ZuiType } from '../types';
import { BaseConversationInstance } from './conversation-instance';
import { Definitions } from './definition';
import { BaseWorkflowInstance } from './workflow-instance';
type WorkflowRequest = {
    [WfName in keyof WorkflowDefinitions & string]: keyof WorkflowDefinitions[WfName]['requests'] extends never ? never : {
        [ReqName in keyof WorkflowDefinitions[WfName]['requests'] & string]: {
            type: `${WfName}:${ReqName}`;
            workflow: BaseWorkflowInstance<WfName>;
            step: string;
        };
    }[keyof WorkflowDefinitions[WfName]['requests'] & string];
}[keyof WorkflowDefinitions & string];
export declare namespace Typings {
    export type Message<TChannel extends keyof ConversationDefinitions = keyof ConversationDefinitions, TType extends keyof ConversationDefinitions[TChannel]['messages'] = keyof ConversationDefinitions[TChannel]['messages']> = TChannel extends keyof ConversationDefinitions ? TType extends keyof ConversationDefinitions[TChannel]['messages'] ? Omit<CMessage, 'type' | 'tags' | 'payload'> & {
        type: TType;
        payload: ConversationDefinitions[TChannel]['messages'][TType];
        tags: ConversationDefinitions[TChannel]['messageTags'];
    } : never : never;
    export type Event<TChannel extends keyof ConversationDefinitions = keyof ConversationDefinitions> = TChannel extends keyof ConversationDefinitions ? {
        [EType in keyof ConversationDefinitions[TChannel]['events']]: {
            type: EType;
            payload: ConversationDefinitions[TChannel]['events'][EType];
        };
    }[keyof ConversationDefinitions[TChannel]['events'] & (string | number)] | WorkflowCallbackEventType : never;
    export type ExtractChannel<T extends ChannelSpec> = T extends readonly string[] ? T[number] : T extends '*' ? Channels : T;
    /**
     * Extract event name from "integration:eventName" format.
     * e.g., "webchat:conversationStarted" -> "conversationStarted"
     */
    type ExtractEventName<T extends string> = T extends `${string}:${infer EventName}` ? EventName : T;
    /**
     * Get the channel for an event based on its integration.
     * e.g., "webchat:conversationStarted" -> "webchat.channel"
     */
    type EventToChannel<T extends string> = T extends `${infer Integration}:${string}` ? `${Integration}.channel` extends keyof ConversationDefinitions ? `${Integration}.channel` : never : never;
    /**
     * Get event payload from an event type string.
     */
    type GetEventPayload<T extends string, TChannel extends keyof ConversationDefinitions = EventToChannel<T>> = TChannel extends keyof ConversationDefinitions ? ExtractEventName<T> extends keyof ConversationDefinitions[TChannel]['events'] ? ConversationDefinitions[TChannel]['events'][ExtractEventName<T>] : unknown : unknown;
    /**
     * Create a discriminated union of event handler props for each event type.
     * Each event type narrows to its specific channel and conversation instance.
     */
    type EventHandlerProps<TEvents extends readonly string[], State extends ZuiType> = TEvents extends readonly [] ? never : {
        [K in TEvents[number]]: EventToChannel<K> extends keyof ConversationDefinitions ? {
            type: 'event';
            channel: EventToChannel<K>;
            conversation: BaseConversationInstance<EventToChannel<K>>;
            event: {
                type: K;
                payload: GetEventPayload<K>;
            } | WorkflowCallbackEventType;
            message?: never;
            workflow?: never;
            request?: never;
            state: z.infer<State>;
            client: BotClient<any>;
            execute: Autonomous.ConvoExecuteFn;
        } : never;
    }[TEvents[number]];
    export type HandlerProps<TChannelSpec extends ChannelSpec = ChannelSpec, State extends ZuiType = ZuiType, TEvents extends readonly string[] = readonly [], Channel extends string = ExtractChannel<TChannelSpec>> = Channel extends keyof ConversationDefinitions ? TEvents extends readonly [] ? {
        type: 'message';
        channel: Channel;
        conversation: BaseConversationInstance<Channel>;
        message: Message<Channel>;
        event?: never;
        workflow?: never;
        request?: never;
        state: z.infer<State>;
        client: BotClient<any>;
        execute: Autonomous.ConvoExecuteFn;
    } | {
        type: 'workflow_request';
        channel: Channel;
        conversation: BaseConversationInstance<Channel>;
        event?: never;
        message?: never;
        workflow?: never;
        request: WorkflowRequest;
        state: z.infer<State>;
        client: BotClient<any>;
        execute: Autonomous.ConvoExecuteFn;
    } : {
        type: 'message';
        channel: Channel;
        conversation: BaseConversationInstance<Channel>;
        message: Message<Channel>;
        event?: never;
        workflow?: never;
        request?: never;
        state: z.infer<State>;
        client: BotClient<any>;
        execute: Autonomous.ConvoExecuteFn;
    } | EventHandlerProps<TEvents, State> | {
        type: 'workflow_request';
        channel: Channel;
        conversation: BaseConversationInstance<Channel>;
        event?: never;
        message?: never;
        workflow?: never;
        request: WorkflowRequest;
        state: z.infer<State>;
        client: BotClient<any>;
        execute: Autonomous.ConvoExecuteFn;
    } : never;
    export type Handler<TChannelSpec extends ChannelSpec = ChannelSpec, State extends ZuiType = ZuiType, TEvents extends readonly string[] = readonly []> = (props: HandlerProps<TChannelSpec, State, TEvents>) => Promise<void> | void;
    export type StartFromTrigger<State extends ZuiType = ZuiType> = (event: any) => Promise<string | false> | string | false;
    /**
     * Get available routable event names for a given channel.
     * These are events that have a conversationId property and can be routed to conversations.
     */
    export type RoutableEventNames<TChannel extends keyof ConversationDefinitions> = TChannel extends keyof ConversationRoutableEvents ? ConversationRoutableEvents[TChannel][number] : never;
    /**
     * Event specification type for conversations.
     * Must be an array of event names that are routable for the channel(s).
     */
    export type EventSpec<TChannelSpec extends ChannelSpec> = ExtractChannel<TChannelSpec> extends keyof ConversationRoutableEvents ? readonly ConversationRoutableEvents[ExtractChannel<TChannelSpec>][number][] : readonly string[];
    export type Props<TChannelSpec extends ChannelSpec = ChannelSpec, State extends ZuiType = ZuiType, TEvents extends EventSpec<TChannelSpec> = readonly []> = {
        channel: TChannelSpec;
        handler: Handler<TChannelSpec, State, TEvents>;
        state?: State;
        startFromTrigger?: StartFromTrigger<State>;
        /**
         * Array of event names this conversation should listen to.
         * Only events with a conversationId property are allowed.
         * By default, conversations only receive messages, not events.
         */
        events?: TEvents;
    };
    export const Primitive: "conversation";
    export {};
}
/**
 * Base Conversation definition class.
 * This defines a conversation handler for one or more channels.
 * At runtime, it will be instantiated as a BaseConversationInstance.
 *
 * The generated Conversation class in runtime.d.ts provides proper typing.
 */
export declare class BaseConversation<TChannelSpec extends ChannelSpec = ChannelSpec, State extends ZuiType = ZuiType, TEvents extends Typings.EventSpec<TChannelSpec> = readonly []> implements Definitions.Primitive {
    #private;
    readonly channel: ChannelSpec;
    /**
     * Array of event names this conversation listens to.
     * Only events with conversationId property are allowed.
     * Empty array means no events (only messages).
     */
    readonly events: readonly string[];
    constructor(props: Typings.Props<TChannelSpec, State, TEvents>);
}
export {};
//# sourceMappingURL=conversation.d.ts.map