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

class ControllerPaymentYapay extends ControllerPaymentYapayLib
{

    public function __construct($registry)
    {
        parent::__construct($registry);
        parent::load();

        $this->paymentInfo = new PaymentInfo();
        $this->paymentInfo->clearParams();

        if (isset($this->session->data['payment_method']['code_type']) && isset($this->session->data['payment_method']['code'])) {
            $code_type = $this->session->data['payment_method']['code_type'];
            $code = $this->session->data['payment_method']['code']; // nome do controller

            $this->data['paymentRoute'] = "$code/pay_$code_type";
            $this->data['paymentName'] = $code;
        }
    }

    public function credit_card()
    {
        $order_info = $this->dmodel_checkout_order->getOrder($this->session->data['order_id']);
        $this->load->helper('ftr_geral');
        $this->data['credit_cards'] = ftr_geral::getPaymentMethods($this->config->get('yapay_credit_card'), $order_info['total']);

        $setting = [
            'display_cpf' => true,
            'Type_PaymentOption' => Type_PaymentOption::Tp_CreditCard,
            'payment_name' => 'yapay',
            'load_customer_info' => true,
            'display_titular' => true,
        ];

        $this->data['payment_address'] = $this->getChild('payment/yapay_payment_address', $setting);
        $this->data['captcha_tpl'] = $this->getChild('payment/captcha');

        if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/payment/yapay/credit_card.twig')) {
            $this->template = $this->config->get('config_template') . '/template/payment/yapay/credit_card.twig';
        } else {
            $this->template = 'default/template/payment/yapay/credit_card.twig';
        }

        if ($this->ftrgeralregistry->isApp()) {
            $this->document->addScriptApp(array(
                'https://static.traycheckout.com.br/js/finger_print.js',
                'catalog/view/javascript/jquery.payment/jquery.payment.js',
                'catalog/view/theme/appmobile/js/payment.yapay_credit_card.js'
            ));
            $this->data['scriptsApp'] = json_encode($this->document->getScriptsApp());
        }

