<?php
$loader = $this->registry->get('load');
$loader->controller('payment/payment_address');

class ControllerPaymentClearsale extends Controller {

    public function setNewOrder($data){
        $this->load->type('tipoclearsale');
        $this->load->type('tiporede');
        $this->load->type('tipocieloapi');
        $this->load->dmodel('checkout/order');
        $this->load->dmodel('payment/payment_info');
        try {

            if(substr_count(strtolower($data['order_info']['shipping_code']),'correios')>0){
                $shipping_type = Type_ClearSaleFrete::Tp_Correio;
            }else if (strtolower($data['order_info']['shipping_code'])=='pickup.pickup'){
                $shipping_type = Type_ClearSaleFrete::Tp_Retirada_loja;
            }else{
                $shipping_type = Type_ClearSaleFrete::Tp_Outros;
            }

            $dataOrder = array(
                "order_id"   => (string)$data['order_info']['order_id'],
                "session_id" => (string)md5(session_id().(string)$this->session->data['order_id']) ,
                "data" => $this->formatDateClearSale($data['order_info']['date_added']),
                "email" => (string)$data['order_info']['email'],
                "total_pedido" => (float)$data['order_info']['total'],
                "ip" => (string)$data['order_info']['ip'],
                "status_pedido" => Type_ClearSaleStatusEntrada::Tp_Novo,
                "origem" => (string)Type_OrigemSistema::getNickFromConstValue($data['order_info']['origem_pedido']),
                "pais" => 'Brasil',
                "nacionalidade" => 'Brasileiro',
                "observacao" => 'Pedido ID:'.$data['order_info']['order_id'].' | Frete: '.$data['order_info']['shipping_method'],
                "produto_clearsale" => (int)$this->config->get('clearsale_tipo_integracao'),
                "shipping_type" => (string)$shipping_type,
                "logged_email" => (string)$data['order_info']['email'],
                "logged_login" => (string)$data['order_info']['email'],
                "is_logged" => (boolean)true
            );

            if (isset($data['payment_info']['qtd_parcela'])){
                $dataOrder['parcelas'] = (int)$data['payment_info']['qtd_parcela'];
            }

            if (isset($data['order_info']['shipping_simalation_days']) && $data['order_info']['shipping_simalation_days']>0){
                $dataOrder['shipping_time'] = (string)$data['order_info']['shipping_simalation_days'];
            }

            if ($this->config->get('fields_register_brazil_tipo_de_pessoa')<>Type_CadastroPessoa::Tp_Ambos) {
                $dataOrder['tipo_ecommerce'] = ($this->config->get('fields_register_brazil_tipo_de_pessoa')==Type_CadastroPessoa::Tp_Fisico) ? Type_ClearSaleEcommerce::getConstFromNickValue(Type_ClearSaleEcommerce::Tp_B2C) : Type_ClearSaleEcommerce::getConstFromNickValue(Type_ClearSaleEcommerce::Tp_B2B);
            }

            $order_totals = $this->dmodel_checkout_order->getOrderTotals($data['order_info']['order_id']);
            if($order_totals){
                $ecm_descontos  = 0;
                $ecm_acrescimos = 0;

                foreach ($order_totals as $total){
                    switch ($total['code']) {
                        case 'sub_total' : $dataOrder["total_produto"] = (float)$total['value'];
                        break;
                        case 'shipping' : $dataOrder["shipping_value"] = (float)$total['value'];
                        break;
                        case 'total' : $dataOrder["total_pedido"] = (float)$total['value'];
                        break;
                        case 'rede_api_acrescimo' :
                            $interest["total_juros"] = (float)round($total['value'], 2);
                            $interest["taxa_juros"] = (float)str_replace(',', '.',$this->config->get('rede_parcela_juros'));
                            $ecm_acrescimos += round($total['value'], 2);
                        break;
                        case 'cielo_api_acrescimo' :
                            $interest["total_juros"] = (float)round($total['value'], 2);
                            $interest["taxa_juros"] = (float)str_replace(',', '.',$this->config->get('cielo_api_parcela_juros'));
                            $ecm_acrescimos += round($total['value'], 2);
                        break;
                        default:
                            if (round($total['value'], 2) < 0){
                                $ecm_descontos += round($total['value'], 2);
                            }else{
                                $ecm_acrescimos += round($total['value'], 2);
                            }
                        break;
                    }
                }
                if($ecm_descontos){
                    $dataOrder['observacao'] .= ' | Descontos: '.$ecm_descontos;
                }
                if($ecm_acrescimos){
                    $dataOrder['observacao'] .= ' | Acréscimos(Taxas/Impostos/outros): '.$ecm_acrescimos;
                }
            }

            //Dados de pagamento
            if (isset($this->request->post['isHolder']) && $this->request->post['isHolder']){
                $dataOrder['customer'] = array(
                    'customer_id' => (string)$data['order_info']['customer_id'],
                    'tipo_pessoa' => $data['order_info']['cpf'] ? Type_ClearSalePessoa::Tp_Fisica : Type_ClearSalePessoa::Tp_Juridica,
                    'cpf_cnpj' => $data['order_info']['cpf'] ? (string)$data['order_info']['cpf'] : (string)$data['order_info']['cnpj'],
                    'nome' => $data['order_info']['firstname'].' '.$data['order_info']['lastname'],
                    'email' => $data['order_info']['email']
                );
                if ($data['order_info']['rg']||$data['order_info']['inscricao_estadual']){
                    $dataOrder['customer']['rg_ie']  = ($data['order_info']['rg']) ? $data['order_info']['rg'] : $data['order_info']['inscricao_estadual'];
                }

                if (isset($data['order_info']['data_nascimento']) && substr_count($data['order_info']['data_nascimento'], '0') <= 5){
                    $dataOrder['customer']['data_nascimento']  = $this->formatDateClearSale($data['order_info']['data_nascimento']);
                } elseif(isset($data['payment_info']['customer_data_nascimento']) && substr_count($data['payment_info']['customer_data_nascimento'], '0') <= 5) {
                    $dataOrder['customer']['data_nascimento']  = $this->formatDateClearSale($data['payment_info']['customer_data_nascimento']);
                }

                if (isset($data['order_info']['sexo'])){
                    $dataOrder['customer']['sexo'] = strtoupper($data['order_info']['sexo']);
                }

                $dataOrder['customer']['payment_address'] = array(
                    'logradouro' => $data['order_info']['payment_address_1'],
                    'numero' => (string)$data['order_info']['payment_numero'],
                    'bairro' => $data['order_info']['payment_address_2'],
                    'cidade' => $data['order_info']['payment_city'],
                    'estado' => $data['order_info']['payment_zone_code'],
                    'pais' => 'Brasil',
                    'zipcode' => (string)$data['order_info']['payment_postcode'],
                    'complemento' => (string)$data['order_info']['payment_complemento']
                );
                if ($data['order_info']['telephone']){
                    $dataOrder['customer']['phones'][] = array(
                        'type' => (int)Type_ClearSaleTelefone::Tp_NaoDefinido,
                        'ddi'  => (int)55,
                        'ddd'  => (int)substr($data['order_info']['telephone'], 0, 2),
                        'number'=> (int)substr($data['order_info']['telephone'], 2, 8)
                    );
                }
                if ($data['order_info']['celular']){
                    $dataOrder['customer']['phones'][] = array(
                        'type' => (int)Type_ClearSaleTelefone::Tp_Celular,
                        'ddi'  => (int)55,
                        'ddd'  => (int)substr($data['order_info']['celular'], 0, 2),
                        'number'=> (int)substr($data['order_info']['celular'], 2, 9)
                    );
                }

            }else{
                $this->load->model('account/address');
                $this->load->dmodel('localisation/zone');
                $this->load->dmodel('localisation/ibge');

                $shipping_address    = $this->model_account_address->getAddress($this->request->post['shipping_address_id']);
                $shipping_address_uf = $this->dmodel_localisation_zone->getZone($shipping_address['zone_id'])['code'];

                $dataOrder['customer'] = array(
                    'customer_id' => (string)'NT_'.$data['order_info']['customer_id'],/* NT = Não titular, apensa para enviar um ID, pois nesse caso não temos */
                    'tipo_pessoa' => $this->request->post['pessoa'] == 'J' ? Type_ClearSalePessoa::Tp_Juridica : Type_ClearSalePessoa::Tp_Fisica,
                    'cpf_cnpj' => $this->request->post['pessoa'] == 'J' ? preg_replace('/([^0-9])/i', '',$this->request->post['cnpj']) : preg_replace('/([^0-9])/i', '',$this->request->post['cpf']),
                    'nome' => $this->request->post['creditcard_name'],
                    'email' => $this->request->post['email']
                );
                if ($data['order_info']['rg']||$data['order_info']['inscricao_estadual']){
                    $dataOrder['customer']['rg_ie']  = ($data['order_info']['rg']) ? $data['order_info']['rg'] : $data['order_info']['inscricao_estadual'];
                }

                if ($data['payment_info']['data_nascimento']){
                    $dataOrder['customer']['data_nascimento']  = $this->formatDateClearSale($data['payment_info']['data_nascimento']);
                }

                if (isset($this->request->post['sexo']) && $this->request->post['sexo']){
                    $dataOrder['customer']['sexo'] = strtoupper($this->request->post['sexo']);
                }

                $dataOrder['customer']['payment_address'] = array(
                    'logradouro' => $this->request->post['address_1'],
                    'numero' => (string)$this->request->post['numero'],
                    'bairro' => $this->request->post['address_2'],
                    'cidade' => $this->dmodel_localisation_ibge->getCidadePorCodigo($this->request->post['codigo_municipio']),
                    'estado' => $shipping_address_uf,
                    'pais'   => 'Brasil',
                    'zipcode' => (string)str_replace('-','',$this->request->post['postcode']),
                    'complemento' => (string)$this->request->post['complemento']
                );

                if ($data['order_info']['telephone']){
                    $telefone = preg_replace('/([^0-9])/i', '', $this->request->post['numero_telefone']);
                    if ($this->request->post['tipo_telefone'] == Type_PaymentPhone::Tp_Celular) {
                        $dataOrder['customer']['phones'][] = array(
                            'type' => (int)Type_ClearSaleTelefone::Tp_Celular,
                            'ddi'  => (int)55,
                            'ddd'  => (int)substr($telefone, 0, 2),
                            'number'=> (int)substr($telefone, 2, 9)
                        );
                    }else{
                        $dataOrder['customer']['phones'][] = array(
                            'type' => (int)Type_ClearSaleTelefone::Tp_NaoDefinido,
                            'ddi'  => (int)55,
                            'ddd'  => (int)substr($telefone, 0, 2),
                            'number'=> (int)substr($telefone, 2, 8)
                        );
                    }

                }

            }
            //Dados de pagamento

            //Dados de entrega

            $dataOrder['customer_shipping'] = array(
                'customer_id' => (string)$data['order_info']['customer_id'],
                'tipo_pessoa' => $data['order_info']['cpf'] ? Type_ClearSalePessoa::Tp_Fisica : Type_ClearSalePessoa::Tp_Juridica,
                'cpf_cnpj' => $data['order_info']['cpf'] ? (string)$data['order_info']['cpf'] : (string)$data['order_info']['cnpj'],
                'nome' => $data['order_info']['firstname'].' '.$data['order_info']['lastname'],
                'email' => $data['order_info']['email']
            );
            if ($data['order_info']['rg']||$data['order_info']['inscricao_estadual']){
                $dataOrder['customer_shipping']['rg_ie']  = ($data['order_info']['rg']) ? $data['order_info']['rg'] : $data['order_info']['inscricao_estadual'];
            }
            if ($data['payment_info']['data_nascimento'] && substr_count($data['payment_info']['data_nascimento'], '0') <= 5){
                $dataOrder['customer_shipping']['data_nascimento']  = $this->formatDateClearSale($data['payment_info']['data_nascimento']);
            }
            if (isset($data['order_info']['sexo']) && $data['order_info']['sexo']){
                $dataOrder['customer_shipping']['sexo'] = strtoupper($data['order_info']['sexo']);
            }
            if ($shipping_type == Type_ClearSaleFrete::Tp_Retirada_loja && $this->config->get('pickup_address_info')){

                $address_info = $this->config->get('pickup_address_info');
                $this->load->dmodel('localisation/zone');
                $shipping_address_uf = $this->dmodel_localisation_zone->getZone($address_info['zone_id'])['code'];

                $dataOrder['customer_shipping']['shipping_address'] = array(
                    'logradouro' => $address_info['address_1'],
                    'numero' => (string)$address_info['numero'],
                    'bairro' => $address_info['address_2'],
                    'cidade' => $address_info['city'],
                    'estado' => $shipping_address_uf,
                    'pais' => 'Brasil',
                    'zipcode' => (string)$address_info['postcode'],
                    'complemento' => (string)$address_info['complemento']
                );

            }else{
                $dataOrder['customer_shipping']['shipping_address'] = array(
                    'logradouro' => $data['order_info']['shipping_address_1'],
                    'numero' => (string)$data['order_info']['shipping_numero'],
                    'bairro' => $data['order_info']['shipping_address_2'],
                    'cidade' => $data['order_info']['shipping_city'],
                    'estado' => $data['order_info']['shipping_zone_code'],
                    'pais' => $data['order_info']['shipping_country'],
                    'zipcode' => (string)$data['order_info']['shipping_postcode'],
                    'complemento' => (string)$data['order_info']['shipping_complemento']
                );
            }
            if ($data['order_info']['telephone']){
                $dataOrder['customer_shipping']['phones'][] = array(
                    'type' => (int)Type_ClearSaleTelefone::Tp_NaoDefinido,
                    'ddi'  => (int)55,
                    'ddd'  => (int)substr($data['order_info']['telephone'], 0, 2),
                    'number'=> (int)substr($data['order_info']['telephone'], 2, 8)
                );
            }
            if ($data['order_info']['celular']){
                $dataOrder['customer_shipping']['phones'][] = array(
                    'type'   => (int)Type_ClearSaleTelefone::Tp_NaoDefinido,
                    'ddi'    => (int)55,
                    'ddd'    => (int)substr($data['order_info']['celular'], 0, 2),
                    'number' => (int)substr($data['order_info']['celular'], 2, 9)
                );
            }
            //Dados de entrega

            foreach ($data['products'] as $product){
                $dataOrder['products'][] = array(
                    'product_id' => (string)$product['product_id'],
                    'description' => $product['name'],
                    'barcode' =>  $product['codigo_barra'] ? (string)$product['codigo_barra'] : null,
                    'value' => (float)$product['price'],
                    'quantity' => (int)$product['quantity']
                );
            }

            $creditcard_ccno = str_replace(' ', '', $this->request->post['creditcard_ccno']);

            switch ($this->request->post['creditcard_cctype']) {
                case Type_RedeBandeira::getNickFromConstValue(Type_RedeBandeira::Tp_Visa) :
                case Type_CieloApiBandeira::getNickFromConstValue(Type_CieloApiBandeira::Tp_Visa) :
                    $creditcard_cctype = Type_ClearSaleCartao::Tp_Visa;
                    break;
                case Type_RedeBandeira::getNickFromConstValue(Type_RedeBandeira::Tp_Mastercard) :
                case Type_CieloApiBandeira::getNickFromConstValue(Type_CieloApiBandeira::Tp_Mastercard) :
                    $creditcard_cctype = Type_ClearSaleCartao::Tp_MasterCard;
                    break;
                case Type_RedeBandeira::getNickFromConstValue(Type_RedeBandeira::Tp_Amex) :
                case Type_CieloApiBandeira::getNickFromConstValue(Type_CieloApiBandeira::Tp_Amex) :
                    $creditcard_cctype = Type_ClearSaleCartao::Tp_AmericanExpress;
                    break;
                case Type_RedeBandeira::getNickFromConstValue(Type_RedeBandeira::Tp_Diners) :
                case Type_CieloApiBandeira::getNickFromConstValue(Type_CieloApiBandeira::Tp_Diners) :
                    $creditcard_cctype = Type_ClearSaleCartao::Tp_Diners;
                    break;
                case Type_RedeBandeira::getNickFromConstValue(Type_RedeBandeira::Tp_Elo) :
                case Type_CieloApiBandeira::getNickFromConstValue(Type_CieloApiBandeira::Tp_Elo) :
                    $creditcard_cctype = Type_ClearSaleCartao::Tp_Elo;
                    break;
                default :
                    $creditcard_cctype = Type_ClearSaleCartao::Tp_Outros;
                    break;
            }

            $dataOrder['payments'][] = array(
                'date' => $this->formatDateClearSale($data['order_info']['date_added']),
                'total' => (float)$data['order_info']['total'],
                'type' => Type_ClearSalePagamento::Tp_Cartao_Credito,
                'installments'  => (int)$data['payment_info']['qtd_parcela'],
                'currency_code' => (int)986,/* 986 -> Real */
                'interest' => isset($interest) ? $interest : false,
                'card' => array(
                    "number" => ftr_geral::MaskCard(strlen($creditcard_ccno), substr($creditcard_ccno, 0, 6), substr($creditcard_ccno, 12, strlen($creditcard_ccno))),
                    "bin"=>  substr($creditcard_ccno, 0, 6),
                    "end"=> substr($creditcard_ccno, -4),
                    "type"=> (int)$creditcard_cctype,
                    "validity" => (string)($data['payment_info']['expire']),
                    "name" => $data['payment_info']['creditcard_name'],
                    "document" => $dataOrder['customer']['cpf_cnpj']
                )
            );

            $retorno = $this->clearsale->setOrder($dataOrder);

            $data_anti_fraude = array(
                'order_id' => $data['order_info']['order_id'],
                'antifraud_method' =>  Type_AntiFraudeCheckout::Tp_CleaSaleTotal,
                'fraud_analysis_id' => $retorno->packageID,
                'status' => Type_ClearSaleStatusRetorno::getConstFromNickValue($retorno->orders[0]->status),
                'score' => $retorno->orders[0]->score
            );
            $this->dmodel_payment_payment_info->addPaymentAntiFraude($data_anti_fraude);

            return $retorno;

        } catch (Exception $e) {
            $this->log->write('Erro ao processar a analise de fraude: '.print_r($e,true));
        }

    }

