<?php

class DadosST{
    public $EmpresaID  = 0;
	public $CadastroID = 0;
	public $produtos = array();

	public function addProdutos($produtoClass){
	  array_push($this->produtos, $produtoClass);
	}

	public function getProducts(){
	  return $this->produtos;
	}
}

class Produto{
    public $ProdutoId      = 0;
	public $quantidade     = 0;
	public $ValorUnitario  = 0;
	public $AcrescimoPerc  = 0;
	public $AcrescimoValor = 0;
	public $DescontoPerc   = 0;
	public $SeguroValor    = 0;
	public $FreteValor     = 0;
}



class Futuracalcularst{

  private $registry;

  public function __construct($registry) {

  }

  public function loadInstances($registry){
	$this->config   = $registry->get('config');
	$this->db       = $registry->get('db');
	$this->request  = $registry->get('request');
	$this->session  = $registry->get('session');
	$this->cart     = $registry->get('cart');
	$this->tax      = $registry->get('tax');
	$this->registry = $registry;

	if(!isset($this->session->data['histcalculost'])){
		$this->session->data['histcalculost'] = new DadosST();
	}

	if(!isset($this->session->data['ultimocalculost'])){
		$this->session->data['ultimocalculost'] = false;
	}

	if(!isset($this->session->data['ultimaconsultarest'])){
		$this->session->data['ultimaconsultarest'] = 0;
	}

	if(!isset($this->session->data['IDSession'])){
	    $this->session->data['IDSession'] = null;
	}

	if(!isset($this->session->data['Calculodataexpire'])){
	    $this->session->data['Calculodataexpire'] = null;
	}

    /*
      No caso da nipocenter o carrinho s� calcula se o cliente
      habilitar no bot�o...
      guarda na sessao esse controle
      byMatheus
    */

    if(!isset($this->session->data['habilitacalculo'])){
      $this->session->data['habilitacalculo'] = false;

    }

    if(!isset($this->session->data['habilitafunction'])){
      $this->session->data['habilitafunction'] = false;

    }


  }

  public function __get($name) {
	return $this->registry->get($name);
  }

  public function getSubTotal($produtos) {
	$total = 0;

	foreach ($produtos as $product) {
		$total += $product['total'];
	}
	return $total;
  }

   public function getDesconto(){
		// Totals
		$this->load->model('setting/extension');

		$total_data = array();
		$total = 0;
		$retorno = 0;

		$taxes = $this->cart->getTaxes();

		// Display prices
		if (($this->config->get('config_customer_price') && $this->customer->isLogged()) || !$this->config->get('config_customer_price')) {
			$results = $this->model_setting_extension->getExtensions('total');

			foreach ($results as $result) {
				if ($this->config->get($result['code'] . '_status')) {
					$this->load->model('total/' . $result['code']);

			        $this->{'model_total_' . $result['code']}->getTotal($total_data, $total, $taxes);
				}

			}

			foreach($total_data as $data){

			  if ($data['value'] < 0){
				$retorno += $data['value'];
			  }

			}
		}

        return $retorno * -1;
   }

   private function recalculaImpostos(DadosST $ultimoCalculo, DadosST $atual){
     $prodold   = $ultimoCalculo->produtos;
	 $prodatual = $atual->produtos;



     if(sizeof($prodold) != sizeof($prodatual)){
	   return true;
	 }

	 if(($ultimoCalculo->EmpresaID != $atual->EmpresaID) || ($ultimoCalculo->CadastroID != $atual->CadastroID)){
	    return true;
	 }

	 $produtosOld  = $ultimoCalculo->produtos;
	 $produtoAtual = $atual->produtos;

	 $x = 0;
     foreach($produtosOld as $produtoOld){
		if(
		    ($produtoOld->ProdutoId      != $produtoAtual[$x]->ProdutoId)      ||
			($produtoOld->quantidade     != $produtoAtual[$x]->quantidade)     ||
			($produtoOld->ValorUnitario  != $produtoAtual[$x]->ValorUnitario)  ||
			($produtoOld->AcrescimoPerc  != $produtoAtual[$x]->AcrescimoPerc)  ||
			($produtoOld->AcrescimoValor != $produtoAtual[$x]->AcrescimoValor) ||
			($produtoOld->DescontoPerc   != $produtoAtual[$x]->DescontoPerc)   ||
			($produtoOld->SeguroValor    != $produtoAtual[$x]->SeguroValor)    ||
			($produtoOld->FreteValor     != $produtoAtual[$x]->FreteValor)
		  ){return true;};

		$x ++;
	 }

	 return false;
   }


