<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

date_default_timezone_set('Asia/Tehran');

$sec = $_GET["secretKey"] ?? null;
if ($sec !== "WatsonPrivateApi20262027") {
     exit("Access Denied!");
}

require_once __DIR__ . "/../herbasc/config.php";

final class main {
    public $update;
    private string $token;
    public string $chartPath = "chart.png";
    public string $text = "none";
    public string $data = "none";
    public ?int $chatId = null;
    public ?int $fromId = null;
    public int $msgId;
    public ?string $usrNme = null;
    public ?string $grNme = null;
    
    public function __construct(string $token){
        $this->token = $token;
        $this->update = json_decode(file_get_contents("php://input"));
        if(isset($this->update->message)){
            $this->text = $this->update->message->text ?? "none";
            $this->chatId = $this->update->message->chat->id ?? 0;
            $this->fromId = $this->update->message->from->id ?? 0;
            $this->msgId = $this->update->message->message_id ?? 0;
            $this->usrNme = $this->update->message->from->username ?? "none";
            $this->grNme = $this->update->message->chat->username ?? "none";
        }elseif(isset($this->update->callback_query)){
            $this->chatId = $this->update->callback_query->message->chat->id ?? 0;
            $this->data = $this->update->callback_query->data ?? "none";
            $this->text = $this->update->callback_query->message->text ?? "none";
            $this->msgId = $this->update->callback_query->message->message_id ?? 0;
            $this->usrNme = $this->update->callback_query->from->username ?? "none";
            $this->grNme = $this->update->callback_query->message->chat->username ?? "none";
            $this->fromId = $this->update->callback_query->from->id ?? 0;
        }
    }
    
    public function api(string $method, array $data=[]) {
        $ch = curl_init();
        
        curl_setopt($ch, CURLOPT_URL, "https://api.telegram.org/bot".$this->token."/".$method);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
        curl_setopt($ch, CURLOPT_TIMEOUT, 20);
        
        $res = curl_exec($ch);

        file_put_contents(__DIR__ . "/tg_errors.txt", date("[Y-m-d H:i:s] ") . $method . " Response: " . $res . "\n", FILE_APPEND);

        if(curl_error($ch)){
            $result = false;
        }else{
            $result = json_decode($res);
        }
        
        curl_close($ch);
        return $result;
    }
    
