<?php
/**
 * Telegram Bot API client for posting images and text
 * Compatible with PHP 7.2+
 */

class TelegramBot
{
    private $botToken;
    private $baseUrl = 'https://api.telegram.org/bot';
    private $defaultChannels = [];

    public function __construct($botToken)
    {
        $this->botToken = $botToken;
    }

    /**
     * Set default channels for posting
     *
     * @param array $channels Array of channel usernames or IDs
     */
    public function setDefaultChannels($channels)
    {
        $this->defaultChannels = $channels;
    }

    /**
     * Make API request to Telegram
     *
     * @param string $method API method
     * @param array $params Parameters
     * @return array Response
     */
    private function request($method, $params = [])
    {
        $url = $this->baseUrl . $this->botToken . '/' . $method;

        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => $url,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $params,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 60,
            CURLOPT_SSL_VERIFYPEER => true,
        ]);

        $response = curl_exec($ch);
        $error = curl_error($ch);
        curl_close($ch);

        if ($error) {
            throw new RuntimeException("Telegram API error: {$error}");
        }

        $data = json_decode($response, true);

        if (!$data['ok']) {
            throw new RuntimeException("Telegram API error: " . (isset($data['description']) ? $data['description'] : 'Unknown error'));
        }

        return isset($data['result']) ? $data['result'] : [];
    }

    /**
     * Send a text message
     *
     * @param string $chatId Chat/Channel ID or username
     * @param string $text Message text
     * @param string $parseMode Parse mode (HTML, Markdown, MarkdownV2)
     * @param bool $disablePreview Disable link preview
     * @return array Message info
     */
    public function sendMessage($chatId, $text, $parseMode = 'HTML', $disablePreview = false)
    {
        return $this->request('sendMessage', [
            'chat_id' => $chatId,
            'text' => $text,
            'parse_mode' => $parseMode,
            'disable_web_page_preview' => $disablePreview,
        ]);
    }

    /**
     * Send a single photo
     *
     * @param string $chatId Chat/Channel ID
     * @param string $photo Photo URL or file_id
     * @param string $caption Photo caption
     * @param string $parseMode Parse mode for caption
     * @return array Message info
     */
    public function sendPhoto($chatId, $photo, $caption = '', $parseMode = 'HTML')
    {
        $params = [
            'chat_id' => $chatId,
            'photo' => $photo,
        ];

        if ($caption) {
            $params['caption'] = $caption;
            $params['parse_mode'] = $parseMode;
        }

        return $this->request('sendPhoto', $params);
    }

    /**
     * Send multiple photos as media group (album)
     *
     * @param string $chatId Chat/Channel ID
     * @param array $photos Array of photo URLs
     * @param string $caption Caption for first photo
     * @param string $parseMode Parse mode
     * @return array Messages info
     */
    public function sendMediaGroup($chatId, $photos, $caption = '', $parseMode = 'HTML')
    {
        $media = [];

        foreach ($photos as $index => $photo) {
            $item = [
                'type' => 'photo',
                'media' => $photo,
            ];

            // Caption only on first photo
            if ($index === 0 && $caption) {
                $item['caption'] = $caption;
                $item['parse_mode'] = $parseMode;
            }

            $media[] = $item;
        }

        return $this->request('sendMediaGroup', [
            'chat_id' => $chatId,
            'media' => json_encode($media),
        ]);
    }

    /**
     * Post photos with text to a channel
     * Smart method that chooses best approach based on content
     *
     * @param string $chatId Chat/Channel ID
     * @param array $photos Array of photo URLs
     * @param string $text Post text
     * @param string $parseMode Parse mode
     * @return array Result info
     */
    public function post($chatId, $photos, $text = '', $parseMode = 'HTML')
    {
        $photoCount = count($photos);

        // Text only
        if ($photoCount === 0) {
            return ['type' => 'text', 'message' => $this->sendMessage($chatId, $text, $parseMode)];
        }

        // Single photo
        if ($photoCount === 1) {
            return ['type' => 'photo', 'message' => $this->sendPhoto($chatId, $photos[0], $text, $parseMode)];
        }

        // Multiple photos (2-10) - use media group
        if ($photoCount <= 10) {
            return ['type' => 'album', 'messages' => $this->sendMediaGroup($chatId, $photos, $text, $parseMode)];
        }

        // More than 10 photos - split into multiple albums
        $results = [];
        $chunks = array_chunk($photos, 10);

        foreach ($chunks as $index => $chunk) {
            $caption = ($index === 0) ? $text : '';
            $results[] = $this->sendMediaGroup($chatId, $chunk, $caption, $parseMode);
        }

        return ['type' => 'multiple_albums', 'messages' => $results];
    }

    /**
     * Post to multiple channels at once
     *
     * @param array $chatIds Array of Chat/Channel IDs
     * @param array $photos Array of photo URLs
     * @param string $text Post text
     * @param string $parseMode Parse mode
     * @return array Results for each channel
     */
    public function postToMultiple($chatIds, $photos, $text = '', $parseMode = 'HTML')
    {
        $results = [];

        foreach ($chatIds as $chatId) {
            try {
                $results[$chatId] = [
                    'success' => true,
                    'result' => $this->post($chatId, $photos, $text, $parseMode),
                ];
            } catch (Exception $e) {
                $results[$chatId] = [
                    'success' => false,
                    'error' => $e->getMessage(),
                ];
            }
        }

        return $results;
    }

    /**
     * Get bot info
     *
     * @return array Bot info
     */
    public function getMe()
    {
        return $this->request('getMe');
    }

    /**
     * Get chat info
     *
     * @param string $chatId Chat/Channel ID
     * @return array Chat info
     */
    public function getChat($chatId)
    {
        return $this->request('getChat', ['chat_id' => $chatId]);
    }

    /**
     * Validate that bot has access to a channel
     *
     * @param string $chatId Channel ID or username
     * @return array Validation result
     */
    public function validateChannel($chatId)
    {
        try {
            $chat = $this->getChat($chatId);
            return [
                'valid' => true,
                'title' => isset($chat['title']) ? $chat['title'] : (isset($chat['username']) ? $chat['username'] : $chatId),
                'type' => $chat['type'],
            ];
        } catch (Exception $e) {
            return [
                'valid' => false,
                'error' => $e->getMessage(),
            ];
        }
    }

    /**
     * Format text for Telegram HTML mode
     *
     * @param string $text Plain text
     * @return string Escaped HTML
     */
    public static function escapeHtml($text)
    {
        return htmlspecialchars($text, ENT_QUOTES | ENT_HTML5, 'UTF-8');
    }

    /**
     * Format text for Telegram MarkdownV2 mode
     *
     * @param string $text Plain text
     * @return string Escaped Markdown
     */
    public static function escapeMarkdown($text)
    {
        $chars = ['_', '*', '[', ']', '(', ')', '~', '`', '>', '#', '+', '-', '=', '|', '{', '}', '.', '!'];
        foreach ($chars as $char) {
            $text = str_replace($char, '\\' . $char, $text);
        }
        return $text;
    }
}