   private function getDadosST($produtos, $clienteid, $totaldesconto){
    $query = $this->db->query("select value from " . DB_PREFIX . "setting s where (s.key = 'futuracalcularst_usuario') and (s.group = 'futuracalcularst')");

	if(!($query->num_rows)){
      $this->session->data['ultimocalculost'] = false;
	  return false;
	}
	$empresaid = $query->row['value'];

	$dadosst             = new DadosST();
	$dadosst->CadastroID = $clienteid;
	$dadosst->EmpresaID  = $empresaid;

    $totalfrete = 0;

	$subtotal = $this->getSubTotal($produtos);

	foreach($produtos as $produto){
	  $classProduto = new Produto();
	  $baseproduto  = (($produto['quantity'] * $produto['price']) * 100) / $subtotal;

	  $classProduto->ProdutoId       = $produto['id_futura'];
	  $classProduto->quantidade      = $produto['quantity'];
	  $classProduto->ValorUnitario   = $produto['price'];
	  $classProduto->AcrescimoPerc   = 0;
	  $classProduto->AcrescimoValor  = 0;

	  $valorDescProd                 = ($baseproduto  / 100) * $totaldesconto;

	  $classProduto->DescontoPerc    = ($valorDescProd * 100) / $subtotal;

	  $classProduto->SeguroValor     = 0;

	  $classProduto->FreteValor      = ($baseproduto / 100) * $totalfrete;

	  $dadosst->addProdutos($classProduto);
	}

    return $dadosst;
   }


   private function getJsonInput($produtos, $clienteid, $totaldesconto){

    $dadosst = $this->getDadosST($produtos, $clienteid, $totaldesconto);

	$recalcular = $this->recalculaImpostos($this->session->data['histcalculost'], $dadosst);

    $this->session->data['histcalculost'] = $dadosst;

	//se n�o teve mudan�a, nao recalcula os valores....
	if(($recalcular) || (!$this->session->data['ultimocalculost'])){
	  $this->session->data['ultimocalculost'] = false;
	  return $dadosst;
	}else{
	  return false;
	}

  }

  public function getconfiguracoes(){
    $result = array();

	$query = $this->db->query("select s.value, s.key from " . DB_PREFIX . "setting s where (s.group = 'futuracalcularst') and ((s.key = 'futuracalcularst_status') or (s.key = 'futuracalcularst_user') or (s.key = 'futuracalcularst_senha') or (s.key = 'futuracalcularst_ip') or (s.key = 'futuracalcularst_porta') or (s.key = 'futuracalcularst_id_empresa')) ");

	foreach($query->rows as $data){
      $result[$data['key']] = $data['value'];
	}
	return $result;
  }

  private function get_headers_from_curl_response($headerContent)
  {
	$headers = array();
	$arrRequests = explode("\r\n\r\n", $headerContent);

	for ($index = 0; $index < count($arrRequests) -1; $index++) {

		foreach (explode("\r\n", $arrRequests[$index]) as $i => $line)
		{
			if ($i === 0)
				$headers[$index]['http_code'] = $line;
			else
			{
				list ($key, $value) = explode(': ', $line);
				$headers[$index][$key] = $value;
			}
		}
	}

	return $headers;
  }


  public function getWebServerCalculoST($jsoninput){
	//pega configuracoes no model
	$confs = $this->getconfiguracoes();

	$user  = $confs['futuracalcularst_user'];
	$senha = $confs['futuracalcularst_senha'];

	$ch = curl_init();

	if (!isset($this->session->data['IDSession'])){
	   curl_setopt($ch, CURLOPT_HTTPHEADER, array ( "Accept: application/json", "Content-Type: text/plain; charset=utf-8" ) ) ;
	}else{
	  curl_setopt($ch, CURLOPT_HTTPHEADER, array ( "Accept: application/json", "Content-Type: text/plain; charset=utf-8", "Pragma: dssession=" . $this->session->data['IDSession'] ) ) ;
	}


	curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
	curl_setopt($ch, CURLOPT_USERPWD, $user . ":" . $senha);
	curl_setopt($ch, CURLOPT_HEADER, true ) ;
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true ) ;
	curl_setopt($ch, CURLOPT_POST, TRUE ) ;
	curl_setopt($ch, CURLOPT_URL, "http://" . $confs['futuracalcularst_ip'] . ":" . $confs['futuracalcularst_porta'] . "/datasnap/rest/TfOtr_ServerMethodsUnit/%22CalculaST%22/") ;
	curl_setopt($ch, CURLOPT_POSTFIELDS, $jsoninput);
	$result = curl_exec($ch);

