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 type { EventName, EventPayload as CustomEventPayload } from '../_types/events';
import type { Integrations } from '../_types/integrations';
import { WorkflowDefinitions } from '../_types/workflows';
import { Autonomous } from '../runtime/autonomous';
import { BotContext } from '../runtime/context/context';
import { WorkflowCallbackEventType } from '../runtime/events';
import { ZuiType } from '../types';
import { BaseConversationInstance } from './conversation-instance';
import { Definitions } from './definition';
import { BaseWorkflowInstance } from './workflow-instance';
import { Chat } from '../runtime/chat/chat';
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;
    /**
     * Check if an event name is a custom event (no colon separator).
     * Custom events are defined in agent.config.ts.
     */
    type IsCustomEvent<T extends string> = T extends `${string}:${string}` ? false : true;
    /**
     * Extract integration alias from "alias:eventName" format.
     * e.g., "webchat:conversationStarted" -> "webchat"
     */
    type ExtractIntegrationAlias<T extends string> = T extends `${infer Alias}:${string}` ? Alias : never;
    /**
     * Get event payload from an event type string.
     * Supports both integration events and custom events.
     *
     * For integration events (format "alias:eventName"), this looks up the event
     * directly from the Integrations type using the alias and event name.
     * For custom events (no colon), this uses the EventPayload type.
     */
    type GetEventPayload<T extends string> = IsCustomEvent<T> extends true ? T extends EventName ? CustomEventPayload<T> : unknown : ExtractIntegrationAlias<T> extends infer Alias ? Alias extends keyof Integrations ? ExtractEventName<T> extends keyof Integrations[Alias]['events'] ? Integrations[Alias]['events'][ExtractEventName<T>] : unknown : unknown : unknown;
    /**
     * Create a discriminated union of event handler props for each event type.
     * The conversation instance is always typed based on the conversation's channel,
     * not the event's source integration.
     */
    type EventHandlerProps<TEvents extends readonly string[], State extends ZuiType, TChannel extends keyof ConversationDefinitions = keyof ConversationDefinitions> = TEvents extends readonly [] ? never : {
        [K in TEvents[number]]: {
            type: 'event';
            channel: TChannel;
            conversation: BaseConversationInstance<TChannel>;
            event: {
                type: K;
                payload: GetEventPayload<K>;
            } | WorkflowCallbackEventType;
            message?: never;
            workflow?: never;
            request?: never;
            state: z.infer<State>;
            client: BotClient<any>;
            execute: Autonomous.ConvoExecuteFn;
            chat: Chat;
        };
    }[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;
        chat: Chat;
    } | {
        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;
        chat: Chat;
    } : {
        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;
        chat: Chat;
    } | EventHandlerProps<TEvents, State, Channel> | {
        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;
        chat: Chat;
    } : 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;
    /**
     * 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.
     * Includes both:
     * - Integration events that are routable for the channel(s) (have conversationId)
     * - Custom events defined in agent.config.ts
     */
    export type EventSpec<TChannelSpec extends ChannelSpec> = ExtractChannel<TChannelSpec> extends keyof ConversationRoutableEvents ? readonly (ConversationRoutableEvents[ExtractChannel<TChannelSpec>][number] | EventName)[] : readonly (string | EventName)[];
    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;
        /**
         * Array of event names this conversation should listen to.
         * Supports both:
         * - Integration events with conversationId (e.g., "webchat:conversationStarted")
         * - Custom events defined in agent.config.ts (e.g., "orderPlaced")
         * By default, conversations only receive messages, not events.
         */
        events?: TEvents;
        chat?: (props: {
            context: BotContext;
            channel: ExtractChannel<TChannelSpec>;
        }) => Chat;
    };
    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