import { Activity, IMessageActivity, IAdaptiveCardActionInvokeActivity, ITaskFetchInvokeActivity, TaskModuleResponse, ITaskSubmitInvokeActivity, IMessageReactionActivity } from '@microsoft/teams.api'; import { IHttpServerAdapter, HttpMethod, HttpRouteHandler, App, IActivityContext, IStreamer } from '@microsoft/teams.apps'; import { Logger, WebhookOptions, BaseFormatConverter, AdapterPostableMessage, Root, FetchOptions, FetchResult, ChannelInfo, ThreadInfo, ListThreadsOptions, ListThreadsResult, CardElement, Adapter, ChatInstance, Message, Attachment, UserInfo, RawMessage, FileUpload, EmojiValue, StreamChunk, StreamOptions, FormattedContent } from 'chat'; import { Client } from '@microsoft/teams.graph'; import { AdaptiveCard } from '@microsoft/teams.cards'; /** * BridgeHttpAdapter — a virtual IHttpServerAdapter that captures the route * handler registered by App.initialize() and exposes dispatch() for * handleWebhook() to call. We never own the HTTP server. * * Also manages per-request WebhookOptions so event handlers can retrieve * the correct options for their activity without shared mutable state. */ declare class BridgeHttpAdapter implements IHttpServerAdapter { private handler; private readonly webhookOptionsMap; private readonly logger; constructor(logger: Logger); registerRoute(_method: HttpMethod, _path: string, handler: HttpRouteHandler): void; dispatch(request: Request, options?: WebhookOptions): Promise; getWebhookOptions(activityId: string | undefined): WebhookOptions | undefined; } /** * Teams-specific format conversion using AST-based parsing. * * Teams supports a subset of HTML for formatting: * - Bold: or * - Italic: or * - Strikethrough: or * - Links: text * - Code:
 and 
 *
 * Teams also accepts standard markdown in most cases.
 */

declare class TeamsFormatConverter extends BaseFormatConverter {
    /**
     * Convert @mentions to Teams format in plain text.
     * @name → name
     */
    private convertMentionsToTeams;
    /**
     * Override renderPostable to convert @mentions in plain strings.
     */
    renderPostable(message: AdapterPostableMessage): string;
    /**
     * Render an AST to Teams format.
     * Teams accepts standard markdown, so we just stringify cleanly.
     */
    fromAst(ast: Root): string;
    /**
     * Parse Teams message into an AST.
     * Converts Teams HTML/mentions to standard markdown format.
     */
    toAst(teamsText: string): Root;
    private nodeToTeams;
    /**
     * Render an mdast table node as a GFM markdown table.
     * Teams renders markdown tables natively.
     */
    private tableToGfm;
}

interface TeamsAuthCertificate {
    /** PEM-encoded certificate private key */
    certificatePrivateKey: string;
    /** Hex-encoded certificate thumbprint (optional when x5c is provided) */
    certificateThumbprint?: string;
    /** Public certificate for subject-name validation (optional) */
    x5c?: string;
}
/** Federated (workload identity) authentication config */
interface TeamsAuthFederated {
    /** Audience for the federated credential (defaults to api://AzureADTokenExchange) */
    clientAudience?: string;
    /** Client ID for the managed identity assigned to the bot */
    clientId: string;
}
interface TeamsAdapterConfig {
    /** Override the Teams Bot Framework service URL (e.g. for GCC-High environments). Defaults to TEAMS_API_URL env var. */
    apiUrl?: string;
    /** Microsoft App ID. Defaults to TEAMS_APP_ID env var. */
    appId?: string;
    /** Microsoft App Password. Defaults to TEAMS_APP_PASSWORD env var. */
    appPassword?: string;
    /** Microsoft App Tenant ID. Defaults to TEAMS_APP_TENANT_ID env var. */
    appTenantId?: string;
    /** Microsoft App Type */
    appType?: "MultiTenant" | "SingleTenant";
    /** @deprecated Certificate auth is not yet supported by the Teams SDK. Throws at startup. */
    certificate?: TeamsAuthCertificate;
    /** Timeout in ms for the handler to call openModal() after a task/fetch trigger. Defaults to 5000. */
    dialogOpenTimeoutMs?: number;
    /** Federated (workload identity) authentication. Maps to managedIdentityClientId in the Teams SDK. */
    federated?: TeamsAuthFederated;
    /** Logger instance for error reporting. Defaults to ConsoleLogger. */
    logger?: Logger;
    /** Override bot username (optional) */
    userName?: string;
}
/** Teams-specific thread ID data */
interface TeamsThreadId {
    conversationId: string;
    replyToId?: string;
    serviceUrl: string;
}
/** Teams channel context extracted from activity.channelData */
interface TeamsChannelContext {
    channelId: string;
    teamId: string;
    /** Discriminator — absent for channel (backwards-compat with existing cache). */
    type?: "channel";
}
/** DM context with the resolved Graph API chat ID */
interface TeamsDmContext {
    graphChatId: string;
    type: "dm";
}
/**
 * Discriminated union for Graph API resolution context.
 * Group chats are not included — their conversation ID works as-is with Graph.
 */
