<?php

use MercadoPago\Preference;
use MercadoPago\Payment;
use MercadoPago\MerchantOrder;


class ControllerPaymentMercadopago2 extends Controller
{

    private $error;
    public $sucess = true;
    private $order_info;
    private $message;

    protected function index()
    {

        $this->data['button_confirm'] = $this->language->get('button_confirm');
        $this->data['button_back'] = $this->language->get('button_back');

        if ($this->config->get('mercadopago2_country')) {
            $this->data['action'] = $this->config->get('mercadopago2_country');
        }

        $this->app();

        $language = $this->language->load('payment/mercadopago2');
        $this->data = array_merge($this->data, $language);

        $this->render('payment/mercadopago2');

    }

    public function app()
    {
        $this->document->addScriptApp(array(
            'catalog/view/theme/appmobile/js/payment.mercadopago2.js'
        ));
        $this->data['scriptsApp'] = json_encode($this->document->getScriptsApp());
    }

    public function confirm()
    {

        $this->load->dmodel('checkout/order');

        $order_info = $this->dmodel_checkout_order->getOrder($this->session->data['order_id']);

        $this->dmodel_checkout_order->confirm($this->session->data['order_id'], $this->config->get('mercadopago2_order_status_id'));

        $client_id = $this->config->get('mercadopago2_client_id');
        $client_secret = $this->config->get('mercadopago2_client_secret');
        MercadoPago\SDK::setClientId($client_id);
        MercadoPago\SDK::setClientSecret($client_secret);

        $preference = new Preference();

        $this->id = 'payment';
        $this->data['server'] = $_SERVER;
        $this->data['debug'] = $this->config->get('mercadopago2_debug');
        $url = $this->config->get('mercadopago2_url');

        $shipments = new MercadoPago\Shipments();
        $shipments->receiver_address = array(
            "floor" => "-",
            "zip_code" => $order_info['shipping_postcode'],
            "street_name" => $order_info['shipping_address_1'] . " - " . $order_info['shipping_address_2'] . " - " . $order_info['shipping_city'] . " - " . $order_info['shipping_zone'] . " - " . $order_info['shipping_country'],
            "apartment" => "-",
            "street_number" => "-"
        );

        //Force format YYYY-DD-MMTH:i:s
        $cust = $this->db->query("SELECT * FROM `" . DB_PREFIX . "customer` WHERE customer_id = " . $order_info['customer_id'] . " ");
        $date_created = "";
        $date_creation_user = "";

        if ($cust->num_rows > 0):

            foreach ($cust->rows as $customer):
                $date_created = $customer['date_added'];
            endforeach;

            $date_creation_user = date('Y-m-d', strtotime($date_created)) . "T" . date('H:i:s', strtotime($date_created));
        endif;

        if ($this->config->get('mercadopago2_sandbox') && $this->config->get('mercadopago2_sandbox') == Type_Status::Tp_Habilitado) {
            $email = $this->config->get('mercadopago2_user_email');
        } else {
            $email = $order_info['email'];
        }


        $payer = new MercadoPago\Payer();
        $payer->name = $order_info['payment_firstname'];
        $payer->surname = $order_info['payment_lastname'];
        $payer->email = $email;
        $payer->date_created = $date_creation_user;
        $payer->phone = array(
            "area_code" => "",
            "number" => $order_info['telephone']
        );

        $payer->address = array(
            "zip_code" => $order_info['payment_postcode'],
            "street_name" => $order_info['payment_address_1'] . " - " . $order_info['payment_address_2'] . " - " . $order_info['payment_city'] . " - " . $order_info['payment_zone'] . " - " . $order_info['payment_country'],
            "street_number" => $order_info['payment_numero']
        );

        if (!empty($order_info['cpf'])) {
            $payer->identification = array(
                "type" => "CPF",
                "number" => $order_info['cpf']
            );
        } else {
            $payer->identification = array(
                "type" => "CNPJ",
                "number" => $order_info['cnpj']
            );
        }

        $allproducts = $this->cart->getProducts();
        $firstproduct = reset($allproducts);
        $totalprice = $order_info['total'];

        $item = new MercadoPago\Item();
        $item->id = $firstproduct['product_id'];
        $item->title = $firstproduct['name'];
        $item->quantity = 1;
        $item->currency_id = "BRL";
        $item->unit_price = round($totalprice, 2);
        $item->picture_url = $this->url->link('', '', 'SSL', false) . 'image/' . $firstproduct['image'];
        $item->description = $firstproduct['quantity'] . ' x ' . $firstproduct['name'];
        $item->category_id = $this->config->get('mercadopago2_category_id');

        //excludes_payment_methods
        $exclude = $this->config->get('mercadopago2_methods');

        $excludemethods = array();

        $country_id = Type_CountryMercadoPago::getNickFromValue(Type_CountryMercadoPago::Tp_Brasil);
        $urlpayment_methods = "https://api.mercadolibre.com/sites/" . $country_id . "/payment_methods";
        $methods_value = $this->config->get('mercadopago2_methods_value');
        $methods = ftr_geral::callJson($urlpayment_methods);
        foreach ($methods as $method) {
            if (($method['id'] != 'account_money') &&
                (isset($methods_value[$method['id']])) &&
                ($methods_value[$method['id']] != '') &&
                (round($totalprice, 2) < round(str_replace(',', '.', $methods_value[$method['id']]), 2))) {
                $excludemethods[] = array('id' => $method['id']);
            }
        }

        if ($exclude != ''):
            //case exist exclude methods
            $methods_excludes = preg_split("/[\s,]+/", $exclude);
            foreach ($methods_excludes as $exclude) {
                if ($exclude != "")
                    $excludemethods[] = array('id' => $exclude);
            }

            $payment_methods = array(
                "installments" => $this->getInstallments($totalprice),
                "excluded_payment_methods" => $excludemethods
            );
        else:
            //case not exist exclude methods
            $payment_methods = array(
                "installments" => $this->getInstallments($totalprice),
                "excluded_payment_methods" => $excludemethods
            );
        endif;

        //set back url
        $back_urls = array(
            "pending" => $url . '/index.php?route=payment/mercadopago2/callback',
            "success" => $url . '/index.php?route=payment/mercadopago2/callback'
        );

        $preference->items = array($item);
        $preference->external_reference = $order_info['order_id'];
        $preference->payer = $payer;
        $preference->shipments = $shipments;
        $preference->back_urls = $back_urls;
        $preference->payment_methods = $payment_methods;
        $preference->save();

        $sandbox = $this->config->get('mercadopago2_sandbox') == 1 ? true : false;

        $json = array();

        if (!$preference->error) {
            if ($sandbox) {
                $link = $preference->sandbox_init_point;
            } else {
                $link = $preference->init_point;
            }
            $json['link'] = $link;

            if (isset($this->session->data['order_id'])) {
                $this->cart->clear();

                unset($this->session->data['shipping_method']);
                unset($this->session->data['shipping_methods']);
                unset($this->session->data['payment_method']);
                unset($this->session->data['payment_methods']);
                unset($this->session->data['guest']);
                unset($this->session->data['comment']);
                unset($this->session->data['coupon']);
                unset($this->session->data['reward']);
                unset($this->session->data['voucher']);
                unset($this->session->data['vouchers']);
            }
        } else {
            $json['error'] = "Error: " . $preference->error->message;
        }

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


    public function callback()
    {
        $this->redirect($this->url->link('checkout/success'));
    }

  public function retorno()
  {
    // No mercado pago tem 2 formas de retorno de informações o Webhooks e o IPN
    // A forma que tem a informação de topic é o IPN e a forma que tem a informação de type é o Webhook
    // IPN - função retorno webhook - função retorno 2
    // fazendo a validação das informações e direcionando para a função correta

    
    $this->load->type('tipomercadopago');
    $this->load->dmodel('checkout/order');

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

    if (isset($_GET['id']) && (isset($_GET['topic']))) {
      $client_id = $this->config->get('mercadopago2_client_id');
      $client_secret = $this->config->get('mercadopago2_client_secret');
      MercadoPago\SDK::setClientId($client_id);
      MercadoPago\SDK::setClientSecret($client_secret);

      $merchant_order = null;

      switch ($_GET["topic"]) {
        case "payment":
          $payment = MercadoPago\Payment::find_by_id($_GET["id"]);
          $merchant_order = MerchantOrder::find_by_id($payment->order->id);
          break;
        case "merchant_order":
          $merchant_order = MerchantOrder::find_by_id($_GET["id"]);
      }

      $order_id = isset($merchant_order->external_reference) ? $merchant_order->external_reference : false;
      if ($order_id) {
        $order = $this->dmodel_checkout_order->getOrder($order_id);
      } else {
        $order = false;
      }

      if (!$order) {
        exit;//caso não encontre o pedido sai fora...
      }

      $status = Type_MpStatus::TpMpSt_Indefinido;

      $paid_amount = 0;
      foreach ($merchant_order->payments as $payment) {
        if ($payment->status == Type_MpStatus::getNickFromConstValue(Type_MpStatus::TpMpSt_Pago)) {
          $paid_amount += $payment->transaction_amount;
        }
      }

      $payment = $merchant_order->payments[sizeof($merchant_order->payments) - 1];

      if ($payment->status == Type_MpStatus::getNickFromConstValue(Type_MpStatus::TpMpSt_Pending)) {
        $status = Type_MpStatus::TpMpSt_Pending;
      }

      if ($payment->status == Type_MpStatus::getNickFromConstValue(Type_MpStatus::TpMpSt_InMediation)) {
        $status = Type_MpStatus::TpMpSt_InMediation;
      }

      if ($payment->status == Type_MpStatus::getNickFromConstValue(Type_MpStatus::TpMpSt_Rejected)) {
        $status = Type_MpStatus::TpMpSt_Rejected;
      }

      if ($payment->status == Type_MpStatus::getNickFromConstValue(Type_MpStatus::TpMpSt_inProcess)) {
        $status = Type_MpStatus::TpMpSt_inProcess;
      }

      if (($paid_amount >= $merchant_order->total_amount) && ($paid_amount > 0) && ($status == Type_MpStatus::TpMpSt_Indefinido)) {
        $status = Type_MpStatus::TpMpSt_Pago;
      }

      if ((!empty($merchant_order->refunded_amount)) && ($merchant_order->refunded_amount > 0)) {
        $status = Type_MpStatus::TpMpSt_Refounded;
      }

      if ($merchant_order->cancelled) {
        $status = Type_MpStatus::TpMpSt_Cancelled;
      }

      if ($order['order_status_id'] == '0') {
        $this->dmodel_checkout_order->confirm($order_id, $this->config->get('mercadopago2_order_status_id'));
      }

      $status_to_update = null;
      switch ($status) {
        case Type_MpStatus::TpMpSt_Pago:
          $status_to_update = $this->config->get('mercadopago2_order_status_id_completed');
          break;
        case Type_MpStatus::TpMpSt_Pending:
        case Type_MpStatus::TpMpSt_Indefinido:
          $status_to_update = $this->config->get('mercadopago2_order_status_id_pending');
          break;
        case Type_MpStatus::TpMpSt_inProcess:
          $status_to_update = $this->config->get('mercadopago2_order_status_id_process');
          break;
        case Type_MpStatus::TpMpSt_Rejected:
          $status_to_update = $this->config->get('mercadopago2_order_status_id_rejected');
          break;
        case Type_MpStatus::TpMpSt_Refounded:
          $status_to_update = $this->config->get('mercadopago2_order_status_id_refunded');
          break;
        case Type_MpStatus::TpMpSt_Cancelled:
          $status_to_update = $this->config->get('mercadopago2_order_status_id_cancelled');
          break;
        case Type_MpStatus::TpMpSt_InMediation:
          $status_to_update = $this->config->get('mercadopago2_order_status_id_in_mediation');
          break;
      }

      if ($status_to_update){
        $this->dmodel_checkout_order->update($order_id, $status_to_update, "", true);
      }
    }else if(isset($json->id) && (isset($json->type))){
      $this->retorno2();
    }
  }

    public function retorno2()
    {
        $this->load->type('tipomercadopago');
        $this->load->dmodel('checkout/order');

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

        if (isset($json->id) && (isset($json->type))) {

            $client_id = $this->config->get('mercadopago2_client_id');
            $client_secret = $this->config->get('mercadopago2_client_secret');
            MercadoPago\SDK::setClientId($client_id);
            MercadoPago\SDK::setClientSecret($client_secret);

            $merchant_order = null;

            switch ($json->type) {
              case "payment":
                $payment = MercadoPago\Payment::find_by_id($json->data->id);
                $merchant_order = MerchantOrder::find_by_id($payment->order->id);
                break;
              case "plan" :
                $plan = MercadoPago\Plan::find_by_id($json->data->id);
                break;
              case "subscription":
                $plan = MercadoPago\Subscription::find_by_id($json->data->id);
                break;
              case "invoice":
                $plan = MercadoPago\Invoice::find_by_id($json->data->id);
                break;
              case "merchant_order":
                $merchant_order = MerchantOrder::find_by_id($json->data->id);
                break;
              case "point_integration_wh":
                // $_POST contém as informações relacionadas à notificação.
                break;
            }

            $order_id = isset($merchant_order->external_reference) ? $merchant_order->external_reference : false;
            if ($order_id) {
                $order = $this->dmodel_checkout_order->getOrder($order_id);
            } else {
                $order = false;
            }

            if (!$order) {
                exit;//caso não encontre o pedido sai fora...
            }

            $status = Type_MpStatus::TpMpSt_Indefinido;

            $paid_amount = 0;
            foreach ($merchant_order->payments as $payment) {
                if ($payment->status == Type_MpStatus::getNickFromConstValue(Type_MpStatus::TpMpSt_Pago)) {
                    $paid_amount += $payment->transaction_amount;
                }
            }

            $payment = $merchant_order->payments[sizeof($merchant_order->payments) - 1];

            if ($payment->status == Type_MpStatus::getNickFromConstValue(Type_MpStatus::TpMpSt_Pending)) {
                $status = Type_MpStatus::TpMpSt_Pending;
            }

            if ($payment->status == Type_MpStatus::getNickFromConstValue(Type_MpStatus::TpMpSt_InMediation)) {
                $status = Type_MpStatus::TpMpSt_InMediation;
            }

            if ($payment->status == Type_MpStatus::getNickFromConstValue(Type_MpStatus::TpMpSt_Rejected)) {
                $status = Type_MpStatus::TpMpSt_Rejected;
            }

            if ($payment->status == Type_MpStatus::getNickFromConstValue(Type_MpStatus::TpMpSt_inProcess)) {
                $status = Type_MpStatus::TpMpSt_inProcess;
            }

            if (($paid_amount >= $merchant_order->total_amount) && ($paid_amount > 0) && ($status == Type_MpStatus::TpMpSt_Indefinido)) {
                $status = Type_MpStatus::TpMpSt_Pago;
            }

            if ((!empty($merchant_order->refunded_amount)) && ($merchant_order->refunded_amount > 0)) {
                $status = Type_MpStatus::TpMpSt_Refounded;
            }

            if ($merchant_order->cancelled) {
                $status = Type_MpStatus::TpMpSt_Cancelled;
            }

            if ($order['order_status_id'] == '0') {
                $this->dmodel_checkout_order->confirm($order_id, $this->config->get('mercadopago2_order_status_id'));
            }

            $status_to_update = null;
            switch ($status) {
                case Type_MpStatus::TpMpSt_Pago:
                    $status_to_update = $this->config->get('mercadopago2_order_status_id_completed');
                    break;
                case Type_MpStatus::TpMpSt_Pending:
                case Type_MpStatus::TpMpSt_Indefinido:
                    $status_to_update = $this->config->get('mercadopago2_order_status_id_pending');
                    break;
                case Type_MpStatus::TpMpSt_inProcess:
                    $status_to_update = $this->config->get('mercadopago2_order_status_id_process');
                    break;
                case Type_MpStatus::TpMpSt_Rejected:
                    $status_to_update = $this->config->get('mercadopago2_order_status_id_rejected');
                    break;
                case Type_MpStatus::TpMpSt_Refounded:
                    $status_to_update = $this->config->get('mercadopago2_order_status_id_refunded');
                    break;
                case Type_MpStatus::TpMpSt_Cancelled:
                    $status_to_update = $this->config->get('mercadopago2_order_status_id_cancelled');
                    break;
                case Type_MpStatus::TpMpSt_InMediation:
                    $status_to_update = $this->config->get('mercadopago2_order_status_id_in_mediation');
                    break;
            }

            if ($status_to_update){
                $this->dmodel_checkout_order->update($order_id, $status_to_update, "", true);
            }
        }else{
          ob_start();
          header($_SERVER["SERVER_PROTOCOL"] . " 401 error");
          ob_end_flush();
        }

    }

    protected function getInstallments($totalprice)
    {

        $qtd_parcelas = (int)$this->config->get('mercadopago2_installments');
        $parcela_minima = $this->config->get('mercadopago2_parcela_minima');

        if ($parcela_minima) {
            $parcela = 0;
            for ($p = 1; $p <= $qtd_parcelas; $p++) {
                if (($totalprice / $p) >= $parcela_minima) {
                    $parcela = $p;
                }
            }
            return $parcela;
        }

        return $qtd_parcelas;

    }


}
