export function telegramMessageToInbound(message) {
    const text = message.text?.trim();
    if (!text)
        return null;
    const conversationId = String(message.chat.id);
    const senderId = String(message.from?.id ?? message.chat.id);
    const senderName = message.from?.username
        ? `@${message.from.username}`
        : message.from?.first_name;
    return {
        channelId: "telegram",
        conversationId,
        senderId,
        senderName,
        text,
        timestamp: (message.date ?? Math.floor(Date.now() / 1000)) * 1000,
        fromMe: false,
        isSelfChat: false,
    };
}
export class TelegramConnector {
    id = "telegram";
    label = "Telegram";
    deps;
    baseUrl;
    _status = "stopped";
    events = null;
    abort = null;
    offset = 0;
    constructor(deps = {}) {
        this.deps = deps;
        this.baseUrl = deps.baseUrl ?? "https://api.telegram.org";
    }
    status() { return this._status; }
    currentQr() { return null; }
    log(msg, ...args) {
        (this.deps.log ?? ((m, ...a) => console.log("[telegram]", m, ...a)))(msg, ...args);
    }
    token() {
        return this.deps.token ?? process.env.TELEGRAM_BOT_TOKEN ?? "";
    }
    setStatus(status, detail) {
        this._status = status;
        this.events?.onStatus(status, detail);
    }
    async start(events) {
        this.events = events;
        const token = this.token();
        if (!token) {
            this.setStatus("error", { error: "TELEGRAM_BOT_TOKEN is required" });
            return;
        }
        this.abort?.abort();
        this.abort = new AbortController();
        this.setStatus("connecting");
        try {
            const me = await this.api("getMe", undefined, this.abort.signal);
            if (!me.ok)
                throw new Error(me.description ?? "Telegram getMe failed");
            this.setStatus("connected");
            this.log(`connected as ${me.result?.username ?? me.result?.id ?? "bot"}`);
            void this.pollLoop();
        }
        catch (err) {
            if (this.abort.signal.aborted)
                return;
            this.setStatus("error", { error: err instanceof Error ? err.message : String(err) });
        }
    }
    async stop() {
        this.abort?.abort();
        this.abort = null;
        this.setStatus("stopped");
    }
    async send(msg) {
        if (this._status !== "connected")
            throw new Error("Telegram is not connected");
        const res = await this.api("sendMessage", {
            chat_id: msg.conversationId,
            text: msg.text,
        }, this.abort?.signal);
        if (!res.ok)
            throw new Error(res.description ?? "Telegram sendMessage failed");
    }
    async pollLoop() {
        const signal = this.abort?.signal;
        if (!signal)
            return;
        while (!signal.aborted) {
            try {
                const res = await this.api("getUpdates", {
                    timeout: this.deps.pollTimeoutSeconds ?? 25,
                    offset: this.offset,
                    allowed_updates: ["message"],
                }, signal);
                if (!res.ok)
                    throw new Error(res.description ?? "Telegram getUpdates failed");
                for (const update of res.result ?? []) {
                    this.offset = Math.max(this.offset, update.update_id + 1);
                    if (!update.message)
                        continue;
                    const inbound = telegramMessageToInbound(update.message);
                    if (inbound)
                        this.events?.onInbound(inbound);
                }
            }
            catch (err) {
                if (signal.aborted)
                    return;
                this.setStatus("error", { error: err instanceof Error ? err.message : String(err) });
                return;
            }
        }
    }
    async api(method, body, signal) {
        const token = this.token();
        const fetchImpl = this.deps.fetchImpl ?? fetch;
        const res = await fetchImpl(`${this.baseUrl}/bot${token}/${method}`, {
            method: body ? "POST" : "GET",
            headers: body ? { "Content-Type": "application/json" } : undefined,
            body: body ? JSON.stringify(body) : undefined,
            signal,
        });
        return await res.json();
    }
}
//# sourceMappingURL=connector.js.map