<?php

require_once DIR_SYSTEM . 'library/clearsale/Load.php';

/* Manuais de integração

  https://api.clearsale.com.br/docs/how-to-start
  https://api.clearsale.com.br/docs/total-totalGarantido-application
  https://api.clearsale.com.br/docs/finger-print
  https://api.clearsale.com.br/docs/mapper

  Login: FuturaSistemas
  Senha 35rLZk8mMG
  Fingerprint (Seu_app):  xxrdlku210i1htfh6mr4  

*/

class Clearsale{

  private $environment;
  private $authentication;
  private $registry;
  private $load;
  private $config;
  private $session;
  private $db;
  private $log;

  public function __construct($registry) {
    $loadclass = new Load;

    $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->setEnvironment();
	}

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

  private function setAuthentication(){
    $this->authentication = new Authentication(
      $this->config->get('clearsale_login'),
      $this->config->get('clearsale_senha'),
      $this->environment
    );
  }

  public function setOrder($dataOrder){
    try{
      $this->setAuthentication();

      $order = new Order();

      if ( $this->config->get('clearsale_custom_sla') > 0 ){
        $order->setCustomSla((int)$this->config->get('clearsale_custom_sla'));
      }

      $order->setCode($dataOrder['order_id'])
            ->setProduct((int)$this->config->get('clearsale_tipo_integracao'))
            ->setSessionID($dataOrder['session_id'])
            ->setDate($dataOrder['data'])
            ->setEmail($dataOrder['email'])
            ->setItemValue($dataOrder['total_produto'])
            ->setTotalValue($dataOrder['total_pedido'])
            ->setIp($dataOrder['ip'])
            ->setStatus($dataOrder['status_pedido'])
            ->setOrigin($dataOrder['origem'])
            ->setCountry($dataOrder['pais'])
            ->setNationality($dataOrder['nacionalidade'])
            ->setObservation($dataOrder['observacao']);

      if(isset($dataOrder['tipo_ecommerce'])){
        $order->setB2bB2c($dataOrder['tipo_ecommerce']);
      }

      if(isset($dataOrder['channel_id'])){
        $order->setChannelID($dataOrder['channel_id']);
      }      
            
      if (isset($dataOrder['parcelas'])){
        $order->setNumberOfInstallments($dataOrder['parcelas']);  
      }

      if (isset($dataOrder['is_gift'])){
        $order->setIsGift($dataOrder['is_gift']);  
        $order->setGiftMessage($dataOrder['gift_message']);    
      }

      $order->PurchaseInformation()->setPurchaseLogged($dataOrder['is_logged'])
        ->setEmail($dataOrder['logged_email'])
        ->setLogin($dataOrder['logged_login']); 

      //Billing - Inicio dados de cobrança
      $billing = $order->Billing()->setClientID($dataOrder['customer']['customer_id'])
        ->setType($dataOrder['customer']['tipo_pessoa'])
        ->setPrimaryDocument($dataOrder['customer']['cpf_cnpj'])
        ->setName($dataOrder['customer']['nome'])
        ->setEmail($dataOrder['customer']['email']);
      if(isset($dataOrder['customer']['rg_ie'])){
        $billing->setSecondaryDocument($dataOrder['customer']['rg_ie']);
      }
      if(isset($dataOrder['customer_shipping']['data_nascimento']) && substr_count($dataOrder['customer_shipping']['data_nascimento'],'0')<=5){
        $billing->setBirthDate($dataOrder['customer']['data_nascimento']);
      }
      if(isset($dataOrder['customer']['sexo']) && in_array( strtoupper($dataOrder['customer']['sexo']) ,['M','F'] ) ){
        $billing->setGender($dataOrder['customer']['sexo']);
      }

      //Endereço
      $billing_address = $billing->Address()->setStreet($dataOrder['customer']['payment_address']['logradouro'])
        ->setNumber($dataOrder['customer']['payment_address']['numero'])
        ->setCounty($dataOrder['customer']['payment_address']['bairro'])
        ->setCity($dataOrder['customer']['payment_address']['cidade'])
        ->setState($dataOrder['customer']['payment_address']['estado'])
        ->setCountry($dataOrder['customer']['payment_address']['pais'])
        ->setZipcode($dataOrder['customer']['payment_address']['zipcode']);

      if (isset($dataOrder['customer']['payment_address']['complemento'])){
        $billing_address->setAdditionalInformation($dataOrder['customer']['payment_address']['complemento']);  
      }  
      if (isset($dataOrder['customer']['payment_address']['reference'])){
        $billing_address->setReference($dataOrder['customer']['payment_address']['reference']);  
      }    
      
      //Telefones
      foreach ($dataOrder['customer']['phones'] as $phone){
        $newphone = new Phone();
        $newphone->setType($phone['type'])
          ->setDdi($phone['ddi'])
          ->setDdd($phone['ddd'])
          ->setNumber($phone['number']);  
        $billing->addPhone($newphone);  
      }
      //Fim dados de cobrança
      
      //Inicio dados de envio
      $shipping = $order->Shipping()->setClientID($dataOrder['customer_shipping']['customer_id'])
        ->setType($dataOrder['customer_shipping']['tipo_pessoa'])
        ->setPrimaryDocument($dataOrder['customer_shipping']['cpf_cnpj'])
        ->setName($dataOrder['customer_shipping']['nome'])
        ->setEmail($dataOrder['customer_shipping']['email']);
      if(isset($dataOrder['customer_shipping']['rg_ie'])){
        $shipping->setSecondaryDocument($dataOrder['customer_shipping']['rg_ie']);
      }
      
      if(isset($dataOrder['customer_shipping']['data_nascimento']) && substr_count($dataOrder['customer_shipping']['data_nascimento'],'0')<=5){
        $shipping->setBirthDate($dataOrder['customer_shipping']['data_nascimento']);
      }
      if(isset($dataOrder['customer_shipping']['sexo'])){
        $shipping->setGender($dataOrder['customer_shipping']['sexo']);
      }

      //Endereço
      //NEW Caso seja pickpup, clearsale pediu para enviar o endereço do pickup no lugar do shipping address
      if(isset($dataOrder['pickup'])){
        $shipping_address = $shipping->Address()->setStreet($dataOrder['pickup']['pickup_address'])
        ->setNumber($dataOrder['pickup']['pickup_number'])
        ->setCounty($dataOrder['pickup']['pickup_neighborhood'])
        ->setCity($dataOrder['pickup']['pickup_city'])
        ->setState($dataOrder['pickup']['pickup_zone'])
        ->setCountry($dataOrder['customer_shipping']['shipping_address']['pais'])
        ->setZipcode($dataOrder['pickup']['pickup_postcode']);

        if (!empty($dataOrder['pickup']['pickup_complement'])){
          $shipping_address->setAdditionalInformation($dataOrder['pickup']['pickup_complement']);  
        }    
      }else{
        $shipping_address = $shipping->Address()->setStreet($dataOrder['customer_shipping']['shipping_address']['logradouro'])
        ->setNumber($dataOrder['customer_shipping']['shipping_address']['numero'])
        ->setCounty($dataOrder['customer_shipping']['shipping_address']['bairro'])
        ->setCity($dataOrder['customer_shipping']['shipping_address']['cidade'])
        ->setState($dataOrder['customer_shipping']['shipping_address']['estado'])
        ->setCountry($dataOrder['customer_shipping']['shipping_address']['pais'])
        ->setZipcode($dataOrder['customer_shipping']['shipping_address']['zipcode']);

        if (isset($dataOrder['customer_shipping']['shipping_address']['complemento'])){
          $shipping_address->setAdditionalInformation($dataOrder['customer_shipping']['shipping_address']['complemento']);  
        }  
        if (isset($dataOrder['customer_shipping']['shipping_address']['reference'])){
          $shipping_address->setReference($dataOrder['customer_shipping']['shipping_address']['reference']);  
        }  
      }
    
      
      //Telefones
      foreach ($dataOrder['customer_shipping']['phones'] as $phone){
        $newphone = new Phone();
        $newphone->setType($phone['type'])
          ->setDdi($phone['ddi'])
          ->setDdd($phone['ddd'])
          ->setNumber($phone['number']);  
        $shipping->addPhone($newphone);  
      }

      if (isset($dataOrder['shipping_type'])){
        $shipping->setDeliveryType($dataOrder['shipping_type']);
      }

      if (isset($dataOrder['shipping_value'])){
        $shipping->setPrice($dataOrder['shipping_value']);
      }

      if (isset($dataOrder['shipping_time'])){
        $shipping->setDeliveryTime($dataOrder['shipping_time']);
      }    

      if (isset($dataOrder['shipping_store_document'])){
        $shipping->setPickUpStoreDocument($dataOrder['shipping_store_document']);
      }    
      //Fim dados de envio    

      $payment_sequential = (count($dataOrder['payments'])>1) ? 1 : 0;

      foreach ($dataOrder['payments'] as $payment){
        $newpayment = new Payment();

        if($payment_sequential>0){
          $newpayment->setSequential($payment_sequential);	
          $payment_sequential++;
        }

        $newpayment->setDate($payment['date']);	
        $newpayment->setValue($payment['total']);	
        $newpayment->setType($payment['type']);

        if (isset($payment['installments'])){
          $newpayment->setInstallments($payment['installments']);	
        }

        if (isset($payment['interest']) && $payment['interest']){
          $newpayment->setInterestRate($payment['interest']['taxa_juros']);
          $newpayment->setInterestValue($payment['interest']['total_juros']);	        
        }      
        
        $newpayment->setCurrency($payment['currency_code']);	
        
        $newpayment->setAddress($billing_address);	

        if (isset($payment['voucher'])){
          $newpayment->setVoucherOrderOrigin($payment['voucher']);
        }

        $card = new Card();
        $card->setNumber($payment['card']['number']);	
        $card->setBin($payment['card']['bin']);	
        $card->setEnd($payment['card']['end']);	
        $card->setType($payment['card']['type']);	
        $card->setValidityDate($payment['card']['validity']);	
        $card->setOwnerName($payment['card']['name']);	
        $card->setDocument($payment['card']['document']);	

        $newpayment->setCard($card);
        
        $order->addPayment($newpayment);  
      }   
      
      foreach ($dataOrder['products'] as $product){
        $newItem = new Item();
        $newItem->setCode($product['product_id']);	
        $newItem->setName($product['description']);	
        if (isset($product['barcode'])){
          $newItem->setBarCode($product['barcode']);	
        }
        $newItem->setValue($product['value']);	
        $newItem->setAmount($product['quantity']);	

        if (isset($product['category_id'])){
          $newItem->setCategoryID($product['category_id']);	
          $newItem->setCategoryName($product['category_name']);
        }

        if (isset($product['is_gift'])){
          $newItem->setIsGift($product['is_gift']);
        }

        /* iformações para caso de marketplace (nesse caso, outra loja vendendo na nossa)
          $newItem->setSellerName($product['product_id']);
          $newItem->setSellerDocument($product['product_id']);
          $newItem->setIsMarketPlace($product['product_id']);
          $newItem->setShippingCompany($product['product_id']);   
        */ 

        $order->addItem($newItem);   
      }    
      
      $result = (new Operation($this->environment,$this->authentication))->createOrder($order);
      return json_decode($result); 
    } catch (Exception $e) {
        $logData = [
            'message'  => 'Erro ao processar a analise de fraude',
            'exception'=> [
                'type'    => get_class($e),
                'message' => $e->getMessage(),
                'code'    => $e->getCode(),
                'file'    => $e->getFile(),
                'line'    => $e->getLine(),
                'trace'   => $e->getTraceAsString()
            ],
            'datetime' => date('c'), // data/hora no padrão ISO
        ];
      $this->log->write(json_encode($logData, JSON_UNESCAPED_UNICODE));
    }

  }

  public function getStatus($order_id){
    $this->setAuthentication();
    $result = (new Operation($this->environment,$this->authentication))->getOrderStatus($order_id);
    return json_decode($result); 
  }  

  public function validateCredential($login, $pwd) {
      $this->authentication = new Authentication(
          $login,
          $pwd,
          $this->environment
      );

      $header = [
          'Content-Type: application/json',
          'Accept: application/json',
          'Authorization: Bearer '. $this->authentication->getToken()
      ];

      $urlrequest = $this->environment->getApiUrl().'v1/orders/0/status';
      $requestResult = (new CurlRequest())->callAPI($urlrequest,'GET',false, $header, false, $retorno);

      return $retorno != '401';
  }
}

