<?php

use Mnv\Core\Utilities\Cookie\Session;

/**
 * Class ClickAPI
 */
class UzCardAPI
{
    private $_table = 'shop_orders';
    private $login = 'ocard';
    private $pass = 'VHTE+z9f%7_JyBZa';

    protected $confirmed;
    protected $rejected;
    protected $waiting;

    protected $request = null;

    /**
     * ClickAPI constructor.
     */
    public function __construct()
    {
        $this->confirmed = 'confirmed'; //подтвердил
        $this->rejected  = 'rejected';  //отвергнуто
        $this->waiting   = 'waiting';   //ожидание
    }

    // TODO: запись в базу для завершения транзакции запрос в базу

    /**
     * PaymentWithoutRegistration
     * Метод позволяет создать запрос на проведение транзакции без регистрации.
     *
     * @param $data
     * @param string $lang
     * @return mixed
     */
   public function paymentWithoutRegistration($data, $lang = 'ru')
   {
       $cardNumber = preg_replace('/[^0-9]/', '', $data['cardNumber']);
//       $cardNumber = str_replace(" ", "", $data['cardNumber']);
       $expireDate = explode(" / ", $data['expireDate']);
       $data = [
           'cardNumber' => $cardNumber,
           'expireDate' => $expireDate[1] . $expireDate[0],
           'amount'     => $data['amount'] = isset($data['amount']) ? $data['amount'] : 0,
           'extraId'    => $data['extraId'] = isset($data['extraId']) ?  $data['extraId'] : 0,
       ];

       $this->request =  $this->curlSend('https://pay.myuzcard.uz/api/Payment/paymentWithoutRegistration', $data, $lang);

       if (!is_null($this->request['result'])) {
           Session::set('transactionId', $this->request['result']['transactionId']);
           Session::set('session', $this->request['result']['session']);

           $this->update("id='$data[extraId]'", [
               'status'         => $this->waiting,
               'state'          => 1,
               'transactionId'  => $this->request['result']['transactionId'],
               'session'        => $this->request['result']['session'],
           ]);
//            Array (
//                [result] => Array (
//                    [session] => 6251735
//                    [transactionId] => 989786
//                    [otpSentPhone] => 99897*****75
//                    [cardId] => 835547
//                    [amount] => 1000
//                    [commission] => 0
//                    [totalAmount] => 1000
//                )
//                [error] =>
//            )
       }

       return $this->request;
   }

    /**
     * ConfirmPayment
     * Метод позволяет подтвердить транзакцию.
     *
     * @param $code
     * @param string $lang
     * @return mixed
     */
   public function confirmPayment($code, $lang = 'ru')
   {
       $order = $this->getOrder(Session::get('transactionId'));
       if (!is_null($order)) {
           $data = [
               'session' => $order['session'],
               'otp' => $code,
           ];

           $this->request = $this->curlSend('https://pay.myuzcard.uz/api/Payment/confirmPayment', $data, $lang);

           if (!is_null($this->request['result'])) {
               $this->update("transactionId='$order[transactionId]'", [
                   'status'         => $this->confirmed,
                   'state'          => 2
               ]);
               Session::delete('transactionId');
               Session::delete('session');
           }
       } else {
           $this->request = array(
               'result' => null,
               'error' => array(
                   'errorCode' => -1,
                   'errorMessage' => self::langMessage(
                       "Нет такого заказа",
                       "Bunday buyurtma yo'q",
                       "No such order",
                       $lang
                   )
               )
           );
       }

       return $this->request;
   }

    /**
     * PaymentReverse
     * Метод позволяет отменить платеж и вернуть средства.
     *
     * @param null $transactionId
     * @param $lang
     * @return array|mixed|null
     */
   public function paymentReverse($transactionId = null, $lang)
   {
//       $order = $this->getOrder(Session::get('transactionId'));
       $order = $this->getOrder($transactionId);
       if (!is_null($order)) {
           $data = [
               'transactionId' => $order['transactionId'],
           ];
           $this->request = $this->curlSend('https://pay.myuzcard.uz/api/Payment/paymentReverse', $data, $lang);
           if (!is_null($this->request['result'])) {
               $this->update("transactionId='$order[transactionId]'", [
                   'status' => $this->rejected,
                   'state' => 3,
               ]);
           }
       } else {
           $this->request = array(
               'result' => null,
               'error' => array(
                   'errorCode' => -1,
                   'errorMessage' => self::langMessage(
                       "Нет такого заказа",
                       "Bunday buyurtma yo'q",
                       "No such order",
                       $lang
                   )
               )
           );
       }
       return $this->request;
   }

