<?php

/*
 ************************************************************************
 Copyright [2013] [PagSeguro Internet Ltda.]

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 ************************************************************************
 */

/**
 * Class Controller Payment PagSeguro Notification
 * Class responsible for receiving and handling of notifications sent by PagSeguro.
 */
include_once 'PagSeguroLibrary/PagSeguroLibrary.php';
class ControllerPaymentPagSeguroNotification extends Controller
{

	/**
	 * $_POST['notificationType']
	 * @var string
	 */
	private $notification_type;

	/**
	 * $_POST['notificationCode']
	 * @var string
	 */
	private $notification_code;

	/**
	 * Reference purchase
	 * @var int
	 */
	private $reference;

	/**
	 * Reference purchase
	 * @var int
	 */
	private $code;

	/**
	 * Code language active in the system
	 * @var string
	 */
	private $code_language;

	/**
	 * Status PagSeguro
	 * @var array
	 */
	private $array_order_status;

	/**
	 *Tipos De Pagamentos
	 *$var array
	 */
	private $array_paymentMethod;

	/**
	 * PagSeguroAccountCredentials
	 * @var PagSeguroAccountCredentials
	 */
	private $obj_credentials;

	/**
	 * PagSeguroNotificationType
	 * @var PagSeguroNotificationType
	 */
	private $obj_notification_type;

	/**
	 * PagSeguroNotificationService
	 * @var Transaction
	 */
	private $obj_transaction;

	/**
	 * The first method to be called by the notification PagSeguro treatment.
	 */
	public function index()
	{

		$this->_load();
		$this->_addPagSeguroLibrary();
		$this->_validatePost();
		$this->_createArrayOrderStatus();
		$this->_createArrayPaymentMethod();
		$this->_codeLanguage();
		$this->_createCredentials();
		$this->_createNotificationType();

		if ($this->obj_notification_type->getValue() == $this->notification_type ) {
			$this->_createTransaction();
			$this->_updateCms();
		}
	}

	/**
	 * Load Model PagSeguro.
	 */
	private function _load()
	{
		$this->load->type('tipopagseguro')	;
    $this->load->type('tipocomum')	;
		$this->load->model('payment/pagseguro');
		$environment = ($this->config->get('pagseguro_environment_status')) ? $this->config->get('pagseguro_environment_status') : Type_Environment::Tp_Production ;
		PagSeguroConfig::setEnvironment($environment);//seta qual ambiente estara em execução
	}

	/**
	 * Add Libary PagSeguro.
	 */
	private function _addPagSeguroLibrary()
	{
		include_once DIR_APPLICATION . 'controller/payment/PagSeguroLibrary/PagSeguroLibrary.php';
	}

	/**
	 * Verifies that post is not empty.
	 */
	private function _validatePost()
	{
		$this->notification_type = (isset($this->request->post['notificationType']) && trim($this->request->post['notificationType']) != "") ? trim($this->request->post['notificationType']) : null;
		$this->notification_code = (isset($this->request->post['notificationCode']) && trim($this->request->post['notificationCode']) != "") ? trim($this->request->post['notificationCode']) : null;
	}

	/**
	 * Retrieves list of status PagSeguro
	 */
	private function _createArrayOrderStatus()
	{
		$this->array_order_status = $this->model_payment_pagseguro->getOrderStatus();
	}

	/**
	 * Retrieves list of payment type PagSeguro
	 */
	private function _createArrayPaymentMethod()
	{
	    $this->array_paymentMethod = $this->model_payment_pagseguro->getPaymentMethod();
	}

	/**
	 * Create Credentials
	 */
	private function _createCredentials()
	{
		$this->obj_credentials = new PagSeguroAccountCredentials($this->config->get('pagseguro_email'), $this->config->get('pagseguro_token'));
	}

	/**
	 * Retrieves the language code active in the system.
	 */
	private function _codeLanguage()
	{
		$this->code_language = $this->session->data['language'];
	}

	/**
	 * Create Notification type
	 */
	private function _createNotificationType()
	{
		$this->obj_notification_type = new PagSeguroNotificationType();
		$this->obj_notification_type->setByType("TRANSACTION");
	}

