import type { DiscordInstrumentationMetadata } from "#public/channels/discord/index.js";
import type { SessionAuthContext } from "#channel/types.js";
import type { SessionContext } from "#public/definitions/callback-context.js";
import type { ChannelSessionOps } from "#public/definitions/channel.js";
import type { HandleMessageStreamEvent } from "#protocol/message.js";
import { type DiscordApiOptions, type DiscordApiResponse, type DiscordCredentials, type DiscordMessageBody, type DiscordPostedMessage } from "#public/channels/discord/api.js";
import { type DiscordCommandInteraction } from "#public/channels/discord/inbound.js";
import { type DiscordWebhookVerifier } from "#public/channels/discord/verify.js";
import { type JsonObject } from "#shared/json.js";
import { type Channel } from "#public/definitions/channel.js";
type EventData<T extends HandleMessageStreamEvent["type"]> = Extract<HandleMessageStreamEvent, {
    type: T;
}> extends {
    data: infer D;
} ? D : undefined;
/** Pre-dispatch Discord context passed to inbound command hooks. */
export interface DiscordContext {
    readonly discord: DiscordHandle;
}
/** Channel-owned Discord context returned by `context()`. */
export type DiscordChannelContext = DiscordContext & {
    state: DiscordChannelState;
};
/** Event-handler Discord context, including session operations. */
export interface DiscordEventContext extends DiscordChannelContext, ChannelSessionOps {
}
/** JSON-serializable Discord channel state. */
export interface DiscordChannelState {
    /** Discord channel id. */
    channelId: string | null;
    /** Discord message id once anchored, or an interaction placeholder before the first reply. */
    conversationId: string | null;
    /** Discord guild id, when the interaction was invoked in a guild. */
    guildId: string | null;
    /** Discord application id from the inbound interaction. */
    applicationId: string | null;
    /** Latest interaction token available to the channel. */
    interactionToken: string | null;
    /** Whether the channel has already edited the deferred original interaction response. */
    initialResponseSent: boolean;
    /** Whether `conversationId` is a real Discord message id. */
    hasMessageAnchor: boolean;
}
/** Discord channel credentials. */
export interface DiscordChannelCredentials extends DiscordCredentials {
    /** Custom inbound webhook verifier. When supplied, eve skips the `DISCORD_PUBLIC_KEY` fallback and delegates verification to it. */
    readonly webhookVerifier?: DiscordWebhookVerifier;
}
/** Target accepted by `receive(discord, { target })` for proactive sessions. */
export interface DiscordReceiveTarget {
    readonly channelId: string;
    readonly conversationId?: string;
    readonly initialMessage?: string | DiscordMessageBody;
}
/**
 * Result of an inbound Discord command hook. Return `null` to acknowledge the
 * interaction without dispatching the agent.
 * - `auth`: session auth context for the dispatched turn, or `null` for anonymous.
 * - `ephemeral`: when `true`, the deferred reply is visible only to the invoking user.
 * - `context`: model-visible context lines appended after the Discord context block.
 */