    /**
     * PaymentCancel
     * Метод позволяет отменить платеж.
     *
     * @param $orderId
     * @return mixed
     */
    public function paymentCancel($orderId)
    {
        $this->update("id='$orderId'", [
            'status'         => $this->rejected,
            'state'          => 3,
        ]);

        return true;
    }

    /**
     * Отправка на сервер
     *
     * @param $url
     * @param $data
     * @param string $lang
     * @return mixed
     */
    private function curlSend($url, $data, $lang = 'ru')
    {
        $curl = curl_init();

        curl_setopt_array($curl, array(
            CURLOPT_USERAGENT => "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17",
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_AUTOREFERER => true,
            CURLOPT_VERBOSE => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 50,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => json_encode($data, JSON_UNESCAPED_UNICODE),
            CURLOPT_HTTPHEADER => array(
                'Accept: application/json',
                'Language: ' . $lang,
                'Authorization: Basic ' . base64_encode($this->login . ":" . $this->pass),
                'Content-Type: application/json',
                'Content-Length: ' . strlen($data)
            ),
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false
        ));

        $response = curl_exec($curl);

        curl_close($curl);

        var_dump(ini_get('disable_functions').PHP_EOL);

//        var_dump(function_exists('curl_exec').PHP_EOL);

        return json_decode($response, true);
    }

    private function fileGetContents($url, $data, $lang = 'ru')
    {
        $data     = self::my_utf8_encode($data);

//        print_r($data);

        $auth = base64_encode("$this->login:$this->pass");
        $headers = [
            'Content-Type'   => 'application/json',
            'Content-Length' => strlen($data),
            'Language' => $lang,
            'Accept' =>  'application/json',
            'Authorization' => "Basic $auth"

        ];

        $opts = [ 'http' => [
            'method' => 'POST',
            'header' => $headers,
            'protocol_version' => 1.1,
            'content' => json_encode($data)
            ],
            'ssl' => [
                'verify_peer' => false,
                'verify_peer_name' => false
            ]
        ];


//        $opts['http']['header'] .= "Content-type: application/json";
//        $opts['http']['header'] .= "Accept: application/json";
//        $opts['http']['header'] .= "Language: $lang";
//        $opts['http']['header'] .= "Content-Length: " . strlen($postdata);

//print_r($opts);

//        $response = file_get_contents($url, false, $opts);
//        var_dump($http_response_header, $response);

        if (($response = file_get_contents($url, false, $opts)) === false) {
            print_r($http_response_header);
        }
        var_dump($response);

        return json_decode($response, true);
    }

    private static function my_utf8_encode($in)
    {
        foreach ($in as $key => $record) {
            if (is_array($record)) {
                $in[$key] = self::my_utf8_encode($record);
            } else {
                $in[$key] = utf8_encode($record);
            }
        }

        return $in;
    }
    /**
     * Обновление статуса заказа
     *
     * @param $where
     * @param $data
     */
    private function update($where, $data)
    {
        $values = array();

        foreach ($data as $key => $value) {
            $values[$key] = $value;
        }

        dbQuery($this->_table, DB_UPDATE, array('where' => $where, 'values' => $values));
    }

    /**
     * Получение заказа по transactionId
     *
     * @param $transactionId
     * @return array|false|int|null
     */
    private function getOrder($transactionId)
    {
        if ($order = dbQuery($this->_table, DB_ARRAY, array('where' => "transactionId = '$transactionId'"))) {
            return $order;
        } else {
            return null;
        }
    }

    /**
     * @param string $ru
     * @param string $uz
     * @param string $en
     * @param $index
     * @return mixed
     */
    public static function langMessage($ru, $uz = '', $en = '', $index)
    {
        $array = ['ru' => $ru, 'uz' => $uz, 'en' => $en];
        return $array[$index];
    }

}