    public function formatDateClearSale(String $date){
        //Clear sale enviou um email solicitando novo padrao de data
        $formated_date = ftr_geral::formatDate($date, 'en');
        $formated_date = Date('Y-m-d H:i:s', strtotime($formated_date));
        return str_replace(' ', 'T', $formated_date) . '.000';
    }

    public function callback(){

        $this->load->type('tipoclearsale');
        $this->load->dmodel('checkout/order');
        $this->load->dmodel('payment/payment_info');

        $json = file_get_contents('php://input');
        $response = json_decode($json);

        if ($response->type == Type_ClearSaleReturnRequest::getNickFromConstValue(Type_ClearSaleReturnRequest::Tp_Status)){
            $retorno = $this->clearsale->getStatus($response->code);
            $data_anti_fraude = array(
                'order_id' => $retorno->code,
                'status' => Type_ClearSaleStatusRetorno::getConstFromNickValue($retorno->status),
                'score' => $retorno->score
            );
            $this->dmodel_payment_payment_info->updatePaymentAntiFraude($data_anti_fraude);


            if ($this->config->get('clearsale_captura_automatica') && in_array($retorno->status,[Type_ClearSaleStatusRetorno::Tp_APA,Type_ClearSaleStatusRetorno::Tp_APM,Type_ClearSaleStatusRetorno::Tp_APP]) && $retorno->score < 30 ){
                $this->processaPagamentoPendente($retorno->code);
            }
        }

    }

