"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TelegramManager = void 0;
const index_js_1 = require("../../utils/index.js");
const bot_client_js_1 = require("./bot-client.js");
const webhook_handler_js_1 = require("./webhook-handler.js");
const channel_manager_js_1 = require("./channel-manager.js");
const stars_manager_js_1 = require("./stars-manager.js");
const log = (0, index_js_1.createModuleLogger)('telegram-manager');
const BOT_TOKEN_PREFIX = 'bot-token:';
class TelegramManager {
    dataStore;
    encryptedStore;
    bots = new Map();
    tokenToCharacterId = new Map();
    webhookHandler;
    channelManager;
    starsManager;
    constructor(dataStore, encryptedStore) {
        this.dataStore = dataStore;
        this.encryptedStore = encryptedStore;
        this.webhookHandler = new webhook_handler_js_1.WebhookHandler(new Set());
        this.channelManager = new channel_manager_js_1.ChannelManager(dataStore, (id) => this.getBotClient(id));
        this.starsManager = new stars_manager_js_1.StarsManager(dataStore);
    }
    // --- Bot management ---
    async addBot(characterId, token) {
        log.info({ characterId }, 'Adding bot');
        const client = new bot_client_js_1.TelegramBotClient(token);
        const botInfo = await client.getMe();
        await this.encryptedStore.setKey(`${BOT_TOKEN_PREFIX}${characterId}`, token);
        this.webhookHandler.registerToken(token);
        this.bots.set(characterId, { characterId, client, botInfo });
        this.tokenToCharacterId.set(token, characterId);
        log.info({ characterId, botUsername: botInfo.username }, 'Bot added successfully');
        return botInfo;
    }
    async removeBot(characterId) {
        log.info({ characterId }, 'Removing bot');
        const entry = this.bots.get(characterId);
        if (entry) {
            const token = await this.encryptedStore.getKey(`${BOT_TOKEN_PREFIX}${characterId}`);
            if (token) {
                try {
                    await entry.client.deleteWebhook();
                }
                catch (err) {
                    log.warn({ characterId, err }, 'Failed to delete webhook during bot removal');
                }
                this.webhookHandler.unregisterToken(token);
                this.tokenToCharacterId.delete(token);
            }
            this.bots.delete(characterId);
        }
        await this.encryptedStore.deleteKey(`${BOT_TOKEN_PREFIX}${characterId}`);
        this.channelManager.stopSchedule(characterId);
        log.info({ characterId }, 'Bot removed');
    }
    async updateBot(characterId, newToken) {
        log.info({ characterId }, 'Updating bot token');
        await this.removeBot(characterId);
        return this.addBot(characterId, newToken);
    }
    async validateBot(characterId) {
        const entry = this.bots.get(characterId);
        if (!entry) {
            throw new Error(`No bot found for character ${characterId}`);
        }
        const botInfo = await entry.client.getMe();
        entry.botInfo = botInfo;
        return botInfo;
    }
    getBotClient(characterId) {
        return this.bots.get(characterId)?.client;
    }
    getCharacterIdByToken(botToken) {
        return this.tokenToCharacterId.get(botToken);
    }
    // --- Webhook management ---
    async setupWebhook(characterId, baseUrl) {
        const entry = this.bots.get(characterId);
        if (!entry) {
            throw new Error(`No bot found for character ${characterId}`);
        }
        const token = await this.encryptedStore.getKey(`${BOT_TOKEN_PREFIX}${characterId}`);
        if (!token) {
            throw new Error(`No token found for character ${characterId}`);
        }
        const webhookUrl = `${baseUrl}/api/v1/webhooks/telegram/${token}`;
        await entry.client.setWebhook(webhookUrl);
        log.info({ characterId }, 'Webhook set up');
    }
    async removeWebhook(characterId) {
        const entry = this.bots.get(characterId);
        if (!entry) {
            throw new Error(`No bot found for character ${characterId}`);
        }
        await entry.client.deleteWebhook();
        log.info({ characterId }, 'Webhook removed');
    }
    getWebhookHandler() {
        return this.webhookHandler;
    }
    // --- Channel management ---
    getChannelManager() {
        return this.channelManager;
    }
    // --- Stars management ---
    getStarsManager() {
        return this.starsManager;
    }
    // --- Lifecycle ---
    async start() {
        log.info('Starting TelegramManager');
        const keys = await this.encryptedStore.listKeys();
        const botKeys = keys.filter((k) => k.name.startsWith(BOT_TOKEN_PREFIX));
        for (const key of botKeys) {
            const characterId = key.name.slice(BOT_TOKEN_PREFIX.length);
            try {
                const token = await this.encryptedStore.getKey(key.name);
                if (!token)
                    continue;
                const client = new bot_client_js_1.TelegramBotClient(token);
                let botInfo;
                try {
                    botInfo = await client.getMe();
                }
                catch (err) {
                    log.warn({ characterId, err }, 'Failed to validate bot on startup');
                }
                this.webhookHandler.registerToken(token);
                this.bots.set(characterId, { characterId, client, botInfo });
                this.tokenToCharacterId.set(token, characterId);
                log.info({ characterId, botUsername: botInfo?.username }, 'Bot loaded');
            }
            catch (err) {
                log.error({ characterId, err }, 'Failed to load bot on startup');
            }
        }
        log.info({ botCount: this.bots.size }, 'TelegramManager started');
    }
    async stop() {
        log.info('Stopping TelegramManager');
        this.channelManager.stopAllSchedules();
        for (const [characterId, entry] of this.bots) {
            try {
                await entry.client.deleteWebhook();
            }
            catch (err) {
                log.warn({ characterId, err }, 'Failed to delete webhook during shutdown');
            }
        }
        this.bots.clear();
        this.tokenToCharacterId.clear();
        log.info('TelegramManager stopped');
    }
    // --- Status ---
    getActiveBots() {
        const result = new Map();
        for (const [id, entry] of this.bots) {
            result.set(id, { characterId: entry.characterId, botInfo: entry.botInfo });
        }
        return result;
    }
    async getBotStatus(characterId) {
        const entry = this.bots.get(characterId);
        if (!entry) {
            return { active: false };
        }
        return { active: true, botInfo: entry.botInfo };
    }
}
exports.TelegramManager = TelegramManager;
//# sourceMappingURL=index.js.map