export class ChannelCommandRouter {
    handlers = new Map();
    command(name, handler) {
        const normalized = normalizeChannelCommandName(name);
        if (!normalized) {
            throw new Error("Channel command name is required.");
        }
        this.handlers.set(normalized, handler);
        return this;
    }
    commands(names, handler) {
        for (const name of names) {
            this.command(name, handler);
        }
        return this;
    }
    async dispatch(message) {
        const parsed = parseChannelCommand(message.text ?? "");
        if (!parsed) {
            return { matched: false };
        }
        const handler = this.handlers.get(parsed.command);
        if (!handler) {
            return { matched: false, command: parsed.command };
        }
        const response = await handler({
            ...message,
            text: parsed.argument,
        });
        return {
            matched: true,
            command: parsed.command,
            response: response ?? undefined,
        };
    }
}
export async function deliverChannelAction(runtime, context, response) {
    return runtime.sendMessage(context, {
        text: response.html,
        fallbackText: response.plain,
        parseMode: "html",
        buttons: response.buttons,
    });
}
export function parseChannelCommand(text, options = {}) {
    const mention = options.allowBotMention === false ? "" : "(?:@\\w+)?";
    const match = text.trimStart().match(new RegExp(`^/([a-zA-Z0-9_-]+)${mention}(?:\\s+([\\s\\S]*))?$`));
    if (!match?.[1]) {
        return null;
    }
    return {
        command: normalizeChannelCommandName(match[1]),
        argument: match[2]?.trim() ?? "",
    };
}
export class InMemoryChannelRuntime {
    descriptor;
    capabilities;
    id;
    label;
    sentMessages = [];
    editedMessages = [];
    typingContexts = [];
    sentFiles = [];
    constructor(descriptor) {
        this.descriptor = descriptor;
        this.id = descriptor.id;
        this.label = descriptor.label;
        this.capabilities = new Set(descriptor.capabilities);
    }
    describe() {
        return {
            ...this.descriptor,
            capabilities: [...this.descriptor.capabilities],
        };
    }
    async sendMessage(context, message) {
        const messageId = `${this.id}-message-${this.sentMessages.length + 1}`;
        this.sentMessages.push({ context, message, messageId });
        return { messageId };
    }
    async editMessage(context, messageId, message) {
        this.editedMessages.push({ context, messageId, message });
    }
    async sendTyping(context) {
        this.typingContexts.push(context);
    }
    async sendFile(context, file) {
        const messageId = `${this.id}-file-${this.sentFiles.length + 1}`;
        this.sentFiles.push({ context, file, messageId });
        return { messageId };
    }
}
export function normalizeChannelCommandName(name) {
    return name.trim().replace(/^\//, "").toLowerCase();
}
