<?php

namespace Mnv\Core\Bot;

use Mnv\Core\Utilities\Curl\Curl;
use Mnv\Core\Bot\Exceptions\InvalidTokenException;
use Mnv\Core\Bot\Exceptions\InvalidChatIdException;

/**
 * Class Telegram
 * @package Mnv\Core\Bot
 */
final class Telegram
{

    const URL = 'https://api.telegram.org/bot';

    protected $token;
    protected $chat_id;

    private $proxy;
    private $logtype;
    private $log;
    private $timeout;

    public function __construct($token = null, $timeout = 5)
    {
        $this->token = $token;
        $this->timeout = $timeout;
        $this->logtype = '0';
        $this->proxy = '';
    }

    public function setLog($log, $logtype = '0')
    {
        if ($logtype == '2') {
            $this->logtype = '2';
        } elseif ($logtype == '1') {
            $this->logtype = '1';
        } else {
            $this->logtype = '0';
        }

        $this->log = $log;
    }

    public function setProxy($proxy = '')
    {
        if (empty($proxy)) {
            $this->proxy = '';
            return $this;
        }

        $pos = strrpos($proxy, '@');

        if ($pos) {
            $host = substr($proxy, 0, $pos);
        } else {
            $host = $proxy;
        }

        $this->proxy = [
            CURLOPT_PROXY       => $host,
            CURLOPT_PROXYTYPE   => CURLPROXY_SOCKS5,
        ];

        if ($pos) {
            $this->proxy = $this->proxy + [CURLOPT_PROXYUSERPWD => substr($proxy, $pos + 1),];
        }

        return $this;
    }

    public function getUpdates()
    {
        return $this->call('getUpdates');
    }

    public function setWebhook($url)
    {
        $data['url'] = $url;
        return $this->call('setWebhook', $data);
    }

    public function delWebhook()
    {
        $data['url'] = '';
        return $this->call('setWebhook', $data);
    }

    public function getWebhookInfo()
    {
        return $this->call('getWebhookInfo');
    }

    public function getBotInfo()
    {
        return $this->call('getMe');
    }

    public function setTo($chat_id)
    {
        $this->chat_id = $chat_id;
    }

    public function sendMessage($message, $trim = false)
    {
        $text = $message;
        $data = array();

        if ($trim) {
            $data['chat_id'] = $this->chat_id;
            $data['text'] = mb_substr($text, 0, 4096);
            $data['parse_mode'] = 'HTML';
            $response = $this->call('sendMessage', $data);
        } else {
            do {
                $data['chat_id'] = $this->chat_id;
                $data['text'] = mb_substr($text, 0, 4096);
                $data['parse_mode'] = 'HTML';
                $response = $this->call('sendMessage', $data);

                $text = mb_substr($text, 4096);
            } while (mb_strlen($text, 'UTF-8') > 0);
        };
        return $response;
    }

    private function call($method, $data = array())
    {
        $curl = curl_init();

        $options = [
            CURLOPT_URL => self::URL . $this->token . '/' . $method,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => null,
            CURLOPT_POSTFIELDS => null,
            CURLOPT_CONNECTTIMEOUT => 5,
            CURLOPT_TIMEOUT => $this->timeout,
        ];

//        var_dump($this->proxy);
        if (!empty($this->proxy)) {
            $options = $options + $this->proxy;
//            print_r($options);
        }

        if (!empty($data)) {
            $options[CURLOPT_POST] = true;
            $options[CURLOPT_POSTFIELDS] = $data;
        }

//        print_r($options);
        curl_setopt_array($curl, $options);

        $response = curl_exec($curl);

//        print_r($response);
        if (!$response) {
            if ($this->logtype == '2') {
                $this->log->write('ERROR in ' . $method . ' (array = ' . serialize($data) . ') :: CURL failed ' . curl_error($curl) . '(' . curl_errno($curl) . ')');
            } elseif ($this->logtype == '1') {
                $this->log->write('ERROR in ' . $method . ' :: CURL failed ' . curl_error($curl) . '(' . curl_errno($curl) . ')');
            }
            return false;
        }

        $result = json_decode($response, true);
        if (isset($result['ok']) && ($result['ok'])) {
            if ($this->logtype == '2') {
                $this->log->write('SUCCESS in ' . $method . ' (result = ' . json_encode($result['result']) . ')');
            }
            return $result['result'];
        } elseif (!($result['ok'])) {
            if ($this->logtype == '2') {
                $this->log->write('ERROR in ' . $method . ' (array = ' . serialize($data) . ') :: description = ' . $result['description'] . '(error code = ' . $result['error_code'] . ')');
            } elseif ($this->logtype == '1') {
                $this->log->write('ERROR in ' . $method . ' :: description = ' . $result['description'] . '(error code = ' . $result['error_code'] . ')');
            }
            return false;
        } else {
            if ($this->logtype == '2') {
                $this->log->write('ERROR in ' . $method . ' (array = ' . serialize($data) . ') :: result = ' . serialize($result));
            } elseif ($this->logtype == '1') {
                $this->log->write('ERROR in ' . $method . ' :: result = ' . serialize($result));
            }
            return false;
        }

        curl_close($curl);

        return false;
    }
    /**
     * @throws InvalidChatIdException
     * @throws InvalidTokenException
     */
    public static function send(int $permissionSend, string $token = null, string $chatID = null, $text, $coordinates = null): void
    {
        if ($permissionSend == 1) {
            if (empty($token))
                throw new InvalidTokenException();

            if (empty($chatID))
                throw new InvalidChatIdException();

            $curl = new Curl();
            $curl->post(Telegram::URL . $token . '/sendMessage', [
                'chat_id'       => $chatID,
                'parse_mode'    => 'html',
                'text'          => $text,
            ]);

            if (!empty($coordinates)) {
                $coordinates = explode(",", $coordinates);
                $curl->post(Telegram::URL . $token . '/sendLocation', [
                    'chat_id' => $chatID,
                    'latitude' => str_replace(" ", "", $coordinates[0]),
                    'longitude' => str_replace(" ", "", $coordinates[1]),
                ]);
            }

            if ($curl->error) {
                $curl->response = 'ERROR: ' . $curl->errorCode . ': ' . $curl->errorMessage;
            }
        }
    }

//    /**
//     * @throws InvalidChatIdException
//     * @throws InvalidTokenException
//     */
//    private function sending($permissionSend = 0, string $token = null, string $chatID = null, $text, $coordinates = null): void
//    {
//        if ($permissionSend == 1) {
//            if (empty($token))
//                throw new InvalidTokenException();
//
//            if (empty($chatID))
//                throw new InvalidChatIdException();
//
//            $curl = new Curl();
//            $curl->post('https://api.telegram.org/bot' . $token . '/sendMessage', [
//                'chat_id'       => $chatID,
//                'parse_mode'    => 'html',
//                'text'          => $text,
//            ]);
//
////            if (!empty($coordinates)) {
////                $coordinates = explode(",", $coordinates);
////                $curl->post('https://api.telegram.org/bot' . $token . '/sendLocation', [
////                    'chat_id' => $chatID,
////                    'latitude' => str_replace(" ", "", $coordinates[0]),
////                    'longitude' => str_replace(" ", "", $coordinates[1]),
////                ]);
////            }
//
//            if ($curl->error) {
//                $curl->response = 'Error: ' . $curl->errorCode . ': ' . $curl->errorMessage;
//            }
//        }
//    }


}