"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TelegramBotClient = void 0;
const undici_1 = require("undici");
const logger_js_1 = require("../../utils/logger.js");
const logger = (0, logger_js_1.createModuleLogger)('telegram-bot-client');
const TELEGRAM_API_BASE = 'https://api.telegram.org/bot';
const MAX_RETRIES = 3;
const INITIAL_BACKOFF_MS = 1000;
class TelegramBotClient {
    token;
    baseUrl;
    initialBackoffMs;
    constructor(token, options) {
        if (!token) {
            throw new Error('Telegram bot token is required');
        }
        this.token = token;
        this.baseUrl = `${TELEGRAM_API_BASE}${token}`;
        this.initialBackoffMs = options?.initialBackoffMs ?? INITIAL_BACKOFF_MS;
    }
    async getMe() {
        const response = await this.callApi('getMe');
        return response;
    }
    async sendMessage(chatId, text, options) {
        return this.callApi('sendMessage', {
            chat_id: chatId,
            text,
            ...options,
        });
    }
    async sendChatAction(chatId, action) {
        return this.callApi('sendChatAction', {
            chat_id: chatId,
            action,
        });
    }
    async sendPaidMedia(request) {
        return this.callApi('sendPaidMedia', { ...request });
    }
    async sendInvoice(params) {
        return this.callApi('sendInvoice', params);
    }
    async sendPhoto(chatId, photo, caption) {
        return this.callApi('sendPhoto', {
            chat_id: chatId,
            photo,
            ...(caption ? { caption } : {}),
        });
    }
    async createChatInviteLink(chatId, options) {
        return this.callApi('createChatInviteLink', {
            chat_id: chatId,
            ...options,
        });
    }
    async setWebhook(url, options) {
        return this.callApi('setWebhook', {
            url,
            ...options,
        });
    }
    async deleteWebhook() {
        return this.callApi('deleteWebhook');
    }
    async answerPreCheckoutQuery(preCheckoutQueryId, ok, errorMessage) {
        return this.callApi('answerPreCheckoutQuery', {
            pre_checkout_query_id: preCheckoutQueryId,
            ok,
            ...(errorMessage !== undefined && { error_message: errorMessage }),
        });
    }
    async callApi(method, params) {
        let lastError;
        for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
            try {
                logger.debug({ attempt, method }, 'Sending Telegram API request');
                const url = `${this.baseUrl}/${method}`;
                const fetchOptions = {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                };
                if (params !== undefined) {
                    fetchOptions.body = JSON.stringify(params);
                }
                const response = await (0, undici_1.fetch)(url, fetchOptions);
                const data = (await response.json());
                if (!data.ok) {
                    const err = new Error(`Telegram API error: ${data.error_code ?? response.status} - ${data.description ?? 'Unknown error'}`);
                    logger.warn({ status: data.error_code, attempt, description: data.description }, 'Telegram API request failed');
                    // Don't retry on client errors (4xx) except 429 (rate limit)
                    if (data.error_code !== undefined &&
                        data.error_code >= 400 &&
                        data.error_code < 500 &&
                        data.error_code !== 429) {
                        throw err;
                    }
                    lastError = err;
                }
                else {
                    logger.debug({ method }, 'Telegram API request successful');
                    return data.result;
                }
            }
            catch (error) {
                if (lastError === undefined || lastError !== error) {
                    lastError = error instanceof Error ? error : new Error(String(error));
                }
                if (lastError.message.includes('Telegram API error: 4') &&
                    !lastError.message.includes('429')) {
                    throw lastError;
                }
                logger.warn({ attempt, error: lastError.message }, 'Telegram request attempt failed');
            }
            if (attempt < MAX_RETRIES) {
                const backoff = this.initialBackoffMs * Math.pow(2, attempt - 1);
                logger.debug({ backoff, attempt }, 'Waiting before retry');
                await sleep(backoff);
            }
        }
        logger.error({ error: lastError?.message }, 'All Telegram API retry attempts exhausted');
        throw lastError ?? new Error('Telegram API request failed after all retries');
    }
}
exports.TelegramBotClient = TelegramBotClient;
function sleep(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms));
}
//# sourceMappingURL=bot-client.js.map