    public function processaPagamentoPendente($order_id){

      try {

        $this->language->load('sale/order');
        $this->load->model('sale/order');
        $this->load->dmodel('checkout/order');
        $this->load->dmodel('payment/payment_info');
        $this->load->helper('ftr_geral');
        $this->load->type('tipocomum');

        $order_info = $this->model_sale_order->getOrder($order_id);
        $payment_credit_info = $this->dmodel_payment_payment_info->getPaymentInfo($order_id, Type_PagamentoTabela::Tp_Cartao);

        switch ($order_info['payment_code']){

          case 'rede_credito' : /*Rede*/
            $this->load->type('tiporede');

            $captura = $this->rede->capturaPagamento($payment_credit_info['valor_pagamento'],$payment_credit_info['tid']);
            if ($captura['status_captura'] == Type_PagamentoStatusCaptura::Tp_Capturado){
              $paymentinfo = array();
              $paymentinfo['cod_retorno']        = $captura['codRetorno'];
              $paymentinfo['mensagem_retorno']   = $captura['msgRetorno'];
              $paymentinfo['tid']                = $captura['tid'];
              $paymentinfo['nsu']                = $captura['nsu'];
              $paymentinfo['data_pagamento']     = $captura['dataCaptura']->format('Y-m-d H:i:s');
              $paymentinfo['status_captura']     = $captura['status_captura'];
              $paymentinfo['payment_id']         = $captura['referencia'];
              $paymentinfo['order_id']           = $order_id;
              $paymentinfo['status_pagamento']   = Type_RedeStatusPgto::Tp_RedePago;

              $order_status_id = $this->config->get('rede_order_status_id');
              $retorno_status = Type_RedeStatusPgto::getNickFromConstValue(Type_RedeStatusPgto::Tp_RedePago);
              $this->dmodel_payment_payment_info->updatePaymentCreditCard($paymentinfo);
            }

          break;
          case 'cielo_api_credito' : /*Cielo Checkout 3.0*/
            $this->load->type('tipocieloapi');
            $data = new DateTime($this->db->dataAtual(), new DateTimeZone('America/Sao_Paulo'));

            $cielocentavos = number_format($payment_credit_info['valor_pagamento'], 2, '', '');
            $retornoAPI = $this->cieloapi->cieloCapturaPagamento($payment_credit_info['payment_id'], $cielocentavos);
            $mensagemTraduzida = $retornoAPI['msgRetorno']; //Type_CieloApiRetorno::getNickFromConstValue($retornoAPI['codRetorno']);

            switch ($retornoAPI['status']) {
              case Type_CieloApiStatus::Tp_AptoAFinalizar : $order_status_id = $this->config->get('cielo_api_order_status_id');
              break;
              case Type_CieloApiStatus::Tp_Finalizado : $order_status_id = $this->config->get('cielo_api_order_pg_id');
              break;
              case Type_CieloApiStatus::Tp_Negado : $order_status_id = $this->config->get('cielo_api_order_ne_id');
              break;
              case Type_CieloApiStatus::Tp_Cancelado;
              case Type_CieloApiStatus::Tp_CanceladoAposHorario;
              case Type_CieloApiStatus::Tp_CanceladoFalha : $order_status_id = $this->config->get('cielo_api_order_status_cancelado_id');
              break;
              case Type_CieloApiStatus::Tp_Aguardando;
              case Type_CieloApiStatus::Tp_AguardandoStatusIF : $order_status_id = $this->config->get('cielo_api_order_pe_id');
              break;
            }

            $paymentinfo = array();
            $paymentinfo['tid']                = $retornoAPI['tid'];
            $paymentinfo['numero_autorizacao'] = $retornoAPI['numAutorizacao'];
            $paymentinfo['cod_autorizacao']    = $retornoAPI['codAutorizacao'];
            $paymentinfo['mensagem_retorno']   = $mensagemTraduzida;
            $paymentinfo['cod_retorno']        = $retornoAPI['codRetorno'];
            $paymentinfo['order_id']           = $order_id;
            $paymentinfo['valor_pagamento']    = $payment_credit_info['valor_pagamento'];
            $paymentinfo['data_pagamento']     = $data->format("Y-m-d H:i:s");
            $paymentinfo['status_pagamento']   = $order_status_id;
            $paymentinfo['status_retorno']     = $retornoAPI['status'];
            $paymentinfo['tipo_cartao']        = Type_Card::Tp_Credito;
            $paymentinfo['cartao_mascara']     = $payment_credit_info['cartao_mascara'];
            $paymentinfo['cartao_bandeira']    = $payment_credit_info['cartao_bandeira'];
            $paymentinfo['qtd_parcela']        = $payment_credit_info['qtd_parcela'];

            $this->dmodel_payment_payment_info->addPaymentCreditCard($paymentinfo);

            $retorno_status = Type_CieloApiStatus::getNickFromConstValue($retornoAPI['status']);
            break;
        }

        if (isset($order_status_id)){
            $data = array(
              'order_status_id' => $order_status_id,
              'cometario_html' => false,
              'comment' => ''
            );
            $this->dmodel_checkout_order->addOrderHistory($order_id, $data);
        }

      } catch (Exception $e) {
        $this->log->write('Erro ao fazer captura do apgamento: '.print_r($e,true));
      }

    }

}