<?php

class PIXPDV {
    private $homologacao;
    private $cnpj;
    private $token;
    private $secret;
    private $instacia;
    private $urlbase;
    private $load;
    private $log;

    public function __construct($registry, $cnpj, $token, $secret, $homologacao = true) {

        $this->homologacao = $homologacao;
        $this->urlbase = $this->homologacao === false ? "https://pixnopdv.com.br/api/v1/" : "https://pixnopdv.com.br/api-h/v1/";
        $this->cnpj = $this->homologacao === false ? $cnpj : '00641418000188';
        $this->token = $this->homologacao === false ? $token : 'tk-ezI0OTgwMzRDLUE1MzctNDM3QS1CQTk0LUZFODlFMEE0MzIyNn0';
        $this->secret = $this->homologacao === false ? $secret : 'sk-e0JBNTFGRTY0LTczMkYtNDYxNC1CQ0Q1LUI0OTVDODgxOTUwRX0';

        $this->log = $registry->get('log');

        $this->instacia = curl_init();
        if ($this->instacia === false) {
            $logData = [
                'tag'      => '[' . get_class($this) . ']',
                'event'    => __FUNCTION__,
                'message'  => 'Falha ao inicializar o cURL na library PixPDV.',
                'datetime' => date('Y-m-d H:i:s'),
            ];
             $this->logError($logData);
             return;
        }
        curl_setopt($this->instacia, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($this->instacia, CURLOPT_POST, 1);
        curl_setopt($this->instacia,CURLOPT_ENCODING, '');
        curl_setopt($this->instacia,CURLOPT_MAXREDIRS, 10);
        curl_setopt($this->instacia,CURLOPT_TIMEOUT, 0);
        curl_setopt($this->instacia,CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($this->instacia,CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
        curl_setopt($this->instacia,CURLOPT_USERAGENT, 'PHP');
    }

    public function statusToken() {
        $body = json_encode(["cnpj" => $this->cnpj]);
        $headers = [
            'Content-Type: application/json',
            'Json-Hash: ' . $this->gerarHmac($body),
            'Authorization: Basic ' . base64_encode($this->cnpj . ':' . $this->token)
        ];

        curl_setopt($this->instacia,CURLOPT_CUSTOMREQUEST, 'POST');
        curl_setopt($this->instacia, CURLOPT_URL, $this->urlbase . "statustoken");
        curl_setopt($this->instacia, CURLOPT_POSTFIELDS, $body);
        curl_setopt($this->instacia, CURLOPT_HTTPHEADER, $headers);

        $response = curl_exec($this->instacia);
        if ($response === false) {
            $logData = [
                'tag'      => '[' . get_class($this) . ']',
                'event'    => __FUNCTION__,
                'message'  => 'Erro na requisição statusToken: ' . curl_error($this->instacia),
                'datetime' => date('Y-m-d H:i:s'),
            ];
             $this->logError($logData);
             return null;
        }

        return json_decode($response, true);
    }

    public function QRDinamico($valor, $minutos, $msg, $imagem = false) {
        $body = json_encode([
            "valor" => $valor,
            "minutos" => $minutos,
            "mensagem" => $msg,
            "imagem" => $imagem
        ]);

        $headers = [
            'Content-Type: application/json',
            'Json-Hash: ' . $this->gerarHmac($body),
            'Authorization: Basic ' . base64_encode($this->cnpj . ':' . $this->token)
        ];

        curl_setopt($this->instacia,CURLOPT_CUSTOMREQUEST, 'POST');
        curl_setopt($this->instacia, CURLOPT_URL, $this->urlbase . "qrdinamico");
        curl_setopt($this->instacia, CURLOPT_POSTFIELDS, $body);
        curl_setopt($this->instacia, CURLOPT_HTTPHEADER, $headers);

        $response = curl_exec($this->instacia);
        if ($response === false) {
            $logData = [
                'tag'      => '[' . get_class($this) . ']',
                'event'    => __FUNCTION__,
                'message'  => 'Erro na requisição QRDinamico: ' . curl_error($this->instacia),
                'datetime' => date('Y-m-d H:i:s'),
            ];
            $this->logError($logData);
            return json_decode(['error' => curl_error($this->instacia)]);
        }

        return json_decode($response, true);
    }

    public function QRCobranca(string $acao, string $valor, string $vencimento, int $expira, string $msg, array $pagador, array $juros, array $multa, array $desconto, bool $img = false, string $documento = "") {
        $body = json_encode([
            "valor" => $valor,
            "vencimento" => $vencimento,
            "expira" => $expira,
            "mensagem" => $msg,
            "imagem" => $img,
            "documento" => $documento,
            "pagador" => $pagador,
            "juros" => $juros,
            "multa" => $multa,
            "desconto" => $desconto
        ]);

        $headers = [
            'Content-Type: application/json',
            'Json-Hash: ' . $this->gerarHmac($body),
            'Authorization: Basic ' . base64_encode($this->cnpj . ':' . $this->token)
        ];

        curl_setopt($this->instacia,CURLOPT_CUSTOMREQUEST, "POST");
        curl_setopt($this->instacia, CURLOPT_URL, $this->urlbase . "qrcobranca");
        curl_setopt($this->instacia, CURLOPT_POSTFIELDS, $body);
        curl_setopt($this->instacia, CURLOPT_HTTPHEADER, $headers);

        $response = curl_exec($this->instacia);
        if ($response === false) {
            $logData = [
                'tag'      => '[' . get_class($this) . ']',
                'event'    => __FUNCTION__,
                'message'  => 'Erro na requisição QRCobranca: ' . curl_error($this->instacia),
                'datetime' => date('Y-m-d H:i:s'),
            ];
            $this->logError($logData);
            return json_decode(['error' => curl_error($this->instacia)]);
        }

        return json_decode($response, true);
    }

    public function QRCobrancaRemove(string $qrcodeid) {
        $headers = [
            'Content-Type: application/json',
            'Authorization: Basic ' . base64_encode($this->cnpj . ':' . $this->token)
        ];

        curl_setopt($this->instacia,CURLOPT_CUSTOMREQUEST, 'DELETE');
        curl_setopt($this->instacia, CURLOPT_URL, $this->urlbase . "qrcobranca?qrcodeid=" . $qrcodeid);
        curl_setopt($this->instacia, CURLOPT_HTTPHEADER, $headers);

        $response = curl_exec($this->instacia);
        if ($response === false) {
            $logData = [
                'tag'      => '[' . get_class($this) . ']',
                'event'    => __FUNCTION__,
                'message'  => 'Erro na requisição QRCobrancaRemove: ' . curl_error($this->instacia),
                'datetime' => date('Y-m-d H:i:s'),
            ];
            $this->logError($logData);
            return json_decode(['error' => curl_error($this->instacia)]);
        }

        return json_decode($response, true);
    }

    public function QRDinamicoRemove(string $qrcodeid) {
        $headers = [
            'Content-Type: application/json',
            'Authorization: Basic ' . base64_encode($this->cnpj . ':' . $this->token)
        ];

        curl_setopt($this->instacia,CURLOPT_CUSTOMREQUEST, 'DELETE');
        curl_setopt($this->instacia, CURLOPT_URL, $this->urlbase . "qrdinamico?qrcodeid=" . $qrcodeid);
        curl_setopt($this->instacia, CURLOPT_HTTPHEADER, $headers);

        $response = curl_exec($this->instacia);
        if ($response === false) {
            $logData = [
                'tag'      => '[' . get_class($this) . ']',
                'event'    => __FUNCTION__,
                'message'  => 'Erro na requisição QRDinamicoRemove: ' . curl_error($this->instacia),
                'datetime' => date('Y-m-d H:i:s'),
            ];
            $this->logError($logData);
            return json_decode(['error' => curl_error($this->instacia)]);
        }

        return json_decode($response, true);
    }

    public function QRStatus(string $qrcodeid) {
        $headers = [
            'Content-Type: application/json',
            'Authorization: Basic ' . base64_encode($this->cnpj . ':' . $this->token)
        ];

        curl_setopt($this->instacia,CURLOPT_CUSTOMREQUEST, 'GET');
        curl_setopt($this->instacia, CURLOPT_URL, $this->urlbase . "qrstatus?qrcodeid=" . $qrcodeid);
        curl_setopt($this->instacia, CURLOPT_HTTPHEADER, $headers);

        $response = curl_exec($this->instacia);
        if ($response === false) {
            $logData = [
                'tag'      => '[' . get_class($this) . ']',
                'event'    => __FUNCTION__,
                'message'  => 'Erro na requisição QRStatus: ' . curl_error($this->instacia),
                'datetime' => date('Y-m-d H:i:s'),
            ];
            $this->logError($logData);
            return json_decode(['error' => curl_error($this->instacia)]);
        }

        return json_decode($response, true);
    }

    public function QRRefund(string $qrcodeid) {
        $body = json_encode(["qrcodeid" => $qrcodeid]);

        $headers = [
            'Content-Type: application/json',
            'Json-Hash: ' . $this->gerarHmac($body),
            'Authorization: Basic ' . base64_encode($this->cnpj . ':' . $this->token)
        ];

        curl_setopt($this->instacia,CURLOPT_CUSTOMREQUEST, 'POST');
        curl_setopt($this->instacia, CURLOPT_URL, $this->urlbase . "qrrefund");
        curl_setopt($this->instacia, CURLOPT_POSTFIELDS, $body);
        curl_setopt($this->instacia, CURLOPT_HTTPHEADER, $headers);

        $response = curl_exec($this->instacia);
        if ($response === false) {
            $logData = [
                'tag'      => '[' . get_class($this) . ']',
                'event'    => __FUNCTION__,
                'message'  => 'Erro na requisição QRRefund: ' . curl_error($this->instacia),
                'datetime' => date('Y-m-d H:i:s'),
            ];
            $this->logError($logData);
            return json_decode(['error' => curl_error($this->instacia)]);
        }

        return json_decode($response, true);
    }

    public function resumo(string $inicio, string $fim, string $tipo) {
        $headers = [
            'Authorization: Basic ' . base64_encode($this->cnpj . ':' . $this->token)
        ];

        curl_setopt($this->instacia,CURLOPT_CUSTOMREQUEST, 'GET');
        curl_setopt($this->instacia, CURLOPT_URL, $this->urlbase . "qrresumo?inicio=$inicio&fim=$fim&tipo=$tipo");
        curl_setopt($this->instacia, CURLOPT_HTTPHEADER, $headers);

        $response = curl_exec($this->instacia);
        if ($response === false) {
            $logData = [
                'tag'      => '[' . get_class($this) . ']',
                'event'    => __FUNCTION__,
                'message'  => 'Erro na requisição resumo: ' . curl_error($this->instacia),
                'datetime' => date('Y-m-d H:i:s'),
            ];
            $this->logError($logData);
            return json_decode(['error' => curl_error($this->instacia)]);
        }

        return json_decode($response, true);
    }

    public function saldo() {
        $headers = [
            'Authorization: Basic ' . base64_encode($this->cnpj . ':' . $this->token)
        ];

        curl_setopt($this->instacia,CURLOPT_CUSTOMREQUEST, 'GET');
        curl_setopt($this->instacia, CURLOPT_URL, $this->urlbase . "saldo");
        curl_setopt($this->instacia, CURLOPT_HTTPHEADER, $headers);

        $response = curl_exec($this->instacia);
        if ($response === false) {
            $logData = [
                'tag'      => '[' . get_class($this) . ']',
                'event'    => __FUNCTION__,
                'message'  => 'Erro na requisição saldo: ' . curl_error($this->instacia),
                'datetime' => date('Y-m-d H:i:s'),
            ];
            $this->logError($logData);
            return json_decode(['error' => curl_error($this->instacia)]);
        }

        return json_decode($response, true);
    }

    public function Retirada(float $valor) {
        $body = json_encode(["valor" => $valor]);

        $headers = [
            'Content-Type: application/json',
            'Json-Hash: ' . $this->gerarHmac($body),
            'Authorization: Basic ' . base64_encode($this->cnpj . ':' . $this->token)
        ];

        curl_setopt($this->instacia,CURLOPT_CUSTOMREQUEST, 'POST');
        curl_setopt($this->instacia, CURLOPT_URL, $this->urlbase . "retirada");
        curl_setopt($this->instacia, CURLOPT_POSTFIELDS, $body);
        curl_setopt($this->instacia, CURLOPT_HTTPHEADER, $headers);

        $response = curl_exec($this->instacia);
        if ($response === false) {
            $logData = [
                'tag'      => '[' . get_class($this) . ']',
                'event'    => __FUNCTION__,
                'message'  => 'Erro na requisição Retirada: ' . curl_error($this->instacia),
                'datetime' => date('Y-m-d H:i:s'),
            ];
            $this->logError($logData);
            return json_decode(['error' => curl_error($this->instacia)]);
        }

        return json_decode($response, true);
    }

    public function extrato(string $inicio, string $fim) {
        $headers = [
            'Authorization: Basic ' . base64_encode($this->cnpj . ':' . $this->token)
        ];

        curl_setopt($this->instacia,CURLOPT_CUSTOMREQUEST, 'GET');
        curl_setopt($this->instacia, CURLOPT_URL, $this->urlbase . "extrato?inicio=$inicio&fim=$fim");
        curl_setopt($this->instacia, CURLOPT_HTTPHEADER, $headers);

        $response = curl_exec($this->instacia);
        if ($response === false) {
            $logData = [
                'tag'      => '[' . get_class($this) . ']',
                'event'    => __FUNCTION__,
                'message'  => 'Erro na requisição extrato: ' . curl_error($this->instacia),
                'datetime' => date('Y-m-d H:i:s'),
            ];
            $this->logError($logData);
            return json_decode(['error' => curl_error($this->instacia)]);
        }

        return json_decode($response, true);
    }

    private function gerarHmac($body) {
        $hmac = hash_hmac('sha256', $body, $this->secret);
        return $hmac;
    }

    public function __destruct() {
        curl_close($this->instacia);
    }

    private function logError($data) 
    {
       $log = new Log('payment_error.txt');
       $logData = $data;
       $log->write(json_encode($logData, JSON_UNESCAPED_UNICODE));
    }
}

?>