<?php

if (file_exists('TelegramErrorLogger.php')) {
    require_once 'TelegramErrorLogger.php';
}


class Base
{
    /**
     * Constant for type Inline Query.
     */
    const INLINE_QUERY = 'inline_query';
    /**
     * Constant for type FORWARD FROM Chat.
     */
    const forward_from_CHAT = 'forward_from_chat';
    /**
     * Constant for type Callback Query.
     */
    const CALLBACK_QUERY = 'callback_query';
    /**
     * Constant for type Edited Message.
     */
    const EDITED_MESSAGE = 'edited_message';
    /**
     * Constant for type Reply.
     */
    const REPLY = 'reply';
    /**
     * Constant for type Message.
     */
    const MESSAGE = 'message';
    /**
     * Constant for type Photo.
     */
    const PHOTO = 'photo';
    /**
     * Constant for type Video.
     */
    const VIDEO = 'video';
    /**
     * Constant for type Audio.
     */
    const AUDIO = 'audio';
    /**
     * Constant for type Voice.
     */
    const VOICE = 'voice';
    /**
     * Constant for type animation.
     */
    const ANIMATION = 'animation';
    /**
     * Constant for type Document.
     */
    const DOCUMENT = 'document';
    /**
     * Constant for type Location.
     */
    const LOCATION = 'location';
    /**
     * Constant for type Contact.
     */
    const CONTACT = 'contact';
    /**
     * Constant for type Channel Post.
     */
    const CHANNEL_POST = 'channel_post';

    const PRE_CHECKOUT_QUERY = 'pre_checkout_query';
    /**
     * Constant for type Sticker.
     */
    const STICKER = 'sticker';


    private $bot_token = '';
    private $data = [];
    private $updates = [];
    private $multi = false;
    private $log_errors;


    public function __construct($bot_token, $multi = false, $log_errors = true)
    {
        $this->bot_token = $bot_token;
        $this->multi = $multi;
        $this->data = $this->getData();
        $this->log_errors = $log_errors;
    }

    public function endpoint($api, array $content, $post = true)
    {
        $url = 'https://api.telegram.org/bot' . $this->bot_token . '/' . $api;
        if ($post) {
            $reply = $this->sendAPIRequest($url, $content);
        } else {
            $reply = $this->sendAPIRequest($url, [], false);
        }

        return json_decode($reply, true);
    }




