<?php
namespace App;

class Telegram {
    public static function api(string $method, array $params = []) {
        $ch = curl_init(TELEGRAM_API . $method);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        // Avoid hanging forever (critical for webhook + worker stability)
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 8);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        $res = curl_exec($ch);
        if ($res === false) throw new \RuntimeException('Telegram API transport error: ' . curl_error($ch));
        curl_close($ch);

        $j = json_decode($res, true);
        if (!is_array($j)) {
            throw new \RuntimeException('Telegram API invalid JSON response');
        }
        if (isset($j['ok']) && $j['ok'] === false) {
            $code = $j['error_code'] ?? '';
            $desc = $j['description'] ?? 'Unknown Telegram API error';
            throw new \RuntimeException('Telegram API error' . ($code !== '' ? " ({$code})" : '') . ": {$desc}");
        }
        return $j;
    }
    /**
     * پاسخ به callback query — همیشه best-effort و هرگز استثنا پرتاب نمی‌کند.
     *
     * شناسهٔ callback در تلگرام حدود ۱۵ ثانیه معتبر است و بعدش API خطای
     * «query is too old and response timeout expired» می‌دهد. این خطا نباید
     * کل هندلر را متوقف کند: در برخی نقطه‌ها پاسخ callback درست *قبل از*
     * ساخت فایل‌های خروجی زده می‌شود و پرتاب استثنا یعنی فایل‌ها اصلاً
     * ساخته نمی‌شوند.
     *
     * @return bool موفقیت پاسخ (برای لاگ؛ معمولاً می‌شود نادیده گرفت)
     */
    public static function answerCallback($cbid, string $text = ''): bool {
        try {
            self::api('answerCallbackQuery', ['callback_query_id' => $cbid, 'text' => $text]);
            return true;
        } catch (\Throwable $e) {
            return false;
        }
    }

    public static function sendMessage($chat_id, $text, $reply_to = null, $parse_mode = 'HTML', $reply_markup = null) {
        $p = ['chat_id'=>$chat_id, 'text'=>$text, 'parse_mode'=>$parse_mode];
        if ($reply_to) $p['reply_to_message_id'] = $reply_to;
        if ($reply_markup !== null) {
            // Telegram expects JSON string
            $p['reply_markup'] = json_encode($reply_markup, JSON_UNESCAPED_UNICODE);
        }
        return self::api('sendMessage', $p);
    }
    public static function sendDocument($chat_id, $file_path, $caption='') {
        $p = ['chat_id'=>$chat_id, 'caption'=>$caption];
        $p['document'] = new \CURLFile($file_path);
        return self::api('sendDocument', $p);
    }

    public static function editMessageReplyMarkup($chat_id, $message_id, array $reply_markup): array {
        return self::api('editMessageReplyMarkup', [
            'chat_id'      => $chat_id,
            'message_id'   => $message_id,
            'reply_markup' => json_encode($reply_markup, JSON_UNESCAPED_UNICODE),
        ]);
    }

    public static function editMessageText($chat_id, $message_id, string $text, string $parse_mode = 'HTML', ?array $reply_markup = null): array {
        $p = [
            'chat_id'    => $chat_id,
            'message_id' => $message_id,
            'text'       => $text,
            'parse_mode' => $parse_mode,
        ];
        if ($reply_markup !== null) {
            $p['reply_markup'] = json_encode($reply_markup, JSON_UNESCAPED_UNICODE);
        }
        return self::api('editMessageText', $p);
    }

    public static function sendPhoto($chat_id, $file_path, $caption='') {
        $p = ['chat_id'=>$chat_id, 'caption'=>$caption];
        $p['photo'] = new \CURLFile($file_path);
        return self::api('sendPhoto', $p);
    }
    public static function getFilePath($file_id): ?string {
        $info = self::api('getFile', ['file_id'=>$file_id]);
        if (!$info['ok']) return null;
        return $info['result']['file_path'] ?? null;
    }
    public static function downloadFileById($file_id, $dest_path): bool {
        $path = self::getFilePath($file_id);
        if (!$path) return false;
        $url = FILE_API . $path;

        // Use cURL with timeouts + small retry to avoid hanging the webhook/worker
        $tries = 0;
        while ($tries < 3) {
            $tries++;
            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 8);
            curl_setopt($ch, CURLOPT_TIMEOUT, 60);
            $data = curl_exec($ch);
            $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            $err  = curl_error($ch);
            curl_close($ch);

            if ($data !== false && $code >= 200 && $code < 300) {
                if (@file_put_contents($dest_path, $data) !== false) return true;
                return false;
            }

            // brief backoff
            usleep(250000);
        }

        return false;
    }
}