type TeamsGraphContext = TeamsChannelContext | TeamsDmContext;

/**
 * Graph API chat message — uses the shape returned by @microsoft/teams.graph-endpoints.
 * Nullable fields are accessed via `??` / `||` at usage sites.
 */
/** Infer the chat message type from the graph-endpoints list response */
type ChatMessageListResponse = Awaited>>;
type GraphMessage = NonNullable[number];
interface TeamsGraphReaderDeps {
    botId: string;
    formatConverter: TeamsFormatConverter;
    getGraphContext: (baseConversationId: string) => Promise;
    graph: Client;
    logger: Logger;
}
declare class TeamsGraphReader {
    private readonly deps;
    constructor(deps: TeamsGraphReaderDeps);
    /**
     * Resolve the Graph API chat ID for a non-channel conversation.
     * Uses the DM context's graphChatId if available, otherwise falls back to
     * the raw conversation ID (works for group chats).
     */
    private chatIdFromContext;
    fetchMessages(threadId: string, options?: FetchOptions): Promise>;
    fetchChannelMessages(channelId: string, options?: FetchOptions): Promise>;
    fetchChannelInfo(channelId: string): Promise;
    fetchThread(threadId: string): Promise;
    listThreads(channelId: string, options?: ListThreadsOptions): Promise>;
    private fetchChannelThreadMessages;
    /**
     * Fetch all replies for a channel message, following pagination.
     */
    private fetchAllChannelReplies;
    /**
     * Follow a Graph API @odata.nextLink URL for pagination.
     * Uses the graph client's HTTP client directly to avoid URL re-encoding issues.
     */
    private graphGetNextLink;
    extractTextFromGraphMessage(msg: GraphMessage): string;
    extractCardTitle(card: unknown): string | null;
    private extractAttachmentsFromGraphMessage;
    private mapGraphMessages;
}

/**
 * Teams Adaptive Card converter for cross-platform cards.
 *
 * Converts CardElement to Microsoft Adaptive Cards format.
 * @see https://adaptivecards.io/
 */

/**
 * Convert a CardElement to a Teams Adaptive Card.
 */
declare function cardToAdaptiveCard(card: CardElement): AdaptiveCard;
/**
 * Generate fallback text from a card element.
 * Used when adaptive cards aren't supported.
 */
declare function cardToFallbackText(card: CardElement): string;

declare function encodeThreadId(platformData: TeamsThreadId): string;
declare function decodeThreadId(threadId: string): TeamsThreadId;
declare function isDM(threadId: string): boolean;