    public function buyTonAPI($API_KEY, $count, $username)
    {
        $data = [
            "query" => $username,
            "amount" => $count,
            "show_sender" => "1"
        ];

        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => 'https://tg.parssms.info/v1/ads/topup',
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => json_encode($data),
            CURLOPT_HTTPHEADER => array(
                "api-key: $API_KEY",
                'Content-Type: application/json'
            ),
        ));

        $response = curl_exec($curl);
        curl_close($curl);
        $response = json_decode($response, true);
        return $response;
    }

    public function buyStarsAPI($API_KEY, $count, $username)
    {
        $data = [
            "query" => $username,
            "quantity" => $count,
            "show_sender" => "1"
        ];

        $curl = curl_init();

        curl_setopt_array($curl, array(
            CURLOPT_URL => 'https://tg.parssms.info/v1/stars/payment',
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => json_encode($data),
            CURLOPT_HTTPHEADER => array(
                "api-key: $API_KEY",
                'Content-Type: application/json'
            ),
        ));

        $response = curl_exec($curl);
        curl_close($curl);
        $response = json_decode($response, true);
        return $response;
    }

    public function buyPremiumAPI($API_KEY, $months, $username)
    {
        $data = [
            "query" => $username,
            "months" => $months,
            // "show_sender" => "1"
        ];

        $curl = curl_init();

        curl_setopt_array($curl, array(
            CURLOPT_URL => 'https://tg.parssms.info/v1/premium/payment',
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => json_encode($data),
            CURLOPT_HTTPHEADER => array(
                "api-key: $API_KEY",
                'Content-Type: application/json'
            ),
        ));

        $response = curl_exec($curl);
        curl_close($curl);
        $response = json_decode($response, true);
        return $response;
    }

    public function xRocketPayApi($API_KEY, $amount, $orderID, $currency = 'trx')
    {
        $data = [
            "amount" => $amount,
            "numPayments" => 1,
            "currency" => $currency,
            "description" => "orderid: $orderID",
            "commentsEnabled" => false,
            // "callbackUrl" => "$callback",
            "payload" => "$orderID",
            "expiredIn" => 60 * 10,
        ];

        $curl = curl_init();

        curl_setopt_array($curl, array(
            CURLOPT_URL => 'https://pay.xrocket.tg/tg-invoices',
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => json_encode($data),
            CURLOPT_HTTPHEADER => array(
                "Rocket-Pay-Key: $API_KEY",
                'Content-Type: application/json'
            ),
        ));

        $response = curl_exec($curl);
        curl_close($curl);
        $response = json_decode($response, true);
        return $response;
    }



    public function NOWPayments($API_KEY, $amount, $orderID, $currency = 'trx')
    {
        $data = [
            "price_amount" => $amount,
            "price_currency" => "usd",
            "pay_currency" => $currency,
            "order_id" => $orderID,
            "order_description" => "UserBalance",
        ];

        $curl = curl_init();

        curl_setopt_array($curl, array(
            CURLOPT_URL => 'https://api.nowpayments.io/v1/payment',
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => json_encode($data),
            CURLOPT_HTTPHEADER => array(
                "x-api-key: $API_KEY",
                'Content-Type: application/json'
            ),
        ));

        $response = curl_exec($curl);
        curl_close($curl);
        $response = json_decode($response, true);
        return $response;
    }


    public function VerifyNOWPayments($API_KEY, $payment_id)
    {
        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => "https://api.nowpayments.io/v1/payment/$payment_id",
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'GET',
            CURLOPT_HTTPHEADER => array(
                "x-api-key: $API_KEY"
            ),
        ));
        $response = curl_exec($curl);
        curl_close($curl);
        $response = json_decode($response, true);
        return $response;
    }

    function ip_info($ip = NULL, $purpose = "location", $deep_detect = TRUE)
    {
        $output = NULL;
        if (filter_var($ip, FILTER_VALIDATE_IP) === FALSE) {
            $ip = $_SERVER["REMOTE_ADDR"];
            if ($deep_detect) {
                if (filter_var(@$_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP))
                    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
                if (filter_var(@$_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP))
                    $ip = $_SERVER['HTTP_CLIENT_IP'];
            }
        }
        $purpose    = str_replace(array("name", "\n", "\t", " ", "-", "_"), '', strtolower(trim($purpose)));
        $support    = array("country", "countrycode", "state", "region", "city", "location", "address");
        $continents = array(
            "AF" => "Africa",
            "AN" => "Antarctica",
            "AS" => "Asia",
            "EU" => "Europe",
            "OC" => "Australia (Oceania)",
            "NA" => "North America",
            "SA" => "South America"
        );
        if (filter_var($ip, FILTER_VALIDATE_IP) && in_array($purpose, $support)) {
            $ipdat = @json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip=" . $ip));
            if (@strlen(trim($ipdat->geoplugin_countryCode)) == 2) {
                switch ($purpose) {
                    case "location":
                        $output = @$ipdat->geoplugin_countryName;
                }
            }
        }
        return $output;
    }



    public function deleteFile($fName)
    {
        $filehh = fopen($fName, "w") or die("Unable to open file!");
        fclose($filehh);
        unlink($fName);
    }
    public function deleteFolder($directory)
    {
        if (!is_dir($directory))
            return;
        $contents = scandir($directory);
        $contents = array_diff($contents, ['.', '..']);
        foreach ($contents as $object) {
            $current_object = $directory . '/' . $object;
            if (filetype($current_object) === 'dir') {
                $this->deleteFolder($current_object);
            } else {
                $this->deleteFile($current_object);
            }
        }
        rmdir($directory);
    }

    public function getMe()
    {
        return $this->endpoint('getMe', [], false);
    }

    public function getBot($TOKEN)
    {
        $json = file_get_contents('https://api.telegram.org/bot' . $TOKEN . '/getMe');
        $data = json_decode($json, true);
        return $data;
    }

    public function respondSuccess()
    {
        http_response_code(200);

        return json_encode(['status' => 'success']);
    }


    public function sendInvoice(array $content)
    {
        return $this->endpoint('sendInvoice', $content);
    }
    public function createInvoiceLink(array $content)
    {
        return $this->endpoint('createInvoiceLink', $content);
    }
    public function answerPreCheckoutQuery(array $content)
    {
        return $this->endpoint('answerPreCheckoutQuery', $content);
    }
    public function refundStarPayment(array $content)
    {
        return $this->endpoint('refundStarPayment', $content);
    }

    public function sendMessage(array $content)
    {
        return $this->endpoint('sendMessage', $content);
    }

    public function copyMessage(array $content)
    {
        return $this->endpoint('copyMessage', $content);
    }
    public function createChatInviteLink(array $content)
    {
        return $this->endpoint('createChatInviteLink', $content);
    }

    public function forwardMessage(array $content)
    {
        return $this->endpoint('forwardMessage', $content);
    }


    public function sendPhoto(array $content)
    {
        return $this->endpoint('sendPhoto', $content);
    }

    public function sendAudio(array $content)
    {
        return $this->endpoint('sendAudio', $content);
    }

    public function sendDocument(array $content)
    {
        return $this->endpoint('sendDocument', $content);
    }

    public function sendAnimation(array $content)
    {
        return $this->endpoint('sendAnimation', $content);
    }


    public function sendSticker(array $content)
    {
        return $this->endpoint('sendSticker', $content);
    }


    public function sendVideo(array $content)
    {
        return $this->endpoint('sendVideo', $content);
    }
    public function sendVideoNote(array $content)
    {
        return $this->endpoint('sendVideoNote', $content);
    }
    public function sendVoice(array $content)
    {
        return $this->endpoint('sendVoice', $content);
    }


    public function sendLocation(array $content)
    {
        return $this->endpoint('sendLocation', $content);
    }


    public function editMessageLiveLocation(array $content)
    {
        return $this->endpoint('editMessageLiveLocation', $content);
    }
    public function stopMessageLiveLocation(array $content)
    {
        return $this->endpoint('stopMessageLiveLocation', $content);
    }

    public function setChatStickerSet(array $content)
    {
        return $this->endpoint('setChatStickerSet', $content);
    }

    public function deleteChatStickerSet(array $content)
    {
        return $this->endpoint('deleteChatStickerSet', $content);
    }

    public function sendMediaGroup(array $content)
    {
        return $this->endpoint('sendMediaGroup', $content);
    }

    public function sendVenue(array $content)
    {
        return $this->endpoint('sendVenue', $content);
    }

    public function sendContact(array $content)
    {
        return $this->endpoint('sendContact', $content);
    }

    public function sendChatAction(array $content)
    {
        return $this->endpoint('sendChatAction', $content);
    }

    public function getUserProfilePhotos(array $content)
    {
        return $this->endpoint('getUserProfilePhotos', $content);
    }

    public function getFile($file_id)
    {
        $content = ['file_id' => $file_id];

        return $this->endpoint('getFile', $content);
    }

    public function kickChatMember(array $content)
    {
        return $this->endpoint('kickChatMember', $content);
    }

    public function leaveChat(array $content)
    {
        return $this->endpoint('leaveChat', $content);
    }

    public function unbanChatMember(array $content)
    {
        return $this->endpoint('unbanChatMember', $content);
    }

    public function getChat(array $content)
    {
        return $this->endpoint('getChat', $content);
    }

    public function getChatAdministrators(array $content)
    {
        return $this->endpoint('getChatAdministrators', $content);
    }

    public function getChatMembersCount(array $content)
    {
        return $this->endpoint('getChatMembersCount', $content);
    }

    public function getChatMember(array $content)
    {
        return $this->endpoint('getChatMember', $content);
    }

    public function answerInlineQuery(array $content)
    {
        return $this->endpoint('answerInlineQuery', $content);
    }


    public function setGameScore(array $content)
    {
        return $this->endpoint('setGameScore', $content);
    }

    public function answerCallbackQuery(array $content)
    {
        return $this->endpoint('answerCallbackQuery', $content);
    }

    public function editMessageText(array $content)
    {
        return $this->endpoint('editMessageText', $content);
    }

    public function editMessageCaption(array $content)
    {
        return $this->endpoint('editMessageCaption', $content);
    }

    public function editMessageReplyMarkup(array $content)
    {
        return $this->endpoint('editMessageReplyMarkup', $content);
    }
    public function editMessageMedia(array $content)
    {
        return $this->endpoint('editMessageMedia', $content);
    }

    public function downloadFile($telegram_file_path, $local_file_path)
    {
        $file_url = 'https://api.telegram.org/file/bot' . $this->bot_token . '/' . $telegram_file_path;
        $in = fopen($file_url, 'rb');
        $out = fopen($local_file_path, 'wb');

        while ($chunk = fread($in, 8192)) {
            fwrite($out, $chunk, 8192);
        }
        fclose($in);
        fclose($out);
    }
    public function setWebhook($url, $certificate = '')
    {
        if ($certificate == '') {
            $requestBody = ['url' => $url, 'drop_pending_updates' => true];
        } else {
            $requestBody = ['url' => $url, 'certificate' => "@$certificate", 'drop_pending_updates' => true];
        }

        return $this->endpoint('setWebhook', $requestBody, true);
    }


    public function webHookInfo($token)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, 'https://api.telegram.org/bot' . $token . '/getWebhookInfo');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $curl_exec = curl_exec($ch);
        return json_decode($curl_exec, true);
    }

    public function deleteWebhook()
    {
        return $this->endpoint('deleteWebhook', [], false);
    }
    public function getData()
    {
        if (empty($this->data)) {
            if ($this->multi) {
                $up = glob("update/*.update");
                if (count($up) > 0) {
                    $f = $up[count($up) - 1];
                    $rawData = file_get_contents($f);
                    unlink($f);
                } else $rawData = [];
            } else {
                $rawData = file_get_contents('php://input');
            }

            return json_decode($rawData, true);
        } else {
            return $this->data;
        }
    }

    public function setData(array $data)
    {
        $this->data = $data;
    }
    public function Text()
    {
        $type = $this->getUpdateType();
        if ($type == self::CALLBACK_QUERY) {
            return @$this->data['callback_query']['data'];
        }
        if ($type == self::CHANNEL_POST) {
            return @$this->data['channel_post']['text'];
        }
        if ($type == self::EDITED_MESSAGE) {
            return @$this->data['edited_message']['text'];
        }

        return @$this->data['message']['text'];
    }

    public function pre_checkout_query()
    {
        $type = $this->getUpdateType();
        if ($type == self::PRE_CHECKOUT_QUERY) {
            return @$this->data['pre_checkout_query'];
        }
        return @$this->data['pre_checkout_query'];
    }

    public function successful_payment()
    {
        $type = $this->getUpdateType();
        if ($type == self::MESSAGE) {
            return @$this->data['message']['successful_payment'];
        }
        return @$this->data['message']['successful_payment'];
    }

    public function Caption()
    {
        return @$this->data['message']['caption'];
    }

    public function photo()
    {
        return @$this->data['message']['photo'];
    }

    public function video_note()
    {
        return @$this->data['message']['video_note'];
    }

    public function ChatID()
    {
        $type = $this->getUpdateType();
        if ($type == self::CALLBACK_QUERY) {
            return @$this->data['callback_query']['message']['chat']['id'];
        }
        if ($type == self::CHANNEL_POST) {
            return @$this->data['channel_post']['chat']['id'];
        }
        if ($type == self::EDITED_MESSAGE) {
            return @$this->data['edited_message']['chat']['id'];
        }
        if ($type == self::INLINE_QUERY) {
            return @$this->data['inline_query']['from']['id'];
        }

        return $this->data['message']['chat']['id'];
    }

    public function MessageID()
    {
        $type = $this->getUpdateType();
        if ($type == self::CALLBACK_QUERY) {
            return @$this->data['callback_query']['message']['message_id'];
        }
        if ($type == self::CHANNEL_POST) {
            return @$this->data['channel_post']['message_id'];
        }
        if ($type == self::EDITED_MESSAGE) {
            return @$this->data['edited_message']['message_id'];
        }

        return $this->data['message']['message_id'];
    }

    public function ReplyToMessageID()
    {
        $type = $this->getUpdateType();
        if ($type == self::CHANNEL_POST) {
            return $this->data['channel_post']['reply_to_message']['message_id'];
        }
        return $this->data['message']['reply_to_message']['message_id'];
    }

    public function ReplyToMessageFromUserID()
    {
        return $this->data['message']['reply_to_message']['forward_from']['id'];
    }

    /// Get the inline_query of the current update

    /**
     * \return the Array inline_query.
     */
    public function Inline_Query()
    {
        return $this->data['inline_query']['query'];
    }
    public function Inline_Queryid()
    {
        return $this->data['inline_query']['id'];
    }
    public function Inline_Queryfromid()
    {
        return $this->data['inline_query']['from']['id'];
    }
    public function ReplyToMessagetxt()
    {
        return $this->data['message']['reply_to_message']['text'];
    }

    public function phone()
    {
        return $this->data['message']['contact'];
    }

    public function phoneho()
    {
        return $this->data['message']['contact']['user_id'];
    }
    public function LinkType()
    {
        return $this->data['message']['entities'][0]['type'];
    }
    public function LinkUrl()
    {
        return $this->data['message']['entities'][0]['url'];
    }
    public function phonenu()
    {
        return $this->data['message']['contact']['phone_number'];
    }
    public function documentid()
    {
        return $this->data['message']['document']['file_id'];
    }
    public function video_noteid()
    {
        return $this->data['message']['video_note']['file_id'];
    }
    public function stickerid()
    {
        return $this->data['message']['sticker']['file_id'];
    }
    public function gifid()
    {
        return $this->data['message']['animation']['file_id'];
    }
    public function audioid()
    {
        return $this->data['message']['audio']['file_id'];
    }
    public function voiceid()
    {
        return $this->data['message']['voice']['file_id'];
    }
    public function videoid()
    {
        return $this->data['message']['video']['file_id'];
    }
    public function photoid()
    {
        return $this->data['message']['photo'][0]['file_id'];
    }

    /// Get the callback_query of the current update

    /**
     * \return the String callback_query.
     */
    public function Callback_Query()
    {
        return $this->data['callback_query'];
    }

    //// Get the callback_query id of the current update

    /**
     * \return the String callback_query id.
     */
    public function CallbackQueryID()
    {
        return $this->data['callback_query']['id'];
    }

    /// Get the Get the data of the current callback

    /**
     * \deprecated Use Text() instead
     * \return the String callback_data.
     */
    public function Callback_Data()
    {
        return $this->data['callback_query']['data'];
    }

    public function Callback_Data_Id()
    {
        return $this->data['callback_query']['id'];
    }

    /// Get the Get the message of the current callback

    /**
     * \return the Message.
     */
    public function Callback_Message()
    {
        return $this->data['callback_query']['message'];
    }

    /// Get the Get the chati_id of the current callback

    /**
     * \deprecated Use ChatId() instead
     * \return the String callback_query.
     */
    public function Callback_ChatID()
    {
        return $this->data['callback_query']['message']['chat']['id'];
    }

    /// Get the date of the current message

    /**
     * \return the String message's date.
     */
    public function Date()
    {
        return $this->data['message']['date'];
    }

    /// Get the first name of the user
    public function FirstName()
    {
        $type = $this->getUpdateType();
        if ($type == self::CALLBACK_QUERY) {
            return @$this->data['callback_query']['from']['first_name'];
        }
        if ($type == self::CHANNEL_POST) {
            return @$this->data['channel_post']['from']['first_name'];
        }
        if ($type == self::EDITED_MESSAGE) {
            return @$this->data['edited_message']['from']['first_name'];
        }

        return @$this->data['message']['from']['first_name'];
    }

    /// Get the last name of the user
    public function LastName()
    {
        $type = $this->getUpdateType();
        if ($type == self::CALLBACK_QUERY) {
            return @$this->data['callback_query']['from']['last_name'];
        }
        if ($type == self::CHANNEL_POST) {
            return @$this->data['channel_post']['from']['last_name'];
        }
        if ($type == self::EDITED_MESSAGE) {
            return @$this->data['edited_message']['from']['last_name'];
        }

        return @$this->data['message']['from']['last_name'];
    }

    /// Get the username of the user
    public function Username()
    {
        $type = $this->getUpdateType();
        if ($type == self::CALLBACK_QUERY) {
            return @$this->data['callback_query']['from']['username'];
        }
        if ($type == self::CHANNEL_POST) {
            return @$this->data['channel_post']['chat']['username'];
        }
        if ($type == self::EDITED_MESSAGE) {
            return @$this->data['edited_message']['from']['username'];
        }

        return @$this->data['message']['chat']['username'];
    }

    public function sendsms($mobile, $templateId, $parameters)
    {
        $api = "FQMeqakJ20Vfn1x6R7jgkpyGhdpoMqtrO0p4hKut7KalCuUy";
        $url = "https://api.sms.ir/v1/send/verify";

        $data = [
            'mobile' => $mobile,
            'templateId' => $templateId,
            'parameters' => $parameters,
        ];
        $headers = [
            "Content-Type: application/json",
            "Accept: application/json",
            "x-api-key: $api"
        ];
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

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

        return json_decode($response, true);
    }

    public function Title()
    {
        $type = $this->getUpdateType();

        if ($type == self::CHANNEL_POST) {
            return @$this->data['channel_post']['chat']['title'];
        }
        return @$this->data['message']['chat']['title'];
    }

    public function Type()
    {
        $type = $this->getUpdateType();

        if ($type == self::CHANNEL_POST) {
            return @$this->data['channel_post']['chat']['type'];
        }
        return @$this->data['message']['chat']['type'];
    }

    /// Get the location in the message
    public function Location()
    {
        return $this->data['message']['location'];
    }

    /// Get the update_id of the message
    public function UpdateID()
    {
        return $this->data['update_id'];
    }

    /// Get the number of updates
    public function UpdateCount()
    {
        return count($this->updates['result']);
    }

    /// Get user's id of current message
    public function UserID()
    {
        $type = $this->getUpdateType();
        if ($type == self::CALLBACK_QUERY) {
            return $this->data['callback_query']['from']['id'];
        }
        if ($type == self::CHANNEL_POST) {
            return $this->data['channel_post']['from']['id'];
        }
        if ($type == self::EDITED_MESSAGE) {
            return @$this->data['edited_message']['from']['id'];
        }

        return $this->data['message']['from']['id'];
    }

    /// Get user's id of current forwarded message
    public function FromID()
    {
        return $this->data['message']['forward_from']['id'];
    }


    /// Get chat's id where current message forwarded from
    public function FromChatID()
    {
        return $this->data['message']['forward_from_chat']['id'];
    }
    public function FromChatUsername()
    {
        return $this->data['message']['forward_from_chat']['username'];
    }
    public function FromChatType()
    {
        return $this->data['message']['forward_from_chat']['type'];
    }
    public function FromChatTitle()
    {
        return $this->data['message']['forward_from_chat']['title'];
    }
    /// Tell if a message is from a group or user chat

    /**
     *  \return BOOLEAN true if the message is from a Group chat, false otherwise.
     */
    public function messageFromGroup()
    {
        if ($this->data['message']['chat']['type'] == 'private') {
            return false;
        }

        return true;
    }
    public function random()
    {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        return substr(str_shuffle($chars), 0, 5);
    }



    public function zarinPall($merchant_id, $amount, $callback_url, $order_id)
    {
        $data = array(
            "merchant_id" => $merchant_id,
            "amount" => $amount,
            "callback_url" => $callback_url,
            "description" => "سفارش شماره $order_id",
            "currency" => 'IRT',
        );
        $jsonData = json_encode($data);
        // $ch = curl_init('https://sandbox.zarinpal.com/pg/v4/payment/request.json');
        $ch = curl_init('https://api.zarinpal.com/pg/v4/payment/request.json');
        curl_setopt($ch, CURLOPT_USERAGENT, 'ZarinPal Rest Api v1');
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
        curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Content-Type: application/json',
            'Content-Length: ' . strlen($jsonData)
        ));

        $result = curl_exec($ch);
        $err = curl_error($ch);
        $result = json_decode($result, true, JSON_PRETTY_PRINT);
        curl_close($ch);
        return $result;
    }

    public function zarinPallPaymentVerification($merchant_id, $authority, $amount)
    {

        $data = array("merchant_id" => $merchant_id, "authority" => $authority, "amount" => $amount);
        $jsonData = json_encode($data);
        // $ch = curl_init('https://sandbox.zarinpal.com/pg/v4/payment/verify.json');
        $ch = curl_init('https://api.zarinpal.com/pg/v4/payment/verify.json');
        curl_setopt($ch, CURLOPT_USERAGENT, 'ZarinPal Rest Api v4');
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
        curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Content-Type: application/json',
            'Content-Length: ' . strlen($jsonData)
        ));

        $result = curl_exec($ch);
        curl_close($ch);
        $result = json_decode($result, true);
        return $result;
    }


    public function protect($db, $text)
    {
        $text = $db->real_escape_string($text);
        return str_replace(['$', ';', '"', "'", '<', '>', '\n'], [null, null, null, null, null, null, PHP_EOL], $text);
    }

    function getTime($seconds)
    {
        $days = floor($seconds / 86400);
        $hours = floor(($seconds - ($days * 86400)) / 3600);
        $minutes = floor(($seconds - ($days * 86400) - ($hours * 3600)) / 60);
        $res = '2';
        if ($days != 0) {
            $hours = $hours != 0 ? 'و ' . $hours . ' ساعت' : '';
            return "$days روز $hours";
        }
        if ($hours) {
            $minutes = $minutes != 0 ? 'و ' . $minutes . ' دقیقه' : '';
            return "$hours ساعت $minutes";
        }
        return "$minutes دقیقه";
    }


    public function getUrlStatus($url)
    {
        $ch = curl_init($url);
        curl_setopt_array($ch, array(
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_TIMEOUT => 10
        ));
        curl_exec($ch);
        $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        return $status;
    }


    public function getConfigLink($link, $protocol, $url, $domain = '', $host = '', $tunnel = '0')
    {
        $newLink = '';
        $url = $domain ? $domain : $url;
        $domain = $domain ? $domain : $url;
        if ($tunnel != '0' && isset($tunnel)) {
            $url = $tunnel;
        }
        switch ($protocol) {
            case "vless":
                $newLink = str_replace("URL", $url, $link);
                $newLink = str_replace("DOMAIN", $domain, $newLink);
                $newLink = str_replace("HOST", $host, $newLink);
                break;
            case "vmess":
                $link = base64_decode(explode("//", $link)[1]);
                $newLink = str_replace("DOMAIN", $domain, $link);
                $newLink = str_replace("URL", $url, $newLink);
                $newLink = "vmess://" . base64_encode($newLink);

                break;
            case "trojan":
            case "shadowsock":
            case "shadowsocks":
                $newLink = str_replace("URL", $url, $link);
                break;
        }

        return $newLink;
    }

    public function deleteMessage(array $content)
    {
        return $this->endpoint('deleteMessage', $content);
    }

    public function deleteSendMessage(array $content, array $content1)
    {

        $this->endpoint('deleteMessage', $content);
        return $this->endpoint('sendMessage', $content1);
    }

    /// Receive incoming messages using polling

    /** Use this method to receive incoming updates using long polling.
     * \param $offset Integer Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as getUpdates is called with an offset higher than its update_id.
     * \param $limit Integer Limits the number of updates to be retrieved. Values between 1—100 are accepted. Defaults to 100
     * \param $timeout Integer Timeout in seconds for long polling. Defaults to 0, i.e. usual short polling
     * \param $update Boolean If true updates the pending message list to the last update received. Default to true.
     * \return the updates as Array.
     */
    public function getUpdates($offset = 0, $limit = 100, $timeout = 0, $update = true)
    {
        $content = ['offset' => $offset, 'limit' => $limit, 'timeout' => $timeout];
        $this->updates = $this->endpoint('getUpdates', $content);
        if ($update) {
            if (count($this->updates['result']) >= 1) { //for CLI working.
                $last_element_id = $this->updates['result'][count($this->updates['result']) - 1]['update_id'] + 1;
                $content = ['offset' => $last_element_id, 'limit' => '1', 'timeout' => $timeout];
                $this->endpoint('getUpdates', $content);
            }
        }

        return $this->updates;
    }

    /// Serve an update

    /** Use this method to use the bultin function like Text() or Username() on a specific update.
     * \param $update Integer The index of the update in the updates array.
     */
    public function serveUpdate($update)
    {
        $this->data = $this->updates['result'][$update];
    }

    /// Return current update type

    /**
     * Return current update type `False` on failure.
     *
     * @return bool|string
     */
    public function getUpdateType()
    {
        $update = $this->data;
        if (isset($update['inline_query'])) {
            return self::INLINE_QUERY;
        }
        if (isset($update['callback_query'])) {
            return self::CALLBACK_QUERY;
        }
        if (isset($update['edited_message'])) {
            return self::EDITED_MESSAGE;
        }
        if (isset($update['message']['forward_from_chat'])) {
            return self::forward_from_CHAT;
        }
        if (isset($update['message']['text'])) {
            return self::MESSAGE;
        }
        if (isset($update['message']['photo'])) {
            return self::PHOTO;
        }
        if (isset($update['message']['video'])) {
            return self::VIDEO;
        }
        if (isset($update['message']['audio'])) {
            return self::AUDIO;
        }
        if (isset($update['message']['voice'])) {
            return self::VOICE;
        }
        if (isset($update['message']['contact'])) {
            return self::CONTACT;
        }
        if (isset($update['message']['location'])) {
            return self::LOCATION;
        }
        // if (isset($update['message']['reply_to_message'])) {
        //     return self::REPLY;
        // }
        if (isset($update['message']['animation'])) {
            return self::ANIMATION;
        }
        if (isset($update['message']['document'])) {
            return self::DOCUMENT;
        }
        if (isset($update['message']['animation'])) {
            return self::ANIMATION;
        }
        if (isset($update['message']['sticker'])) {
            return self::STICKER;
        }
        if (isset($update['channel_post'])) {
            return self::CHANNEL_POST;
        }
        if (isset($update['pre_checkout_query'])) {
            return self::PRE_CHECKOUT_QUERY;
        }
        return false;
    }

    private function sendAPIRequest($url, array $content, $post = true)
    {
        if (isset($content['chat_id'])) {
            $url = $url . '?chat_id=' . $content['chat_id'];
            unset($content['chat_id']);
        }
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        if ($post) {
            $ok = 2;
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
        }
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        $result = curl_exec($ch);
        if ($result === false) {
            $result = json_encode(['ok' => false, 'curl_error_code' => curl_errno($ch), 'curl_error' => curl_error($ch)]);
        }
        curl_close($ch);
        if ($this->log_errors) {
            if (class_exists('TelegramErrorLogger')) {
                $loggerArray = ($this->getData() == null) ? [$content] : [$this->getData(), $content];
                TelegramErrorLogger::log(json_decode($result, true), $loggerArray);
            }
        }

        return $result;
    }
}

// Helper for Uploading file using CURL
if (!function_exists('curl_file_create')) {
    function curl_file_create($filename, $mimetype = '', $postname = '')
    {
        return "@$filename;filename="
            . ($postname ?: basename($filename))
            . ($mimetype ? ";type=$mimetype" : '');
    }
}
