<?php
/* Biblioteca de integração com a API da Rede*/

use Rede\Environment;
use Rede\Store;
use Rede\Transaction;
use Rede\eRede;
use Rede\ThreeDSecure;
use Rede\Exception\RedeException;



use Rede\Consumer;
use Rede\Phone;
use Rede\Address;
use Rede\Item;


class Rede{

	private $pv;
  private $token;
  private $environment;

  public function __construct($registry) {
    $this->registry = $registry;
    $this->load     = $registry->get('load');
	$this->config   = $registry->get('config');
	$this->session  = $registry->get('session');
    $this->db       = $registry->get('db');
    $this->log      = $registry->get('log');
    $this->url      = $registry->get('url');
    $this->log      = new BaseLog($registry);

    if($this->config->get('rede_ambiente_teste')){
      $this->environment = Environment::sandbox();
    }else{
      $this->environment = Environment::production();
    }

    $crypto = new Crypto();
    if($this->config->get('rede_pv')){
        $this->pv    = $crypto->descriptografarAES256($this->config->get('rede_pv')   ,$crypto::CAES256 );
    }
    if($this->config->get('rede_token')){
      $this->token = $crypto->descriptografarAES256($this->config->get('rede_token'), $crypto::CAES256);
    }

	}

  public function redePagamentoCartaoCredito($dadosTransacao){
    $captura_automatica = ($this->config->get('rede_anti_fraude') == Type_AntiFraudeCheckout::Tp_SemVerificacao) ? true : false;

    try{
      $store = new Store($this->pv, $this->token, $this->environment);

      $this->load->type('tiporede');
      $this->load->type('tipocomum');

      // Transação que será autorizada
      $transaction = (new Transaction($dadosTransacao['total_pedido'], 'pedido' . time()))->creditCard(
        $dadosTransacao['cartao_numero'],
        $dadosTransacao['cartao_cod'],
        $dadosTransacao['cartao_mes'],
        $dadosTransacao['cartao_ano'],
        $dadosTransacao['cartao_nome']
      )->capture(false);//A captura sera tratada após a autorização

      if ($dadosTransacao['cartao_parcelas'] > 1){
        $transaction->setInstallments($dadosTransacao['cartao_parcelas']);
      }

      $this->environment->setIp($dadosTransacao['cliente_ip']);
      $this->environment->setSessionId($this->config->get('rede_pv').$dadosTransacao['order_id'].date("dmY"));

      $transaction = (new eRede($store))->create($transaction);

      $retorno = array(
        'nsu'             => $transaction->getNsu(),
        'tid'             => $transaction->getTid(),
        'codAutorizacao'  => $transaction->getAuthorizationCode(),
        'inicioNumCartao' => $transaction->getCardBin(),
        'ultimosNumCartao'=> $transaction->getLast4(),
        'codRetorno'      => $transaction->getReturnCode(),
        'msgRetorno'      => $transaction->getReturnMessage(),
        'referencia'      => $transaction->getReference(),
        'dataTransacao'   => $transaction->getDateTime(),
        'status_captura'  => Type_PagamentoStatusCaptura::Tp_Aguardando
      );

      if ($transaction->getReturnCode() == '00'  && $captura_automatica){
        $retornocaptura = $this->capturaPagamento($dadosTransacao['total_pedido'], $transaction->getTid());
        //Atualiza o retorno
        if (!isset($retornocaptura['error']) && $retornocaptura['codRetorno'] == '00'){
          $retorno['codRetorno'] = $retornocaptura['codRetorno'];
          $retorno['msgRetorno'] = $retornocaptura['msgRetorno'];
          $retorno['status_captura'] = Type_PagamentoStatusCaptura::Tp_Capturado;
        }else{
          $retorno['status_captura'] = Type_PagamentoStatusCaptura::Tp_Erro;
        }
      }
    } catch (RedeException $e) {
      $log = new Log('error_eRede.txt');
      $log->write(print_r($e->getMessage(), true));
      $retorno['error'] = array(
        'code' => $e->getCode(),
        'message' => $e->getMessage()
      );

        if (isset($transaction)) {
            $this->log->baseLog->setTipoEnviado(Type_LogEnviado::Tp_LogEnviado);
            $this->log->baseLog->setOrigem(__METHOD__);
            $this->log->baseLog->setTipoLog(Type_Log::Tp_LogPedido);
            $this->log->baseLog->setTipoId(Type_LogId::Tp_LogIdPedido);
            $this->log->baseLog->setEntidadeId($dadosTransacao['order_id']);
            $this->log->baseLog->setMetodo('POST');
            $this->log->baseLog->setRetorno($transaction);
            $this->log->baseLog->setDataHora($this->db->dataAtual());
            $this->log->saveBaseLog();
        }

    }
    return $retorno;
  }

