<?php
/**
 * Telegram API Handler
 * Version: 2.0
 * PHP: 7.4+
 */

declare(strict_types=1);

class Telegram {
    private string $token;
    private string $apiUrl;
    private static ?Telegram $instance = null;
    
    private function __construct(string $token) {
        $this->token = $token;
        $this->apiUrl = "https://api.telegram.org/bot{$token}/";
    }
    
    public static function getInstance(): Telegram {
        if (self::$instance === null) {
            self::$instance = new self(BOT_TOKEN);
        }
        return self::$instance;
    }
    
    /**
     * Call Telegram API
     */
    public function apiRequest(string $method, array $data = []): ?object {
        $ch = curl_init($this->apiUrl . $method);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $data,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_CONNECTTIMEOUT => 10
        ]);
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        
        if ($httpCode !== 200 || !$response) {
            $this->logError("API request failed: {$method}", ['http_code' => $httpCode]);
            return null;
        }
        
        return json_decode($response);
    }
    
    /**
     * Send message
     */
    public function sendMessage(
        $chatId,
        string $text,
        ?string $parseMode = 'Markdown',
        ?array $replyMarkup = null,
        ?int $replyToMessageId = null
    ): ?object {
        $data = [
            'chat_id' => $chatId,
            'text' => $text,
            'parse_mode' => $parseMode
        ];
        
        if ($replyMarkup) {
            $data['reply_markup'] = json_encode($replyMarkup);
        }
        
        if ($replyToMessageId) {
            $data['reply_to_message_id'] = $replyToMessageId;
        }
        
        return $this->apiRequest('sendMessage', $data);
    }
    
    /**
     * Edit message
     */
    public function editMessageText(
        $chatId,
        int $messageId,
        string $text,
        ?string $parseMode = 'Markdown',
        ?array $replyMarkup = null
    ): ?object {
        $data = [
            'chat_id' => $chatId,
            'message_id' => $messageId,
            'text' => $text,
            'parse_mode' => $parseMode
        ];
        
        if ($replyMarkup) {
            $data['reply_markup'] = json_encode($replyMarkup);
        }
        
        return $this->apiRequest('editMessageText', $data);
    }
    
    /**
     * Delete message
     */
    public function deleteMessage($chatId, int $messageId): ?object {
        return $this->apiRequest('deleteMessage', [
            'chat_id' => $chatId,
            'message_id' => $messageId
        ]);
    }
    
    /**
     * Forward message
     */
    public function forwardMessage($toChatId, $fromChatId, int $messageId): ?object {
        return $this->apiRequest('forwardMessage', [
            'chat_id' => $toChatId,
            'from_chat_id' => $fromChatId,
            'message_id' => $messageId
        ]);
    }
    
    /**
     * Send photo
     */
    public function sendPhoto(
        $chatId,
        $photo,
        ?string $caption = null,
        ?string $parseMode = 'Markdown',
        ?array $replyMarkup = null,
        ?int $replyToMessageId = null
    ): ?object {
        $data = [
            'chat_id' => $chatId,
            'photo' => $photo
        ];
        
        if ($caption) {
            $data['caption'] = $caption;
            $data['parse_mode'] = $parseMode;
        }
        
        if ($replyMarkup) {
            $data['reply_markup'] = json_encode($replyMarkup);
        }
        
        if ($replyToMessageId) {
            $data['reply_to_message_id'] = $replyToMessageId;
        }
        
        return $this->apiRequest('sendPhoto', $data);
    }
    
    /**
     * Get chat administrators
     */
    public function getChatAdministrators($chatId): ?array {
        $result = $this->apiRequest('getChatAdministrators', ['chat_id' => $chatId]);
        return $result->result ?? null;
    }
    
    /**
     * Get chat member
     */
    public function getChatMember($chatId, int $userId): ?object {
        $result = $this->apiRequest('getChatMember', [
            'chat_id' => $chatId,
            'user_id' => $userId
        ]);
        return $result->result ?? null;
    }
    
    /**
     * Kick chat member
     */
    public function kickChatMember($chatId, int $userId, ?int $untilDate = null): ?object {
        $data = [
            'chat_id' => $chatId,
            'user_id' => $userId
        ];
        
        if ($untilDate) {
            $data['until_date'] = $untilDate;
        }
        
        return $this->apiRequest('kickChatMember', $data);
    }
    
    /**
     * Unban chat member
     */
    public function unbanChatMember($chatId, int $userId): ?object {
        return $this->apiRequest('unbanChatMember', [
            'chat_id' => $chatId,
            'user_id' => $userId
        ]);
    }
    
    /**
     * Restrict chat member
     */
    public function restrictChatMember(
        $chatId,
        int $userId,
        array $permissions,
        ?int $untilDate = null
    ): ?object {
        $data = [
            'chat_id' => $chatId,
            'user_id' => $userId,
            'permissions' => json_encode($permissions)
        ];
        
        if ($untilDate) {
            $data['until_date'] = $untilDate;
        }
        
        return $this->apiRequest('restrictChatMember', $data);
    }
    
    /**
     * Answer callback query
     */
    public function answerCallbackQuery(
        string $callbackQueryId,
        ?string $text = null,
        bool $showAlert = false
    ): ?object {
        $data = ['callback_query_id' => $callbackQueryId];
        
        if ($text) {
            $data['text'] = $text;
        }
        
        if ($showAlert) {
            $data['show_alert'] = true;
        }
        
        return $this->apiRequest('answerCallbackQuery', $data);
    }
    
    /**
     * Pin chat message
     */
    public function pinChatMessage($chatId, int $messageId, bool $disableNotification = false): ?object {
        return $this->apiRequest('pinChatMessage', [
            'chat_id' => $chatId,
            'message_id' => $messageId,
            'disable_notification' => $disableNotification
        ]);
    }
    
    /**
     * Unpin chat message
     */
    public function unpinChatMessage($chatId): ?object {
        return $this->apiRequest('unpinChatMessage', ['chat_id' => $chatId]);
    }
    
    /**
     * Leave chat
     */
    public function leaveChat($chatId): ?object {
        return $this->apiRequest('leaveChat', ['chat_id' => $chatId]);
    }
    
    /**
     * Get chat
     */
    public function getChat($chatId): ?object {
        $result = $this->apiRequest('getChat', ['chat_id' => $chatId]);
        return $result->result ?? null;
    }
    
    /**
     * Get user profile photos
     */
    public function getUserProfilePhotos(int $userId, int $limit = 1): ?object {
        $result = $this->apiRequest('getUserProfilePhotos', [
            'user_id' => $userId,
            'limit' => $limit
        ]);
        return $result->result ?? null;
    }
    
    /**
     * Set chat permissions
     */
    public function setChatPermissions($chatId, array $permissions): ?object {
        return $this->apiRequest('setChatPermissions', [
            'chat_id' => $chatId,
            'permissions' => json_encode($permissions)
        ]);
    }
    
    /**
     * Log errors
     */
    private function logError(string $message, array $context = []): void {
        $logFile = LOGS_PATH . '/telegram_errors_' . date('Y-m-d') . '.log';
        $timestamp = date('Y-m-d H:i:s');
        $contextStr = !empty($context) ? json_encode($context, JSON_UNESCAPED_UNICODE) : '';
        file_put_contents($logFile, "[{$timestamp}] {$message} {$contextStr}\n", FILE_APPEND);
    }
}