	if(!$result){
      $this->session->data['ultimaconsultarest'] = time();
	  return false;
	}

	//Separando header e retorno
	$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
	$header = substr($result, 0, $header_size);
	$json = substr($result, $header_size, strlen($result) - strlen($header_size));
	//transformando o header em array



	$arrayHeader = null;

	if($header != ''){
	    $lista = $this->get_headers_from_curl_response($header);

		for($i = 0; $i < sizeOf($lista); $i++){
			if(array_key_exists("Pragma", $lista[$i])){
			  $arrayHeader = $lista[$i];
			  break;
			}
		}

    }else {
	  $this->session->data['ultimaconsultarest'] = time();
	  return false;
	}



	//capturando apenas sessao dsession do retorno
	$dsession = "";
	if(isset($arrayHeader["Pragma"])){
		$dsession = substr($arrayHeader["Pragma"], 10, strpos($arrayHeader["Pragma"], ',')-10);
	}

	if(isset($dsession)){
	    $this->session->data['IDSession'] = $dsession;

	}

	curl_close($ch);

    return $json;
  }


  public function finalizaUltimaSessao(){

      if(!isset($this->session->data['IDSession'])){
          return;
      }

      $confs = $this->getconfiguracoes();

      $user  = $confs['futuracalcularst_user'];
      $senha = $confs['futuracalcularst_senha'];

      try{
          $ch = curl_init();
          curl_setopt($ch, CURLOPT_HTTPHEADER, array ( "Accept: application/json", "Content-Type: text/plain; charset=utf-8", "Pragma: dssession=" . $this->session->data['IDSession'] ) ) ;
          curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
          curl_setopt($ch, CURLOPT_USERPWD, $user . ":" . $senha);
          curl_setopt($ch, CURLOPT_HEADER, true ) ;
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, true ) ;
          curl_setopt($ch, CURLOPT_POST, FALSE ) ;
          curl_setopt($ch, CURLOPT_URL, "http://" . $confs['futuracalcularst_ip'] . ":" . $confs['futuracalcularst_porta'] . "/datasnap/rest/TfOtr_ServerMethodsUnit/%22CloseSession%22/") ;
          $resultado=curl_exec($ch);
          curl_close($ch);
      }catch(Exception $e){
      }

      $this->session->data['IDSession'] = null;

  }


  public function getJsonCalculaST($produtos, $cliente, $totaldesconto){


	if(!$produtos){
	  return false;
	}

    if(((!$this->session->data['habilitacalculo']) || (!$this->session->data['habilitafunction'])) && (!isset($this->session->data['shipping_method']['cost']))){
        $recalcular = true;


        if($this->session->data['ultimocalculost']){
            $dadosst = $this->getDadosST($produtos, $cliente, $totaldesconto);
            $recalcular = $this->recalculaImpostos($this->session->data['histcalculost'], $dadosst);
        }

        if($this->session->data['ultimocalculost'] && (!$recalcular))
        {
            return $this->session->data['ultimocalculost'];
        }else{
            return false;
        }
    }

    /* Ao finalizar a compra, existe o frete, então, para não ficar recalculando toda hora,
     * estou incluindo uma expiração para a ST de 2 HORAS... ESPECIFICO PRA NIPO
     */

    //$this->session->data['Calculodataexpire']


    if(isset($this->session->data['Calculodataexpire']) && ($this->session->data['Calculodataexpire'] > time())){

        $recalcular = false;
        if($this->session->data['ultimocalculost']){
            $dadosst = $this->getDadosST($produtos, $cliente, $totaldesconto);
            $recalcular = $this->recalculaImpostos($this->session->data['histcalculost'], $dadosst);
        }

        if($this->session->data['ultimocalculost'] && (!$recalcular))
        {
            return $this->session->data['ultimocalculost'];
        }

    }



	$vatual = time();

	//Captura JSON no model
    $jsoninput = $this->getJsonInput($produtos, $cliente, $totaldesconto);


	if((($vatual - $this->session->data['ultimaconsultarest']) <= 20) && (!$this->session->data['ultimocalculost']) && ($this->session->data['ultimaconsultarest'] != 0)){
	    return false;
	}

	if($this->session->data['ultimocalculost'] && (!json_encode($jsoninput))){

	  return $this->session->data['ultimocalculost'];
	}

	if((!$this->session->data['ultimocalculost'])  && (!json_encode($jsoninput))){

	  return false;
	}

	$prodsAux = $jsoninput->produtos;

	$json = array();
	$listjsonCount = 0;
	$countAdd = -1;


	//Consumindo WEBSERVICE em partes de 100 itens cada... ByMatheus
	while(sizeof($prodsAux) > 0){
		$tmpDadosst             = new DadosST();
		$tmpDadosst->CadastroID = $jsoninput->CadastroID;
		$tmpDadosst->EmpresaID  = $jsoninput->EmpresaID;

        $produtosTemp = array();
		for ($count = 0; $count <= 100; $count++){
            if(sizeof($prodsAux) > 0){
			    $countAdd ++;
				array_push($produtosTemp, $prodsAux[$countAdd]);
				unset($prodsAux[$countAdd]);
			}else{
				break;
			}
		}

		$tmpDadosst->produtos = $produtosTemp;

		$jsonTemp = json_encode($tmpDadosst);


		$jsonretorno = $this->getWebServerCalculoST($jsonTemp);

		$jsonconv = json_decode($jsonretorno, true);

		if(array_key_exists('error',$jsonconv)){
		    $this->finalizaUltimaSessao();
			return false;
		}

		$listjsonCount ++;

        array_push($json, $jsonretorno);
	}

	 $this->finalizaUltimaSessao();

	 $this->session->data['Calculodataexpire'] = time() + 43200;// Calcula o momento que vai expirar esse calculo... 12 HORAS

	$this->session->data['ultimocalculost'] = $json;

    return $json;
  }

  function getSTFromArray($pProdutoFutura, $array){

	  if (!is_array($array))
		  return 'N';


	  foreach($array as $arrayitens){


		  $jsonArray = json_decode($arrayitens, true);

		  if (!$jsonArray){
		    return 'N';
		  }

		  if((array_key_exists('result', $jsonArray)) && (array_key_exists(0, $jsonArray['result'])) && (array_key_exists('Produtos', $jsonArray['result'][0]))){
			$produtosLista = $jsonArray['result'][0]['Produtos'];
		  }	else{
            return 'N';
          }

		  for($i = 0; $i <= sizeOf($produtosLista) - 1; $i ++){
			if (strcmp($produtosLista[$i]["ProdutoId"], $pProdutoFutura) == 0){
               return $produtosLista[$i]["SubstTribValor"];
			}
          }

      }

	  return 'N';

  }

  function getIPIFromArray($pProdutoFutura, $array){
	  if (!is_array($array))
		  return 'N';

	  foreach($array as $arrayitens){


		  $jsonArray = json_decode($arrayitens, true);

		  if (!$jsonArray){
		    return 'N';
		  }

		  if((array_key_exists('result', $jsonArray)) && (array_key_exists(0, $jsonArray['result'])) && (array_key_exists('Produtos', $jsonArray['result'][0]))){
			$produtosLista = $jsonArray['result'][0]['Produtos'];
		  }	else{
            return 'N';
          }

		  for($i = 0; $i <= sizeOf($produtosLista) -1; $i ++){

			if (strcmp($produtosLista[$i]["ProdutoId"], $pProdutoFutura) == 0){
               return $produtosLista[$i]["IPIValor"];
			}

          }

      }

	  return 'N';

  }

  function getFCPSTFromArray($pProdutoFutura, $array){
	  if (!is_array($array))
		  return 'N';

	  foreach($array as $arrayitens){


		  $jsonArray = json_decode($arrayitens, true);

		  if (!$jsonArray){
		    return 'N';
		  }

		  if((array_key_exists('result', $jsonArray)) && (array_key_exists(0, $jsonArray['result'])) && (array_key_exists('Produtos', $jsonArray['result'][0]))){
			  $produtosLista = $jsonArray['result'][0]['Produtos'];
		  }	else{
        return 'N';
      }

		  for($i = 0; $i <= sizeOf($produtosLista) -1; $i ++){
    			if (strcmp($produtosLista[$i]["ProdutoId"], $pProdutoFutura) == 0){
                   return $produtosLista[$i]["FcpSubstTribValor"];
    			}
      }

    }

	  return 'N';

  }




  public function jsonencode($json){
    return json_encode($json);
  }

}

?>
