"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TelegramPoller = void 0;
exports.startTelegramPoller = startTelegramPoller;
const undici_1 = require("undici");
const logger_js_1 = require("./utils/logger.js");
const log = (0, logger_js_1.createModuleLogger)('telegram-poller');
const TELEGRAM_API_BASE = 'https://api.telegram.org/bot';
const POLL_TIMEOUT = 30; // seconds
class TelegramPoller {
    pollers = new Map();
    modules;
    active = false;
    syncInterval;
    constructor(modules) {
        this.modules = modules;
    }
    addBot(characterId, token) {
        if (this.pollers.has(characterId))
            return;
        const entry = { token, characterId, offset: 0, running: false };
        this.pollers.set(characterId, entry);
        log.info({ characterId }, 'Bot added to poller');
        if (this.active) {
            this.pollLoop(entry);
        }
    }
    removeBot(characterId) {
        const entry = this.pollers.get(characterId);
        if (entry) {
            entry.running = false;
            this.pollers.delete(characterId);
            log.info({ characterId }, 'Bot removed from poller');
        }
    }
    start() {
        this.active = true;
        // Initial sync
        this.syncBots();
        // Periodic sync every 10 seconds
        this.syncInterval = setInterval(() => this.syncBots(), 10000);
        for (const entry of this.pollers.values()) {
            if (!entry.running) {
                this.pollLoop(entry);
            }
        }
        log.info({ botCount: this.pollers.size }, 'Telegram poller started');
    }
    stop() {
        this.active = false;
        if (this.syncInterval) {
            clearInterval(this.syncInterval);
            this.syncInterval = undefined;
        }
        for (const entry of this.pollers.values()) {
            entry.running = false;
        }
        log.info('Telegram poller stopped');
    }
    async syncBots() {
        const activeBots = this.modules.telegramManager.getActiveBots();
        for (const [characterId] of activeBots) {
            if (!this.pollers.has(characterId)) {
                const token = await this.modules.encryptedStore.getKey(`bot-token:${characterId}`);
                if (token) {
                    this.addBot(characterId, token);
                }
            }
        }
        // Remove bots that are no longer active
        for (const [characterId] of this.pollers) {
            if (!activeBots.has(characterId)) {
                this.removeBot(characterId);
            }
        }
    }
    async pollLoop(entry) {
        entry.running = true;
        log.info({ characterId: entry.characterId }, 'Starting poll loop');
        // Delete webhook before starting polling (Telegram doesn't allow both)
        try {
            const deleteUrl = `${TELEGRAM_API_BASE}${entry.token}/deleteWebhook`;
            await (0, undici_1.fetch)(deleteUrl, { method: 'POST' });
            log.info({ characterId: entry.characterId }, 'Webhook deleted for polling mode');
        }
        catch (err) {
            log.warn({ characterId: entry.characterId, error: err.message }, 'Failed to delete webhook');
        }
        while (entry.running && this.active) {
            try {
                const url = `${TELEGRAM_API_BASE}${entry.token}/getUpdates`;
                const response = await (0, undici_1.fetch)(url, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        offset: entry.offset,
                        timeout: POLL_TIMEOUT,
                        allowed_updates: ['message', 'pre_checkout_query'],
                    }),
                    signal: AbortSignal.timeout((POLL_TIMEOUT + 5) * 1000),
                });
                const data = await response.json();
                if (!data.ok || !data.result) {
                    log.warn({ characterId: entry.characterId }, 'getUpdates returned not ok');
                    await sleep(3000);
                    continue;
                }
                for (const update of data.result) {
                    entry.offset = update.update_id + 1;
                    // Route through existing webhook handler
                    const webhookHandler = this.modules.telegramManager.getWebhookHandler();
                    try {
                        await webhookHandler.handleTelegramWebhook(entry.token, update);
                        log.debug({ characterId: entry.characterId, updateId: update.update_id }, 'Update processed');
                    }
                    catch (err) {
                        log.error({ characterId: entry.characterId, updateId: update.update_id, error: err.message }, 'Failed to process update');
                    }
                }
                if (data.result.length > 0) {
                    log.info({ characterId: entry.characterId, count: data.result.length }, 'Processed updates');
                }
            }
            catch (err) {
                if (err.name === 'TimeoutError' || err.name === 'AbortError') {
                    // Normal timeout, just continue
                    continue;
                }
                log.error({ characterId: entry.characterId, error: err.message }, 'Poll error');
                await sleep(5000);
            }
        }
        entry.running = false;
        log.info({ characterId: entry.characterId }, 'Poll loop stopped');
    }
}
exports.TelegramPoller = TelegramPoller;
function sleep(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms));
}
function startTelegramPoller(modules) {
    const poller = new TelegramPoller(modules);
    return poller;
}
//# sourceMappingURL=telegram-poller.js.map