    public function call(int $id, string $method, string $text, array $keyboard = [], string $url = null): void {
        $replyMarkup = !empty($keyboard) ? json_encode($keyboard) : null;

        switch(strtolower($method)){
            case "sendmessage":
                $params = ["chat_id" => $id, "text" => $text, "parse_mode" => "HTML"];
                if ($this->msgId > 0) $params["reply_to_message_id"] = $this->msgId;
                if ($replyMarkup) $params["reply_markup"] = $replyMarkup;
                
                $this->api("sendMessage", $params);
                break;
                
            case "sendphoto":
                $params = ["chat_id" => $id, "photo" => new CURLFile($this->chartPath), "caption" => $text, "parse_mode" => "HTML"];
                if ($this->msgId > 0) $params["reply_to_message_id"] = $this->msgId;
                if ($replyMarkup) $params["reply_markup"] = $replyMarkup;
                
                $this->api("sendPhoto", $params);
                if(file_exists($this->chartPath)) @unlink($this->chartPath);
                break;
                
            case "greed":
                $params = ["chat_id" => $id, "photo" => "https://alternative.me/crypto/fear-and-greed-index.png?t=" . time(), "caption" => $text, "parse_mode" => "HTML"];
                if ($this->msgId > 0) $params["reply_to_message_id"] = $this->msgId;
                if ($replyMarkup) $params["reply_markup"] = $replyMarkup;
                
                $this->api("sendPhoto", $params);
                break;
                
            case "editmessagemedia":
                $params = ["chat_id" => $id, "message_id" => $this->msgId, "media" => json_encode(["type" => "photo", "media" => $url, "caption" => $text, "parse_mode" => "HTML"])];
                if ($replyMarkup) $params["reply_markup"] = $replyMarkup;
                
                $this->api("editMessageMedia", $params);
                
                $domain = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://" . $_SERVER['HTTP_HOST'];
                $baseUri = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
                
                $ch = curl_init();
                curl_setopt($ch, CURLOPT_URL, $domain . $baseUri . "/cleanup.php?secret=" . SECRET_KEY);
                curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200);
                curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                curl_exec($ch);
                curl_close($ch);
                break;
                
            case "editmessagetext":
                $params = ["chat_id" => $id, "text" => $text, "parse_mode" => "HTML", "message_id" => $this->msgId];
                if ($replyMarkup) $params["reply_markup"] = $replyMarkup;
                
                $this->api("editMessageText", $params);
                break;
        }
    }
    
    private function formater(float $price): mixed {
        if (!is_numeric($price) || $price == 0) return "0";
        $abs = abs($price);
        if ($abs >= 50000) {
            return number_format(floor($price / 100) * 100);
        }
        elseif ($abs >= 100) {
            return number_format(floor($price / 1) * 1);
        }
        elseif ($abs >= 1000) {
            return number_format(round($price, 0));
        }
        elseif ($abs >= 1) {
            return number_format(round($price, 3), 3, '.', '');
        }
        elseif ($abs >= 0.01) {
            return number_format(round($price, 4), 4, '.', '');
        }
        elseif ($abs >= 0.001) {
            return number_format(round($price, 5), 5, '.', '');
        }
        elseif ($abs >= 0.0001) {
            return number_format(round($price, 6), 6, '.', '');
        }
        else {
            return sprintf("%.2E", round($price, 8));
        }
    }
    
    public function coinDetails(string $coin = "BTCUSDT") {
        global $cryptoMap;
        $coin = strtoupper( $cryptoMap[$coin] ?? $coin ) . "USDT";
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, "https://api.mexc.com/api/v3/ticker/24hr?symbol={$coin}");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 20);
        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");

        $response = curl_exec($ch);
        
        if (curl_errno($ch)) {
            return false;
        }else{
            $data = json_decode($response);
            if ($data === null || (isset($data->code) && $data->code != 0)) {
                return false;
            }else{
                return ["price" => $data->lastPrice, "change" => $data->priceChangePercent * 100, "high" => $data->highPrice, "low" => $data->lowPrice, "volume" => $data->quoteVolume];
            }
        }
        curl_close($ch);
    }
    
    private function find(array $price = []): array {
        $max = (float)$price[0][1];
        $min = (float)$price[0][1];
        $indexs = [1, 2, 3, 4];

        foreach ($price as $k){
            foreach ($indexs as $index){
                $c = (float) $k[$index];
                if($c > $max) $max = $c;
                if($c < $min) $min = $c;
            }
        }

        $range = $max - $min;
        $max += $range * 0.14;
        $min -= $range * 0.07;
        return [$max, $min];
    }

    private function y(float $price, float $min, float $max, float $height): int {
        return (int) floor($height - (($price - $min) / ($max - $min) * $height));
    }

    public function getData(string $coin, string $interval, int $limit) {
        global $cryptoMap;
        $coin = strtoupper( $cryptoMap[$coin] ?? $coin ) . "USDT";
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, "https://api.mexc.com/api/v3/klines?symbol={$coin}&interval={$interval}&limit={$limit}");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 20);
        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");

        $response = curl_exec($ch);

        if (curl_errno($ch)) {
            return false;
        }else{
            if($response){
                $data = json_decode($response);
                if(isset($data->code) && $data->code != 0){
                    return false;
                }else{
                    return $data;
                }
            }else{
                return false;
            }
        }
        curl_close($ch);
    }
    
    public function getTetherData(int $interval = 15, int $limit = 123) {
        $to = time();
        $from = $to - ($interval * 60 * $limit);
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, "https://apiv2.nobitex.ir/market/udf/history?symbol=USDTIRT&resolution={$interval}&from={$from}&to={$to}");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 20);
        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");

        $response = curl_exec($ch);
        
        if (curl_errno($ch)) {
            return false;
        }else{
            if($response){
                $data = json_decode($response, true);
                if(isset($data["s"]) && $data["s"] == "ok"){
                    $klines = [];
                    for ($i = 0; $i < count($data['t']); $i++) {
                        $klines[] = [
                        $data['t'][$i] * 1000,
                        (float)$data['o'][$i],
                        (float)$data['h'][$i],
                        (float)$data['l'][$i],
                        (float)$data['c'][$i],
                        (float)$data['v'][$i]
                        ];
                    }
                    return $klines;
                }else{
                    return false;
                }
            }else{
                return false;
            }
        }
        curl_close($ch);
    }
    
    public function tetherPrice() {
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, "https://apiv2.nobitex.ir/market/stats?srcCurrency=usdt");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 20);
        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");

        $response = curl_exec($ch);
        
        if(curl_errno($ch)){
            return false;
        }else{
            if($response){
                $data = json_decode($response, true);
                if(!isset($data["stats"]["usdt-rls"])){
                    return false;
                }else{
                    return ["price" => $data["stats"]["usdt-rls"]["latest"] / 10, "change" => $data["stats"]["usdt-rls"]["dayChange"], "high" => $data["stats"]["usdt-rls"]["dayHigh"] / 10, "low" => $data["stats"]["usdt-rls"]["dayLow"] / 10, "volume" => $data["stats"]["usdt-rls"]["volumeSrc"]];
                }
            }else{
                return false;
            }
        }
        curl_close($ch);
    }
    
    public function goldPrice() {
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, "https://call3.tgju.org/ajax.json?rev=" . time());
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 20);
        // اضافه شدن User-Agent برای جلوگیری از مسدود شدن
        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36");

        $response = curl_exec($ch);
        
        if(curl_errno($ch)){
            return false;
        }else{
            if($response){
                $data = json_decode($response);
                if(!isset($data->current->geram18->p)){
                    return false;
                }else{
                    return ["price" => str_replace(",", "", $data->current->geram18->p) / 10, "high" => str_replace(",", "", $data->current->geram18->h) / 10, "low" => str_replace(",", "", $data->current->geram18->l) / 10, "priceChange" => str_replace(",", "", $data->current->geram18->d) / 10, "perChange" => str_replace(",", "", $data->current->geram18->dp) / 10, "change" => $data->current->geram18->dt, "update" => $data->current->geram18->ts];
                }
            }else{
                return false;
            }
        }
        curl_close($ch);
    }



    public function gold24Price() {
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, "https://call3.tgju.org/ajax.json?rev=" . time());
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 20);
        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36");

        $response = curl_exec($ch);
        
        if(curl_errno($ch)){
            return false;
        }else{
            if($response){
                $data = json_decode($response);
                if(!isset($data->current->geram24->p)){
                    return false;
                }else{
                    return [
                        "price" => str_replace(",", "", $data->current->geram24->p) / 10, 
                        "high" => str_replace(",", "", $data->current->geram24->h) / 10, 
                        "low" => str_replace(",", "", $data->current->geram24->l) / 10, 
                        "priceChange" => str_replace(",", "", $data->current->geram24->d) / 10, 
                        "perChange" => str_replace(",", "", $data->current->geram24->dp) / 10, 
                        "change" => $data->current->geram24->dt, 
                        "update" => $data->current->geram24->ts
                    ];
                }
            }else{
                return false;
            }
        }
        curl_close($ch);
    }
    
    public function tgju() {
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, "https://call3.tgju.org/ajax.json?rev=" . time());
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 20);
        // اضافه شدن User-Agent برای جلوگیری از مسدود شدن
        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36");

        $response = curl_exec($ch);
        $error = curl_errno($ch);
        curl_close($ch); 
        
        if($error){
            return false;
        }else{
            if($response){
                $data = json_decode($response);
                if(isset($data->current)){
                    $usd = isset($data->current->price_dollar_rl->p) ? (float)str_replace(",", "", $data->current->price_dollar_rl->p) / 10 : 0;
                    $silver = isset($data->current->silver_999->p) ? (float)str_replace(",", "", $data->current->silver_999->p) / 10 : 0;
                    $emami = isset($data->current->sekee->p) ? (float)str_replace(",", "", $data->current->sekee->p) / 10 : 0;
                    
                    if($usd == 0 && $silver == 0 && $emami == 0) return false;
                    
                    return ["usd" => $usd, "silver" => $silver, "emami" => $emami];
                }
                return false;
            }else{
                return false;
            }
        }
    }



    public function goldRates() {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, "https://call3.tgju.org/ajax.json?rev=" . time());
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 20);
        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36");

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

        if ($response) {
            $data = json_decode($response);
            if (isset($data->current)) {
                $c = $data->current;
                return [
                    'gold18' => isset($c->geram18->p) ? (float)str_replace(",", "", $c->geram18->p) / 10 : 0,
                    'gold24' => isset($c->geram24->p) ? (float)str_replace(",", "", $c->geram24->p) / 10 : 0,
                    'emami'  => isset($c->sekee->p) ? (float)str_replace(",", "", $c->sekee->p) / 10 : 0,
                    'bahar'  => isset($c->sekeb->p) ? (float)str_replace(",", "", $c->sekeb->p) / 10 : 0,
                    'nim'    => isset($c->nim->p) ? (float)str_replace(",", "", $c->nim->p) / 10 : 0,
                    'rob'    => isset($c->rob->p) ? (float)str_replace(",", "", $c->rob->p) / 10 : 0,
                    'gerami' => isset($c->gerami->p) ? (float)str_replace(",", "", $c->gerami->p) / 10 : 0,
                ];
            }
        }
        return false;
    }



    public function getTgjuDetail(string $key) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, "https://call3.tgju.org/ajax.json?rev=" . time());
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 20);
        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36");

        $response = curl_exec($ch);
        curl_close($ch);
        
        if($response){
            $data = json_decode($response);
            if(isset($data->current->$key)){
                $item = $data->current->$key;
                return [
                    "price" => str_replace(",", "", $item->p) / 10,
                    "high" => str_replace(",", "", $item->h) / 10,
                    "low" => str_replace(",", "", $item->l) / 10,
                    "priceChange" => str_replace(",", "", $item->d) / 10,
                    "perChange" => str_replace(",", "", $item->dp) / 10,
                    "change" => $item->dt,
                    "update" => $item->ts
                ];
            }
        }
        return false;
    }
    



    public function fiat() {
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, "https://call3.tgju.org/ajax.json?rev=" . time());
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 20);
        // اضافه شدن User-Agent برای جلوگیری از مسدود شدن
        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36");

        $response = curl_exec($ch);
        $error = curl_errno($ch);
        curl_close($ch); 
        
        if($error){
            return false;
        }else{
            if($response){
                $data = json_decode($response);
                if(isset($data->current)){
                    $getVal = function($key) use ($data) {
                        return isset($data->current->$key->p) ? (float)str_replace(",", "", $data->current->$key->p) / 10 : 0;
                    };
                    
                    return [
                        "usd" => $getVal('price_dollar_rl'),
                        "eur" => $getVal('price_eur'),
                        "aed" => $getVal('price_aed'),
                        "gbp" => $getVal('price_gbp'),
                        "try" => $getVal('price_try'),
                        "chf" => $getVal('price_chf'),
                        "cny" => $getVal('price_cny'),
                        "jpy" => $getVal('price_jpy'),
                        "krw" => $getVal('price_krw'),
                        "cad" => $getVal('price_cad'),
                        "aud" => $getVal('price_aud'),
                        "rub" => $getVal('price_rub'),
                        "inr" => $getVal('price_inr'),
                        "kwd" => $getVal('price_kwd'),
                        "sar" => $getVal('price_sar'),
                        "qar" => $getVal('price_qar'), 
                        "sek" => $getVal('price_sek'),
                        "nok" => $getVal('price_nok')
                    ];
                }
                return false;
            }else{
                return false;
            }
        }
    }
    
    public function starsPrice(){
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, "https://bes-dev.github.io/telegram_stars_rates/api.json");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 20);
        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");

        $response = curl_exec($ch);
        
        if(curl_errno($ch)){
            return false;
        }else{
            if($response){
                $data = json_decode($response);
                if(!isset($data->usdt_per_star)){
                    return false;
                }else{
                    return ["price" => $data->usdt_per_star];
                }
            }else{
                return false;
            }
        }
        curl_close($ch);
    }
    
    public function faToEnNumbers(string $text): string {
        // کاما و علامت‌های مشابه اضافه شد تا اعداد مثل 1,000 به درستی پردازش شوند
        $fa = ['۰','۱','۲','۳','۴','۵','۶','۷','۸','۹','٫', ','];
        $ar = ['٠','١','٢','٣','٤','٥','٦','٧','٨','٩', '٬'];
        $en = ['0','1','2','3','4','5','6','7','8','9','.', ''];

        return str_replace(array_merge($fa, $ar), array_merge($en, $en), $text);
    }
    
    public function normalizeCoin(string $coin): string {
        global $cryptoMap;
        
        $text = mb_strtolower(trim($coin), 'UTF-8');
        $text = str_replace(' ', '', $text);
        
        return $cryptoMap[$text] ?? $coin;
    }
    
    public function create(int $width = 1280, int $height = 720, array $price = [], float $current = 1, string $mark = "none", string $coin = "BTC", string $interval = "15m"): void {
        $image = imagecreatetruecolor($width, $height);

        $black = imagecolorallocate($image, 0, 0, 0);
        $white = imagecolorallocate($image, 255, 255, 255);
        $gray = imagecolorallocate($image, 80, 80, 80);
        $green = imagecolorallocate($image, 0, 255, 0);
        $red = imagecolorallocate($image, 255, 0, 0);

        $find = $this->find($price);

        for ($i = 100; $i < 1260; $i += 80){
            imagedashedline($image, $i, 40, $i, 660, $gray);
            if($i < 1100) imageline($image, $i, 660, $i, 665, $white);

            $index = round(($i - 100) / 8);

            if(isset($price[$index])){
                $label = date("H:i", (int)($price[$index][0] / 1000));
                imagettftext($image, 14, 0, $i - 20, 690, $white, __DIR__ . '/fonts/font.ttf', $label);
            }
        }

        for ($i = 50; $i < 660; $i += 80){
            imagedashedline($image, 90, $i, 1260, $i, $gray);
            imageline($image, 85, $i, 90, $i, $white);

            $yPrice = $find[1] + (($height - $i) / $height) * ($find[0] - $find[1]);
            $yPrice = $this->formater($yPrice);

            $bbox = imagettfbbox(14, 0, __DIR__ . '/fonts/font.ttf', $yPrice);
            $tw = $bbox[2] - $bbox[0];
            
            imagettftext($image, 14, 0, 90 - $tw - 12, $i + 7, $white, __DIR__ . '/fonts/font.ttf', $yPrice);
        }

        $x = 120;

        foreach ($price as $c) {
            $open = (float)$c[1];
            $high = (float)$c[2];
            $low = (float)$c[3];
            $close = (float)$c[4];

            $color = ($close > $open) ? $green : $red;

            imageline($image, $x + 3, $this->y($high, $find[1], $find[0], 660), $x + 3, $this->y($low, $find[1], $find[0], 660), $color);

            $top    = max($open, $close);
            $bottom = min($open, $close);

            imagefilledrectangle($image, $x, $this->y($top, $find[1], $find[0], 660), $x + 6, $this->y($bottom, $find[1], $find[0], 660), $color);
            
            $x += 8;
        }

        $yClose = $this->y((float)end($price)[4], $find[1], $find[0], 660);

        $bbox = imagettfbbox(15, 0, __DIR__ . '/fonts/font.ttf', $this->formater($current));
        $tw = $bbox[2] - $bbox[0];
        $th = $bbox[1] - $bbox[7];

        $boxX1 = (int)($x + 45);
        $boxY1 = (int)($yClose - ($th / 2) - 6);
        $boxX2 = (int)($boxX1 + $tw + 20);
        $boxY2 = (int)($boxY1 + $th + 12);

        imagedashedline($image, $x, $yClose, $boxX1, $yClose, $white);

        imagefilledrectangle($image, $boxX1, $boxY1, $boxX2, $boxY2, $black);
        imagerectangle($image, $boxX1, $boxY1, $boxX2, $boxY2, $white);

        imagettftext($image, 15, 0, $boxX1 + 10, $boxY1 + 6 + $th, $white, __DIR__ . '/fonts/font.ttf', $this->formater($current));

        imagettftext($image, 13, 0, 1100,  688, $white, __DIR__ . '/fonts/font.ttf', $mark);
        
        imagettftext($image, 14, 0, 479,  25, $white, __DIR__ . '/fonts/font.ttf', "$coin | $interval | " . date("Y-m-d H:i:s"));

        imagerectangle($image, 90, 40, 1260, 660, $white);

        $this->chartPath = "chart_" . uniqid() . rand(1000, 9999) . ".png";
        
        imagepng($image, $this->chartPath);
        imagedestroy($image);
    }
    
    public function forward(int $txtId, int $chId, string $cht, string $sendMethod = 'copy'): void {
        $ch = curl_init();
        $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http");
        $domain = $protocol . "://" . $_SERVER['HTTP_HOST'];
        $baseUri = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
                 
        curl_setopt($ch, CURLOPT_URL, $domain . $baseUri . "/forward/batch.php");
        curl_setopt($ch, CURLOPT_POSTFIELDS, [
            "text" => $txtId, 
            "where" => $chId, 
            "secret" => SECRET_KEY, 
            "chat" => $cht, 
            "method" => $sendMethod
        ]);
                 
        curl_setopt($ch, CURLOPT_TIMEOUT_MS, 1500); 
        curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        
        curl_exec($ch);
        curl_close($ch);
    }
}

$class = new main(TOKEN);

?>