	/**
	 * Create Transaction
	 */
	private function _createTransaction()
	{
		$this->obj_transaction = PagSeguroNotificationService::checkTransaction($this->obj_credentials, $this->notification_code);
		$this->reference = $this->obj_transaction->getReference();
		$this->code			 = $this->obj_transaction->getCode();
	}

	/**
	 * Updates the transaction status
	 */
	private function _updateCms()
	{
		/*para acessar as opções do retorno deve se seguir a cadeia do xml por exemplo:

			<transaction>
			.
			.
			.
			.
			<sender>
				.
				.
				.
				<email>comprador@uol.com.br</email>


		$this->obj_transaction->getSender->getEmail();
		$this->obj_transaction->getPaymentMethod()->getCode()->getValue();


		links para auxilio
		https://pagseguro.uol.com.br/v2/guia-de-integracao/api-de-notificacoes.html#!rmcl
		http://sounoob.com.br/recebendo-notificacoes-do-pagseguro-usando-php-sem-utilizar-a-biblioteca-oficial/
		*/
    $this->load->type('tipopagseguro');
    $this->load->dmodel('checkout/order');
    $statusRetorno = $this->obj_transaction->getStatus()->getValue();

    $lastStatus = $this->dmodel_checkout_order->getLastPaymentStatusHistory($this->reference);

    if(!$lastStatus || ($statusRetorno <> $lastStatus['status'])){

		switch($statusRetorno){
        case Type_OrderStatusPagseguro::Tp_Processando :
          $this->_updateOrder($this->config->get('pagseguro_processing_order_id'));
        break;
        case Type_OrderStatusPagseguro::Tp_Processado :
          $this->_updateOrder($this->config->get('pagseguro_processed_order_id'));
          $discount = $this->obj_transaction->getGrossAmount() - $this->obj_transaction->getDiscountAmount();
          if($discount != $this->obj_transaction->getGrossAmount()){
            $this->model_payment_pagseguro->updateValueOrder($this->reference, $discount);
            $payment_type = $this->array_paymentMethod[$this->obj_transaction->getPaymentMethod()->getType()->getValue()];
            $this->model_payment_pagseguro->InsertOrderDescontoPagseguro($this->reference, $this->obj_transaction->getDiscountAmount(), 'Desconto: '.$payment_type);
          }
        break;
        case Type_OrderStatusPagseguro::Tp_Completo :
          $pagseguro_complete_order_id = $this->config->get('pagseguro_complete_order_id');
          if($pagseguro_complete_order_id){
            $this->_updateOrder($this->config->get('pagseguro_complete_order_id'));
          }
        break;
        case Type_OrderStatusPagseguro::Tp_Disputa :
          $this->_updateOrder($this->config->get('pagseguro_dispute_order_id'));
        break;
        case Type_OrderStatusPagseguro::Tp_Reembolsado :
          $this->_updateOrder($this->config->get('pagseguro_refunded_order_id'));
        break;
        case Type_OrderStatusPagseguro::Tp_Cancelado :
          $this->_updateOrder($this->config->get('pagseguro_cancelado_order_id'));
        break;
        case Type_OrderStatusPagseguro::Tp_Debitado :
          $this->_updateOrder($this->config->get('pagseguro_debitado_order_id'));
        break;
        case Type_OrderStatusPagseguro::Tp_Retencao :
          $this->_updateOrder($this->config->get('pagseguro_retencao_order_id'));
        break;
      }

      $ordem = isset($lastStatus['ordem']) ? $lastStatus['ordem']+1 : 0;
      $this->dmodel_checkout_order->insertPaymentStatusHistory($this->reference,$statusRetorno,$ordem);

    }

	}

	/**
	 * Update table order and order_history
	 * @param type $id_order_status
	 */
	private function _updateOrder($id_order_status)
	{
    $this->model_payment_pagseguro->saveOrderHistory($this->reference, $id_order_status);
    $this->model_payment_pagseguro->updateOrder($this->reference, $id_order_status, $this->code);
  }
}
