"use strict";
// =============================================================================
// Pure Agent - Telegram Platform Adapter
// Ported from Hermes gateway/platforms/telegram.py
// =============================================================================
Object.defineProperty(exports, "__esModule", { value: true });
exports.TelegramAdapter = void 0;
const config_1 = require("../config");
const base_1 = require("./base");
const logger_1 = require("../../logger");
const platform_registry_1 = require("../platform-registry");
// ---------------------------------------------------------------------------
// TelegramAdapter
// ---------------------------------------------------------------------------
class TelegramAdapter extends base_1.BasePlatformAdapter {
    _botToken;
    _pollOffset = 0;
    _pollTimer = null;
    _apiBase;
    constructor(config) {
        super(config_1.Platform.TELEGRAM, config);
        this._botToken = config.token || '';
        this._apiBase = config.extra?.api_base || 'https://api.telegram.org';
    }
    // -------------------------------------------------------------------------
    // Connection
    // -------------------------------------------------------------------------
    async connect() {
        if (!this._botToken) {
            (0, logger_1.getLogger)().error('Telegram: no bot token configured');
            return false;
        }
        try {
            // Test connection
            const me = await this._api('getMe');
            if (!me?.ok) {
                (0, logger_1.getLogger)().error(`Telegram: getMe failed: ${JSON.stringify(me)}`);
                return false;
            }
            (0, logger_1.getLogger)().info(`Telegram: connected as @${me.result.username} (${me.result.first_name})`);
            this._connected = true;
            // Start polling
            this._startPolling();
            return true;
        }
        catch (err) {
            (0, logger_1.getLogger)().error(`Telegram: connection failed: ${err.message}`);
            return false;
        }
    }
    async disconnect() {
        this._connected = false;
        if (this._pollTimer) {
            clearTimeout(this._pollTimer);
            this._pollTimer = null;
        }
        (0, logger_1.getLogger)().info('Telegram: disconnected');
    }
    // -------------------------------------------------------------------------
    // Polling
    // -------------------------------------------------------------------------
    _startPolling() {
        const poll = async () => {
            if (!this._connected)
                return;
            try {
                const updates = await this._api('getUpdates', {
                    offset: this._pollOffset,
                    timeout: 30,
                    allowed_updates: JSON.stringify(['message']),
                });
                if (updates?.ok && Array.isArray(updates.result)) {
                    for (const update of updates.result) {
                        this._pollOffset = update.update_id + 1;
                        if (update.message) {
                            this._processUpdate(update.message);
                        }
                    }
                }
            }
            catch (err) {
                (0, logger_1.getLogger)().warn(`Telegram poll error: ${err.message}`);
            }
            // Schedule next poll
            if (this._connected) {
                this._pollTimer = setTimeout(poll, 100);
            }
        };
        poll();
    }
    _processUpdate(message) {
        const text = message.text || message.caption || '';
        if (!text)
            return;
        const event = {
            text,
            messageType: message.photo ? base_1.MessageType.PHOTO :
                message.video ? base_1.MessageType.VIDEO :
                    message.voice ? base_1.MessageType.VOICE :
                        message.document ? base_1.MessageType.DOCUMENT :
                            base_1.MessageType.TEXT,
            platform: config_1.Platform.TELEGRAM,
            chatId: String(message.chat.id),
            chatName: message.chat.title || message.chat.first_name || '',
            chatType: message.chat.type === 'private' ? 'dm' :
                message.chat.type === 'group' ? 'group' : 'channel',
            userId: String(message.from?.id),
            userName: message.from?.username || message.from?.first_name || '',
            messageId: String(message.message_id),
            replyToMessageId: message.reply_to_message ? String(message.reply_to_message.message_id) : undefined,
            timestamp: message.date ? message.date * 1000 : Date.now(),
            rawMessage: message,
        };
        // Extract media URLs
        if (message.photo) {
            event.mediaUrls = [message.photo[message.photo.length - 1]?.file_id].filter(Boolean);
            event.mediaTypes = ['image/jpeg'];
        }
        this.handleMessage(event);
    }
    // -------------------------------------------------------------------------
    // Send messages
    // -------------------------------------------------------------------------
    async send(chatId, content, replyTo) {
        // Chunk long messages
        const chunks = this.truncateMessage(content, 4000);
        let lastMessageId;
        for (const chunk of chunks) {
            try {
                const params = {
                    chat_id: chatId,
                    text: chunk,
                    parse_mode: 'Markdown',
                };
                if (replyTo && !lastMessageId) {
                    params.reply_to_message_id = parseInt(replyTo, 10);
                }
                const result = await this._api('sendMessage', params);
                if (result?.ok) {
                    lastMessageId = String(result.result.message_id);
                }
                else {
                    // Retry without markdown if parsing fails
                    if (result?.description?.includes('parse')) {
                        delete params.parse_mode;
                        const retry = await this._api('sendMessage', params);
                        if (retry?.ok)
                            lastMessageId = String(retry.result.message_id);
                    }
                    else {
                        return { success: false, error: result?.description || 'Unknown error' };
                    }
                }
            }
            catch (err) {
                return { success: false, error: err.message };
            }
        }
        return { success: true, messageId: lastMessageId };
    }
    async editMessage(chatId, messageId, content) {
        try {
            const result = await this._api('editMessageText', {
                chat_id: chatId,
                message_id: parseInt(messageId, 10),
                text: content.slice(0, 4000),
                parse_mode: 'Markdown',
            });
            if (result?.ok)
                return { success: true, messageId };
            return { success: false, error: result?.description };
        }
        catch (err) {
            return { success: false, error: err.message };
        }
    }
    async deleteMessage(chatId, messageId) {
        try {
            const result = await this._api('deleteMessage', {
                chat_id: chatId,
                message_id: parseInt(messageId, 10),
            });
            return result?.ok || false;
        }
        catch {
            return false;
        }
    }
    async sendTyping(chatId) {
        await this._api('sendChatAction', { chat_id: chatId, action: 'typing' }).catch(() => { });
    }
    async sendPhoto(chatId, fileId, caption) {
        try {
            const params = {
                chat_id: chatId,
                photo: fileId,
            };
            if (caption)
                params.caption = caption.slice(0, 1024);
            const result = await this._api('sendPhoto', params);
            if (result?.ok)
                return { success: true, messageId: String(result.result.message_id) };
            return { success: false, error: result?.description };
        }
        catch (err) {
            return { success: false, error: err.message };
        }
    }
    async getChatInfo(chatId) {
        try {
            const result = await this._api('getChat', { chat_id: chatId });
            if (result?.ok) {
                const chat = result.result;
                return {
                    name: chat.title || chat.first_name || chatId,
                    type: chat.type === 'private' ? 'dm' : chat.type === 'channel' ? 'channel' : 'group',
                };
            }
        }
        catch { /* ignore */ }
        return { name: chatId, type: 'dm' };
    }
    // -------------------------------------------------------------------------
    // Telegram Bot API
    // -------------------------------------------------------------------------
    async _api(method, params) {
        const url = `${this._apiBase}/bot${this._botToken}/${method}`;
        const response = await fetch(url, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(params || {}),
            signal: AbortSignal.timeout(method === 'getUpdates' ? 60000 : 30000),
        });
        return response.json();
    }
}
exports.TelegramAdapter = TelegramAdapter;
// Auto-register
platform_registry_1.platformRegistry.register({
    name: 'telegram',
    label: 'Telegram',
    factory: (config) => new TelegramAdapter(config),
    checkFn: () => !!process.env.TELEGRAM_BOT_TOKEN,
    requiredEnv: ['TELEGRAM_BOT_TOKEN'],
    installHint: 'Set TELEGRAM_BOT_TOKEN environment variable',
    emoji: '✈️',
    maxMessageLength: 4000,
});
//# sourceMappingURL=telegram.js.map