/** Data payload from an Action.Submit button click. */
interface ActionSubmitData {
    actionId?: string;
    value?: string;
}
declare class TeamsAdapter implements Adapter {
    readonly name = "teams";
    readonly userName: string;
    readonly botUserId?: string;
    protected readonly app: App;
    protected readonly bridgeAdapter: BridgeHttpAdapter;
    protected chat: ChatInstance | null;
    protected readonly logger: Logger;
    protected readonly formatConverter: TeamsFormatConverter;
    protected readonly config: TeamsAdapterConfig;
    protected readonly graphReader: TeamsGraphReader;
    private readonly activeStreams;
    constructor(config?: TeamsAdapterConfig);
    /**
     * Register TeamsSDK event handlers.
     * Called from initialize() after this.chat is set.
     */
    protected registerEventHandlers(): void;
    /**
     * Cache serviceUrl, tenantId, and channel context from activity metadata.
     * Called inline from each event handler (not middleware).
     */
    protected cacheUserContext(activity: Activity): void;
    /**
     * Look up cached Graph context (channel or DM), resolving via Bot API if needed.
     */
    protected getGraphContext(baseConversationId: string): Promise;
    /**
     * Handle message activities (normal messages + Action.Submit button clicks).
     *
     * For DMs we block the handler until chat processing completes so that
     * ctx.stream (the Teams SDK's native IStreamer) stays alive for streaming.
     * The Teams SDK auto-closes the stream after the handler returns.
     */
    protected handleMessageActivity(ctx: IActivityContext): Promise;
    /**
     * Handle Action.Submit button clicks sent as message activities.
     */
    protected handleMessageAction(activity: Activity, actionValue: ActionSubmitData): void;
    /**
     * Handle adaptive card button clicks (invoke-based).
     */
    protected handleAdaptiveCardAction(ctx: IActivityContext): Promise;
    /**
     * Fan out an auto-submit payload into individual onAction calls.
     * Called when the sentinel __auto_submit action ID is detected.
     * Each input key/value pair is dispatched as a separate action in parallel.
     */
    protected fanOutAutoSubmit(payload: Record, activity: Activity, threadId: string): void;
    /**
     * Handle dialog.open (task/fetch) invoke.
     * Uses Promise.race to resolve as soon as onOpenModal fires.
     */
    protected handleDialogOpen(ctx: IActivityContext): Promise;
    /**
     * Handle dialog.submit (task/submit) invoke.
     */
    protected handleDialogSubmit(ctx: IActivityContext): Promise;
    /**
     * Handle Teams reaction events.
     */
    protected handleReactionFromContext(ctx: IActivityContext): void;
    protected parseTeamsMessage(activity: Activity, threadId: string): Message;
    protected createAttachment(att: {
        contentType?: string;
        contentUrl?: string;
        name?: string;
    }): Attachment;
    protected createFetchDataFn(url: string): () => Promise;
    rehydrateAttachment(attachment: Attachment): Attachment;
    protected normalizeMentions(text: string): string;
    initialize(chat: ChatInstance): Promise;
    handleWebhook(request: Request, options?: WebhookOptions): Promise;
    getUser(userId: string): Promise;
    postMessage(threadId: string, message: AdapterPostableMessage): Promise>;
    protected filesToAttachments(files: FileUpload[]): Promise>;
    editMessage(threadId: string, messageId: string, message: AdapterPostableMessage): Promise>;
    deleteMessage(threadId: string, messageId: string): Promise;
    addReaction(_threadId: string, _messageId: string, _emoji: EmojiValue | string): Promise;
    removeReaction(_threadId: string, _messageId: string, _emoji: EmojiValue | string): Promise;
    startTyping(threadId: string, _status?: string): Promise;
    /**
     * Stream responses using the Teams SDK's native streaming protocol when
     * an active IStreamer exists (DMs), falling back to a buffered final message otherwise.
     */
    stream(threadId: string, textStream: AsyncIterable, _options?: StreamOptions): Promise>;
    /**
     * Native streaming using the Teams SDK's IStreamer.emit().
     * Sends typing activities with streamType: 'streaming', then a final
     * message with streamType: 'final' on close (handled by the framework).
     *
     * We do NOT call stream.close() — the Teams SDK calls it automatically
     * after the handler returns.
     */
    protected streamViaEmit(threadId: string, textStream: AsyncIterable, stream: IStreamer): Promise>;
    openDM(userId: string): Promise;
    fetchMessages(threadId: string, options?: FetchOptions): Promise>;
    fetchThread(threadId: string): Promise;
    channelIdFromThreadId(threadId: string): string;
    fetchChannelMessages(channelId: string, options?: FetchOptions): Promise>;
    listThreads(channelId: string, options?: ListThreadsOptions): Promise>;
    fetchChannelInfo(channelId: string): Promise;
    postChannelMessage(channelId: string, message: AdapterPostableMessage): Promise>;
    encodeThreadId(platformData: TeamsThreadId): string;
    isDM(threadId: string): boolean;
    decodeThreadId(threadId: string): TeamsThreadId;
    parseMessage(raw: unknown): Message;
    protected isMessageFromSelf(activity: Activity): boolean;
    renderFormatted(content: FormattedContent): string;
}
declare function createTeamsAdapter(config?: TeamsAdapterConfig): TeamsAdapter;

export { TeamsAdapter, type TeamsAdapterConfig, type TeamsAuthCertificate, type TeamsAuthFederated, TeamsFormatConverter, type TeamsThreadId, cardToAdaptiveCard, cardToFallbackText, createTeamsAdapter, decodeThreadId, encodeThreadId, isDM };