        $this->response->setOutput($this->render());

    }

    public function billet()
    {
        $setting = [
            'display_cpf' => true,
            'payment_name' => 'yapay',
            'load_customer_info' => true,
          'display_titular' => false,
        ];

        $this->data['payment_address'] = $this->getChild('payment/payment_address', $setting);
        $this->data['captcha_tpl'] =  $this->getChild('payment/captcha');

        if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/payment/yapay/billet.twig')) {
            $this->template = $this->config->get('config_template') . '/template/payment/yapay/billet.twig';
        } else {
            $this->template = 'default/template/payment/yapay/billet.twig';
        }

        if ($this->ftrgeralregistry->isApp()) {
            $this->document->addScriptApp(array(
                'catalog/view/theme/appmobile/js/payment.yapay_billet.js'
            ));
            $this->data['scriptsApp'] = json_encode($this->document->getScriptsApp());
        }

        $this->response->setOutput($this->render());

    }

    public function bank_transfer()
    {

        $yapay_bank_transfer = $this->config->get('yapay_bank_transfer');

        foreach ($yapay_bank_transfer as $key => $bank_transfer) {
            $this->data['payment_method_id'] = $key;
        }

        $setting = [
            'display_cpf' => true,
            'payment_name' => 'yapay',
            'display_titular' => false,
        ];

        $this->data['payment_address'] = $this->getChild('payment/yapay_payment_address', $setting);

        if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/payment/yapay/bank_transfer.twig')) {
            $this->template = $this->config->get('config_template') . '/template/payment/yapay/bank_transfer.twig';
        } else {
            $this->template = 'default/template/payment/yapay/bank_transfer.twig';
        }


        if ($this->ftrgeralregistry->isApp()) {
            $this->document->addScriptApp(array(
                'https://static.traycheckout.com.br/js/finger_print.js',
                'catalog/view/theme/appmobile/js/payment.yapay_bank_transfer.js'
            ));
            $this->data['scriptsApp'] = json_encode($this->document->getScriptsApp());
        }


        $this->response->setOutput($this->render());
    }

    public function parcelamento($module = 'yapay', $html = true, $flag_params = array())
    {
        if ($this->config->get('yapay_config_parcelamento') == Type_ConfigParcelamento::PorBandeira) {
            $json = array();
            $this->load->helper('ftr_geral');

            if (isset($this->request->get['bandeira'])) {
                $bandeira = Type_FormPgtoYapayCartao::getConstFromNickValue($this->request->get['bandeira']);
            } else if ($flag_params['bandeira'] != '') {
                $bandeira = Type_FormPgtoYapayCartao::getConstFromNickValue($flag_params['bandeira']);
            } else {
                $json['bandeira'] = 'Não foi possivel fazer o cálculo da parcela pois nenhuma bandeira foi encontrada!';
            }
            $credit_cards = $this->config->get('yapay_credit_card');

            $flag_params['juros'] = ftr_geral::isIsset($this->config->get('yapay_porcentagem_juros')) ? $this->config->get('yapay_porcentagem_juros') : 0;
            $flag_params['parcela_sem_juros'] = (isset($credit_cards[$bandeira]['parcela_juros']) && ($credit_cards[$bandeira]['parcela_juros'] != '')) ? $credit_cards[$bandeira]['parcela_juros'] : 0;
            $flag_params['parcela_maxima_qtd'] = (isset($credit_cards[$bandeira]['total_parcela']) && ($credit_cards[$bandeira]['total_parcela'] != '')) ? $credit_cards[$bandeira]['total_parcela'] : Type_YapayConfigs::Tp_MaximoParcela;
            $flag_params['parcela_minima_val'] = $this->config->get('yapay_parcela_minima');
        }
        return parent::parcelamento($module, $html, $flag_params);
    }

    public function pay_credit_card()
    {

        $this->load->helper('Ftr_sql');
        $this->language->load('payment/yapay');

        $json['error'] = $this->validate();

        if (!$json['error']) {

            try {

                $this->saveRequiedCustomerInfos();

                //validação feita somente para cartão de credito
                if (isset($this->request->post['creditcard_cctype'])) {

                    $payment_method_id = Type_FormPgtoYapayCartao::getConstFromNickValue($this->request->post['creditcard_cctype']);
                    $yapay_credit_card = $this->config->get('yapay_credit_card');

                    if (isset($yapay_credit_card[$payment_method_id])) {

                        if (($this->config->get('yapay_config_parcelamento') == Type_ConfigParcelamento::PorBandeira) && ($this->request->post['qtd_parcela'] > $yapay_credit_card[$payment_method_id]['total_parcela'])) {
                            throw new exception('Quantidade de parcela não suportada para a bandeira' . $this->request->post['creditcard_cctype']);
                        }

                        $parcelas = $this->parcelamento(Type_CreditCardModule::getNickFromConstValue(Type_CreditCardModule::Yapay), false, array("bandeira" => $this->request->post['creditcard_cctype']));

                        if (!in_array($this->request->post['qtd_parcela'], array_keys($parcelas))) {
                            throw new exception('Quantidade de parcela não suportada para a bandeira' . $this->request->post['creditcard_cctype']);
                        }

                    } else {
                        throw new exception('Bandeira ' . $this->request->post['creditcard_cctype'] . ' não habilitado para Yapay.');
                    }

                } else {
                    throw new exception('Bandeira não encontrada.');
                }

                $order_info = parent::getOrder();

                //calcula o juros das parcelas
                $juros_parcela = 0;
                $desconto_parcela = 0;
                if (isset($parcelas[$this->request->post['qtd_parcela']])) {
                    $total_parcelas = $parcelas[$this->request->post['qtd_parcela']]['valor_parcela'] * $this->request->post['qtd_parcela'];
                    if ($total_parcelas > $order_info['total']) {
                        $juros_parcela = number_format($total_parcelas - $order_info['total'], 2, '.', '');
                    } else if ($total_parcelas < $order_info['total']) {
                        $desconto_parcela = $order_info['total'] - $total_parcelas;
                    }
                }

                if (parent::setOrderIncrease($this->order_info['order_id']) || $juros_parcela) {
                    $juros_total = $juros_parcela + parent::getOrderIncreaseValue();
                    $this->paymentInfo->setParam('price_additional', $juros_total);
                }

                if (parent::setOrderDiscount($this->order_info['order_id']) || $desconto_parcela) {
                    $desconto_total = $desconto_parcela + parent::getOrderDiscountValue();
                    $this->paymentInfo->setParam('price_discount', $desconto_total);
                }

                if (isset($this->request->post['cpf'])) {
                    $this->paymentInfo->setParam('cpf', $this->request->post['cpf']);
                }

                //seta a opção escolhida pelo usuario
                $this->paymentInfo->setParam('payment_method_id', $payment_method_id);
                //seta as opções de pagamentos disponiveis
                $this->paymentInfo->setParam('available_payment_methods', implode(',', Type_FormPgtoYapayCartao::getEnumListConst()));

                $paymentData = parent::getTransactionInfo();
                parent::setPaymentCreditCard();

                if (isset($this->request->post['finger_print'])) {
                    $paymentData['finger_print'] = $this->request->post['finger_print'];
                }

                $paymentData['customer']['addresses'][] = array(
                    'type_address' => Type_FormPgtoYapayAddress::Tp_Cobranca,
                    'postal_code' => $this->paymentInfo->getPaymentAddress()->getPostcode(),
                    'street' => $this->paymentInfo->getPaymentAddress()->getRua(),
                    'number' => $this->paymentInfo->getPaymentAddress()->getNumero(),
                    'completion' => $this->paymentInfo->getPaymentAddress()->getComplemento(),
                    'neighborhood' => $this->paymentInfo->getPaymentAddress()->getBairro(),
                    'city' => $this->paymentInfo->getPaymentAddress()->getCidade(),
                    'state' => $this->paymentInfo->getPaymentAddress()->getUf()
                );

                $paymentData['payment'] = array_merge($paymentData['payment'], array(
                    'card_name' => $this->paymentInfo->getCreditCard()->getNome(),
                    'card_number' => $this->paymentInfo->getCreditCard()->getNumero(),
                    'card_expdate_month' => $this->paymentInfo->getCreditCard()->getDataExp()->mes,
                    'card_expdate_year' => $this->paymentInfo->getCreditCard()->getDataExp()->ano,
                    'card_cvv' => $this->paymentInfo->getCreditCard()->getCodigo(),
                    'split' => $this->paymentInfo->getCreditCard()->getParcelas()
                ));

                $result = $this->yapay->sendPayment($paymentData, $order_info['order_id']);

                $this->load->model('payment/yapay');
                $this->model_payment_yapay->setStatusOrder($order_info['order_id'], $result->transaction->status_id);

                $sqlUpdParam = Ftr_sql::generateUpdate('oc_order', ['codigo_integracao_pagamento'], 'order_id = ' . $order_info['order_id']);
                $this->db->executeSql($sqlUpdParam, [$result->transaction->token_transaction]);

                $data = new DateTime($this->db->dataAtual(), new DateTimeZone('America/Sao_Paulo'));
                $creditcard_ccno = str_replace(' ', '', $this->request->post['creditcard_ccno']);

                $paymentinfo = array();
                $paymentinfo['tid'] = $result->transaction->payment->tid;
                $paymentinfo['numero_autorizacao'] = $result->transaction->order_number;
                $paymentinfo['cod_autorizacao'] = $result->transaction->transaction_id;
                $paymentinfo['mensagem_retorno'] = null;
                $paymentinfo['order_id'] = $order_info['order_id'];
                $paymentinfo['valor_pagamento'] = $result->transaction->payment->price_original;
                $paymentinfo['data_pagamento'] = $data->format("Y-m-d H:i:s");
                $paymentinfo['tipo_cartao'] = Type_Card::Tp_Credito;
                $paymentinfo['cartao_mascara'] = ftr_geral::MaskCard(strlen($creditcard_ccno), substr($creditcard_ccno, 0, 6), substr($creditcard_ccno, 12, strlen($creditcard_ccno)));
                $paymentinfo['cartao_bandeira'] = Type_FormPgtoYapayCartao::getConstFromNickValue(strtolower($this->request->post['creditcard_cctype']));
                $paymentinfo['cartao_bandeira_text'] = ucfirst($this->request->post['creditcard_cctype']);
                $paymentinfo['qtd_parcela'] = $result->transaction->payment->split;
                $paymentinfo['valor_acrescimo'] = (isset($juros_parcela) && ($juros_parcela > 0)) ? $juros_parcela : null;

                $this->load->dmodel('payment/payment_info');
                $this->dmodel_payment_payment_info->addPaymentCreditCard($paymentinfo);

                if ($juros_parcela) {
                    $valorPedido = $order_info['total'] + $juros_parcela;
                    $this->dmodel_checkout_order->InsertOrderTotal($this->session->data['order_id'], array(
                        'module_code' => 'yapay_acrescimo',
                        'module_title' => 'Acréscimo Yapay (' . $parcelas[$this->request->post['qtd_parcela']]['percentual_calculo'] . '% de juros ao mês no parcelamento)',
                        'value' => $juros_parcela,
                        'order' => '2'
                    ));
                    $this->dmodel_checkout_order->updateTotalOrder($this->session->data['order_id'], $valorPedido);
                    $this->dmodel_checkout_order->updateApportionment($this->session->data['order_id'], $juros_parcela, Type_Apportionment::Increase);
                }
                if ($desconto_parcela) {
                    $valorPedido = $order_info['total'] - $desconto_parcela;
                    $this->dmodel_checkout_order->InsertOrderTotal($this->session->data['order_id'], array(
                        'module_code' => 'yapay_desconto',
                        'module_title' => 'Desconto Yapay (' . $parcelas[$this->request->post['qtd_parcela']]['percentual_calculo'] . '% de desconto)',
                        'value' => $desconto_parcela * -1,
                        'order' => '2'
                    ));
                    $this->dmodel_checkout_order->updateTotalOrder($this->session->data['order_id'], $valorPedido);
                    $this->dmodel_checkout_order->updateApportionment($this->session->data['order_id'], $desconto_parcela, Type_Apportionment::Discount);
                }

            } catch (Exception $e) {
                $this->dmodel_checkout_order->update($this->session->data['order_id'], $this->config->get('yapay_order_status_canceled'), '');
            }

            $json['redirect'] = $this->url->link('checkout/success');

        }

        $this->response->setOutputJson($json);

    }

    public function pay_billet()
    {
        $this->load->helper('Ftr_sql');
        $this->load->controller('payment/payment_address');
        $controllerPaymentPaymentAddress = new ControllerPaymentPaymentAddress($this->registry);
        $json['error'] = $controllerPaymentPaymentAddress->validate();

        if (!$json['error']) {
            try {
                $order_info = parent::getOrder();

                //seta as opções de pagamentos disponiveis
                $this->paymentInfo->setParam('available_payment_methods', Type_FormPgtoYapayBoleto::Tp_Boleto);
                $this->paymentInfo->setParam('payment_method_id', Type_FormPgtoYapayBoleto::Tp_Boleto);

                if (isset($this->request->post['cpf'])) {
                    $this->paymentInfo->setParam('cpf', $this->request->post['cpf']);
                }

                if (parent::setOrderIncrease($order_info['order_id'])) {
                    $this->paymentInfo->setParam('price_additional', number_format(parent::getOrderIncreaseValue(), 2, '.', ''));
                }

                if (parent::setOrderDiscount($order_info['order_id'])) {
                    $this->paymentInfo->setParam('price_discount', number_format(parent::getOrderDiscountValue(), 2, '.', ''));
                }

                $paymentData = parent::getTransactionInfo();

                $yapay_billet = $this->config->get('yapay_billet');

                array_walk($yapay_billet, function ($array) use (&$paymentData) {
                    if (isset($array['validade']) && (!empty($array['validade']))) {
                        $date = new DateTime('+' . $array['validade'] . ' day');
                        $paymentData['payment']['billet_date_expiration'] = $date->format('d/m/Y');
                    }
                });

                $result = $this->yapay->sendPayment($paymentData, $order_info['order_id']);

                $json['boleto'] = $result->transaction->payment->url_payment;

                $this->load->model('payment/yapay');
                $this->model_payment_yapay->setStatusOrder($order_info['order_id'], $result->transaction->status_id);

                $sqlUpdParam = Ftr_sql::generateUpdate('oc_order', ['codigo_integracao_pagamento'], 'order_id = ' . $order_info['order_id']);
                $this->db->executeSql($sqlUpdParam, [$result->transaction->token_transaction]);

                $paymentInfo = array();
                $paymentInfo['numero_autorizacao'] = $result->transaction->order_number;
                $paymentInfo['cod_autorizacao'] = $result->transaction->transaction_id;
                $paymentInfo['link_boleto'] = $result->transaction->payment->url_payment;
                $paymentInfo['link_digitavel'] = $result->transaction->payment->linha_digitavel;
                $paymentInfo['order_id'] = $order_info['order_id'];

                $this->load->dmodel('payment/payment_info');
                $this->dmodel_payment_payment_info->addPaymentBillit($paymentInfo);

            } catch (Exception $e) {
                $this->dmodel_checkout_order->update($this->session->data['order_id'], $this->config->get('yapay_order_status_canceled'), '');
            }

            $json['redirect'] = $this->url->link('checkout/success');
        }

        $this->response->setOutputJson($json);

    }

    public function pay_bank_transfer()
    {

        $this->load->helper('Ftr_sql');
        $this->load->controller('payment/payment_address');
        $controllerPaymentPaymentAddress = new ControllerPaymentPaymentAddress($this->registry);
        $json['error'] = $controllerPaymentPaymentAddress->validate();

        if (!$json['error']) {

            try {
                $order_info = parent::getOrder();

                if (isset($this->request->post['payment_method_id'])) {
                    $payment_method_id = $this->request->post['payment_method_id'];
                } else {
                    throw new Exception('Modo de pagamento não encontrado');
                }

                //seta a opção escolhida pelo usuario
                $this->paymentInfo->setParam('payment_method_id', $payment_method_id);
                //seta as opções de pagamentos disponiveis
                $this->paymentInfo->setParam('available_payment_methods', $payment_method_id);

                if (isset($this->request->post['cpf'])) {
                    $this->paymentInfo->setParam('cpf', $this->request->post['cpf']);
                }

                if (parent::setOrderIncrease($order_info['order_id'])) {
                    $this->paymentInfo->setParam('price_additional', number_format(parent::getOrderIncreaseValue(), 2, '.', ''));
                }

                if (parent::setOrderDiscount($order_info['order_id'])) {
                    $this->paymentInfo->setParam('price_discount', number_format(parent::getOrderDiscountValue(), 2, '.', ''));
                }

                $paymentData = parent::getTransactionInfo();

                if (isset($this->request->post['finger_print'])) {
                    $paymentData['finger_print'] = $this->request->post['finger_print'];
                }

                $result = $this->yapay->sendPayment($paymentData, $order_info['order_id']);

                $this->load->model('payment/yapay');
                $this->model_payment_yapay->setStatusOrder($order_info['order_id'], $result->transaction->status_id);

                $sqlUpdParam = Ftr_sql::generateUpdate('oc_order', ['codigo_integracao_pagamento'], 'order_id = ' . $order_info['order_id']);
                $this->db->executeSql($sqlUpdParam, [$result->transaction->token_transaction]);

                $paymentInfo = array();
                $paymentInfo['numero_autorizacao'] = $result->transaction->order_number;
                $paymentInfo['cod_autorizacao'] = $result->transaction->transaction_id;
                $paymentInfo['link_payment'] = $result->transaction->payment->url_payment;
                $paymentInfo['order_id'] = $order_info['order_id'];

                $this->load->dmodel('payment/payment_info');
                $this->dmodel_payment_payment_info->addPaymentBankTransfer($paymentInfo);

            } catch (Exception $e) {
                $this->dmodel_checkout_order->update($this->session->data['order_id'], $this->config->get('yapay_order_status_canceled'), '');
            }

            $json['redirect'] = $this->url->link('checkout/success');

        }

        $this->response->setOutputJson($json);
    }

    public function success()
    {

        if (isset($this->session->data['payment_session']['code']) && ($this->session->data['payment_session']['code'] == Type_YapayConfigs::Tp_NameModule)) {

            $this->load->dmodel('payment/payment_info');
            $this->load->language('payment/' . $this->session->data['payment_session']['code']);

            switch ($this->session->data['payment_session']['code_type']) {
                case Type_PaymentOption::Tp_CreditCard :
                    $query = $this->db->query('SELECT pcc.tid, o.order_status_id  FROM oc_order o LEFT JOIN oc_payment_credit_card pcc ON (o.order_id = pcc.order_id) WHERE o.order_id = ' . $this->session->data['payment_session']['order_id'])->row;
                    if (isset($query['tid'])) {
                        $this->data['tid'] = $query['tid'];
                    }
                    break;
                case Type_PaymentOption::Tp_Billet:
                    $query = $this->db->query('SELECT pb.link_boleto, pb.link_digitavel, o.order_status_id  FROM oc_order o LEFT JOIN oc_payment_billet pb ON (o.order_id = pb.order_id) WHERE o.order_id = ' . $this->session->data['payment_session']['order_id'])->row;
                    if (isset($query['link_boleto'])) {
                        $this->data['link_boleto'] = $query['link_boleto'];
                    }
                    if (isset($query['link_digitavel'])) {
                        $this->data['link_digitavel'] = $query['link_digitavel'];
                    }
                    $this->data['link_order'] = $this->url->link('account/order/info', 'order_id=' . $this->session->data['payment_session']['order_id']);
                    break;
                case Type_PaymentOption::Tp_BankTransfer:
                    $query = $this->db->query('SELECT pbt.link_payment, o.order_status_id  FROM oc_order o LEFT JOIN oc_payment_bank_transfer pbt ON (o.order_id = pbt.order_id) WHERE o.order_id = ' . $this->session->data['payment_session']['order_id'])->row;
                    if (isset($query['link_payment'])) {
                        $this->data['link_payment'] = $query['link_payment'];
                    }
                    break;
            }

            $this->load->dmodel('checkout/order');
            $status_info = $this->dmodel_checkout_order->getOrderStatus($query['order_status_id']);
            $this->data['status_descricao'] = $status_info['descricao'];
            if ($status_info['order_status_id'] == $this->config->get('yapay_order_status_canceled')) {
                $this->session->data['orderPaymentCanceled'] = 'Pedido cancelado';
            }

            $this->template = $this->config->get('config_template') . '/template/success/' . $this->session->data['payment_session']['code_type'] . '.twig';
            $this->response->setOutput($this->render());

        } else {
            return false;
        }

    }

    public function validate()
    {
        $error = parent::validate();
        $error = $error ? $error : array();

        if (!isset($this->request->post['qtd_parcela']) || $this->request->post['qtd_parcela'] < 1) {
            $error['qtd_parcela'] = $this->language->get('error_parcelas');
        }

        if ($error) {
            return $error;
        } else {
            return false;
        }

    }

    public function callback()
    {

        if (isset($this->request->post['token_transaction'])) {

            $this->load->dmodel('payment/payment_info');
            $data = array(
                'codigo_integracao_pagamento' => $this->request->post['token_transaction']
            );

            $results = $this->dmodel_payment_payment_info->getOrderByToken($data);

            if ($results) {
                try {
                    $response = $this->yapay->getPaymentStatusByToken($results['order_id'], $this->request->post['token_transaction']);
                    $this->load->model('payment/yapay');
                    $this->model_payment_yapay->setStatusOrder($results['order_id'], $response->transaction->status_id);

                    ob_start();
                    header($_SERVER["SERVER_PROTOCOL"] . " 200 OK");
                    ob_end_flush();
                } catch (Exception $e) {
                    $logData = [
                        'event'    => 'PaymentYapay::callback',
                        'message'  => 'Erro retorno yapay',
                        'order_id' => $results['order_id'],
                        '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));
                }
            }
        }

        if (headers_sent()) {
            echo "Header Sent to Yapay";
        } else {
            echo "Header Not Sent  to Yapay";
        }

    }

}