export type DiscordCommandResult = {
    readonly auth: SessionAuthContext | null;
    readonly ephemeral?: boolean;
    readonly context?: readonly string[];
} | null;
/** Sync or async {@link DiscordCommandResult}. */
export type DiscordCommandResultOrPromise = DiscordCommandResult | Promise<DiscordCommandResult>;
type DiscordEventHandler<T extends HandleMessageStreamEvent["type"]> = (data: EventData<T>, channel: DiscordEventContext, ctx: SessionContext) => void | Promise<void>;
type DiscordSessionFailedHandler = (data: EventData<"session.failed">, channel: DiscordEventContext) => void | Promise<void>;
/** Per-event handlers for `discordChannel({ events })`. Supplied handlers override built-in defaults per key; unspecified events keep their defaults. `session.failed` receives only `(data, channel)`; every other handler also gets the session `ctx`. */
export interface DiscordChannelEvents {
    readonly "turn.started"?: DiscordEventHandler<"turn.started">;
    readonly "actions.requested"?: DiscordEventHandler<"actions.requested">;
    readonly "action.result"?: DiscordEventHandler<"action.result">;
    readonly "message.completed"?: DiscordEventHandler<"message.completed">;
    readonly "message.appended"?: DiscordEventHandler<"message.appended">;
    readonly "input.requested"?: DiscordEventHandler<"input.requested">;
    readonly "turn.failed"?: DiscordEventHandler<"turn.failed">;
    readonly "turn.completed"?: DiscordEventHandler<"turn.completed">;
    readonly "turn.cancelled"?: DiscordEventHandler<"turn.cancelled">;
    readonly "session.failed"?: DiscordSessionFailedHandler;
    readonly "session.completed"?: DiscordEventHandler<"session.completed">;
    readonly "session.waiting"?: DiscordEventHandler<"session.waiting">;
    readonly "authorization.required"?: DiscordEventHandler<"authorization.required">;
    readonly "authorization.completed"?: DiscordEventHandler<"authorization.completed">;
}
/** Configuration for {@link discordChannel}. */
export interface DiscordChannelConfig {
    readonly api?: Omit<DiscordApiOptions, "credentials">;
    readonly credentials?: DiscordChannelCredentials;
    /** Override the default interaction route path (`/eve/v1/discord`). */
    readonly route?: string;
    /** Inbound command hook. Defaults to user-scoped Discord auth and dispatch. Return `{ auth }` to dispatch, or `null` to acknowledge without running the agent. */
    onCommand?(ctx: DiscordContext, interaction: DiscordCommandInteraction): DiscordCommandResultOrPromise;
    readonly events?: DiscordChannelEvents;
}
/** Low-level Discord handle exposed to hooks and event handlers. */
export interface DiscordHandle {
    /** Discord application id when known. */
    readonly applicationId: string | undefined;
    /** Discord channel id. */
    readonly channelId: string;
    /** Current eve conversation id, usually the Discord anchor message id. */
    readonly conversationId: string;
    /** Discord guild id when known. */
    readonly guildId: string | undefined;
    /** Latest Discord interaction token when known. */
    readonly interactionToken: string | undefined;
    /** Raw Discord API escape hatch. */
    request(path: string, body: JsonObject, options?: DiscordRequestOptions): Promise<DiscordApiResponse>;
    /** Posts to the current conversation: interaction response or followup when an interaction token and application id exist, else a channel message. Splits over-length content, returning the first. */
    post(message: string | DiscordMessageBody): Promise<DiscordPostedMessage>;
    /** Sends a bot-authenticated message to this Discord channel. */
    sendChannelMessage(message: string | DiscordMessageBody): Promise<DiscordPostedMessage>;
    /** Edits the deferred original interaction response. */
    editOriginalResponse(message: string | DiscordMessageBody): Promise<DiscordPostedMessage>;
    /** Creates an interaction followup message. */
    followup(message: string | DiscordMessageBody): Promise<DiscordPostedMessage>;
    /** Triggers Discord's short-lived typing indicator. Ignores any failure. */
    startTyping(): Promise<void>;
}
/** Options for {@link DiscordHandle.request}. */
export interface DiscordRequestOptions {
    /** When `true`, attaches bot-token authorization; otherwise the raw request runs unauthenticated, suiting interaction webhook endpoints. */
    readonly botAuth?: boolean;
    /** HTTP method for the raw request. Defaults to `POST`. */
    readonly method?: "DELETE" | "GET" | "PATCH" | "POST" | "PUT";
}
/** Concrete return type of {@link discordChannel}. */
export interface DiscordChannel extends Channel<DiscordChannelState, DiscordReceiveTarget, DiscordInstrumentationMetadata> {
}
/** Discord channel factory for HTTP Interactions and proactive channel messages. */
export declare function discordChannel(config?: DiscordChannelConfig): DiscordChannel;
export {};