  public function redeCancelamentoPagamento($valorpedido,$tid){
    try{
      $this->load->type('tiporede');
      $store = new Store($this->pv, $this->token, $this->environment);
      // Transação que será cancelada
      $transaction = (new eRede($store))->cancel((new Transaction($valorpedido))->setTid($tid));

      $retorno = array(
        'nsu'             => $transaction->getNsu(),
        'tid'             => $transaction->getTid(),
        'codRetorno'      => $transaction->getReturnCode(),
        'msgRetorno'      => $transaction->getReturnMessage(),
        'dataCancelamento'=> $transaction->getRefundDateTime(),
        'refundId'        => $transaction->getRefundId(),
        'cancelId'        => $transaction->getCancelId()
      );

      if(in_array($transaction->getReturnCode(),[Type_RedeCancel::Tp_Refund_successful,Type_RedeCancel::Tp_Refund_request_successful]) ){
        $retorno['status_captura'] = Type_PagamentoStatusCaptura::Tp_Cancelado;
      }else{
        $retorno['status_captura'] = Type_PagamentoStatusCaptura::Tp_Erro;
      }

    } catch (RedeException $e) {
      $log = new Log('error_eRede.txt');
      $log->write(print_r($e->getMessage(), true));
      $retorno['error'] = array(
        'code' => $e->getCode(),
        'message' => $e->getMessage()
      );

    }
    return $retorno;
  }

  public function capturaPagamento($valorpedido,$tid){
    $this->load->type('tipocomum');
    try{
      $store = new Store($this->pv, $this->token, $this->environment);


      $transaction =  (new \Rede\eRede($store))->capture((new \Rede\Transaction($valorpedido))->setTid($tid));


      $retorno = array(
        'nsu'             => $transaction->getNsu(),
        'tid'             => $transaction->getTid(),
        'codAutorizacao'  => $transaction->getAuthorizationCode(),
        'codRetorno'      => $transaction->getReturnCode(),
        'msgRetorno'      => $transaction->getReturnMessage(),
        'dataCaptura'     => $transaction->getDateTime(),
        'referencia'      => $transaction->getReference()
      );

      if($transaction->getReturnCode() == 00){
        $retorno['status_captura'] = Type_PagamentoStatusCaptura::Tp_Capturado;
      }else{
        $retorno['status_captura'] = Type_PagamentoStatusCaptura::Tp_Erro;
      }

    } catch (RedeException $e) {
      $log = new Log('error_eRede.txt');
      $log->write(print_r($e->getMessage(), true));
      $retorno['error'] = array(
        'code' => $e->getCode(),
        'message' => $e->getMessage()
      );
    }
    return $retorno;
  }

    public function validateCredentials($pv, $token) {
        $this->load->type('tiporede');
        $result = [];
        try {
            $store = new Store($pv, $token, $this->environment);
            $result = (new eRede($store))->get('TID123');
        } catch (RedeException $e) {
            if (in_array($e->getCode(), array_values(Type_Authentication_fails::getEnumListConst()))) {
                $result['error'] = array(
                    'code' => $e->getCode(),
                    'message' => $e->getMessage()
                );
            }
        }

        return $result;
    }

}
