<?php

class TrustpayNotificationModuleFrontController extends ModuleFrontController
{
	public function initContent()
	{
		$this->display_column_left = false;
		$this->display_column_right = false;

		parent::initContent();

        $information = print_r($_GET, true);
        Configuration::updateValue('TRUSTPAY_TESTINFO', $information);
	}

    public function postProcess()
    {

    	$id_account = Tools::getValue('AccountId');
        $id_account_sys = Configuration::get('TRUSTPAY_AID');
    	$type = Tools::getValue('Type');
    	$amount = Tools::getValue('Amount');
    	$currency = Tools::getValue('Currency');
    	$result_code = Tools::getValue('ResultCode');
    	$id_payment = Tools::getValue('PaymentId'); //BW
    	$reference = Tools::getValue('Reference');
    	$bank_account = Tools::getValue('CounterAccount'); //BW
    	$bank_account_name = Tools::getValue('CounterAccountName');
    	$signature = Tools::getValue('Signature');
    	$id_payment_request = Tools::getValue('PaymentRequestId'); //CC
    	$card_mask = Tools::getValue('CardMask'); //CC
    	$card_id = Tools::getValue('CardId'); //CC
    	$card_expiration = Tools::getValue('CardExpiration'); //CC
    	$auth_number = Tools::getValue('AuthNumber'); //CC
    	$acq_res_id = Tools::getValue('AcqResId'); //CC
    	
        $order_id = Tools::getValue('orderId'); //BW

        $success_codes = array(0, 1, 2, 3, 4, 5);
        
        $secret_key = Configuration::get('TRUSTPAY_SECRET_KEY');
        
        
        if ($id_account == $id_account_sys && in_array($result_code, $success_codes)) {
            if(!empty($reference)) {
                
                // vacsina nastaveni na serveroch je 30s beh skriptu
                $maxChecks = 5;
                $cnt = 0;
                $total = 0;
                
                while($total <= 0 && $cnt < $maxChecks) {
                    sleep(7);

                    $cart = new Cart($reference);

                    $id_order = $this->module->getIdOrder($reference);
                    $orderState = $this->module->getOrderState($result_code);

                    
                    // tu dochadza k problemu, ze objednavka neexistuje a $total je 0
                    // sposobene pomalostou systemu alebo pomalou replikaciou mysql
                    // 
                    // davalo to v EUR namiesto USD - default currency
                    //$total = (float)(number_format($cart->getOrderTotal(true, 3), 2, '.', ''));
                    $total = (float)(number_format($this->module->getOrderTotalPaid($id_order), 2, '.', ''));
                    
                    $cnt++;
                }
                
                if(!$id_order) {
                    $this->module->validateOrder(
                        (int)$cart->id,
                        (int)$orderState['id_state'],
                        $total,
                        $this->module->displayName,
                        $orderState['msg'],
                        false,
                        (int)$cart->id_currency,
                        false,
                        $cart->secure_key
                    );
                    $id_order = $this->module->getIdOrder($reference);
                }
                
                $order = new Order($id_order);
                
                $data = [];
                if($card_mask) {
                    $data[] = $id_account;
                    $data[] = $amount;
                    $data[] = $currency;
                    $data[] = $reference;
                    $data[] = $type;
                    $data[] = $result_code;
                    
                    $data[] = $id_payment_request;

                    if($card_id) {
                        $data[] = $card_id;
                    }

                    if($card_mask) {
                        $data[] = $card_mask;
                    }

                    if($card_expiration) {
                        $data[] = $card_expiration;
                    }

                    if($auth_number) {
                        $data[] = $auth_number;
                    }
                }
                else {
                    $data[] = $id_account;
                    $data[] = $amount;
                    $data[] = $currency;
                    $data[] = $type;
                    $data[] = $result_code;
                    
                    if($bank_account) {
                        $data[] = $bank_account;
                    }

                    if($bank_account_name) {
                        $data[] = $bank_account_name;
                    }

                    if($order_id) {
                        $data[] = $order_id;
                    }

                    $data[] = $id_payment;
                    
                    $data[] = $reference;
                }
                $calculatedSignature = $this->getSignature($secret_key, implode('/', $data));
                
                if($signature != $calculatedSignature) {
                    // wrong signature
                    if (version_compare(_PS_VERSION_, '1.7', '>=') === true) {
                        return $this->setTemplate('module:trustpay/views/templates/front/notification.tpl');
                    } else {
                        return $this->setTemplate('notification.tpl');
                    }
                }

                if ($amount == $total) {
                    if($orderState['id_state'] != $order->current_state) {
                        $history = new OrderHistory();
                        $history->id_order = (int)($id_order);
                        $history->changeIdOrderState((int)$orderState['id_state'], $history->id_order);
                        $history->addWithemail();
                    }

                    if (!empty($bank_account) & !empty($id_order)) {

                        $message = $this->module->l('TRUSTPAY PAYMENT INFO', 'notification').':<br>'; 
                        $message .= $this->module->l('Bank account', 'notification').': '.$bank_account.'<br>'; 
                        $message .= $this->module->l('Bank account owner', 'notification').': '.$bank_account_name.'<br>'; 
                        $message .= $this->module->l('Payment ID', 'notification').': '.$id_payment.'<br>';
                        $this->addOrderMessage($id_order, $message);
                    }

                    if (!empty($card_mask) & !empty($id_order)) {
                        $message = $this->module->l('TRUSTPAY PAYMENT INFO', 'notification').':<br>'; 
                        $message .= $this->module->l('Last 4 digits', 'notification').': '.$card_mask.'<br>'; 
                        $message .= $this->module->l('Card expiration', 'notification').': '.$card_expiration.'<br>'; 
                        $message .= $this->module->l('Auth ID', 'notification').': '.$auth_number.'<br>';
                        $message .= $this->module->l('Payment request ID', 'notification').': '.$id_payment_request.'<br>';
                        $this->addOrderMessage($id_order, $message);
                    }
                } else {
                    $history = new OrderHistory();
                    $history->id_order = (int)($id_order);
                    $history->changeIdOrderState((int)Configuration::get('TRUSTPAY_STATUS_FAIL'), $history->id_order);
                    $history->addWithemail();
                }

                if ($amount > $total) {
                    $message = $this->module->l('TRUSTPAY PAYMENT INFO', 'notification').':<br>'; 
                    $message .= $this->module->l('Received payment is more than total order value', 'notification').'<br>';
                    $message .= $this->module->l('Payment', 'notification').': '.$amount.' '.$currency.'<br>';
                    $message .= $this->module->l('Order value', 'notification').': '.$total.' '.$currency.'<br>';
                    $this->addOrderMessage($id_order, $message);
                }
                else if ($amount < $total) {
                    
                    $message = $this->module->l('TRUSTPAY PAYMENT ERROR INFO', 'notification').':<br>'; 
                    $message .= $this->module->l('Received payment is less than total order value', 'notification').'<br>';
                    $message .= $this->module->l('Payment', 'notification').': '.$amount.' '.$currency.'<br>';
                    $message .= $this->module->l('Order value', 'notification').': '.$total.' '.$currency.'<br>';
                    $this->addOrderMessage($id_order, $message);
                }
            }
        }

        if (version_compare(_PS_VERSION_, '1.7', '>=') === true) {
            return $this->setTemplate('module:trustpay/views/templates/front/notification.tpl');
        } else {
            return $this->setTemplate('notification.tpl');
        }
    }

    public function addOrderMessage($id_order, $message)
    {

        $msg = new Message();
        $message = str_replace("<br>", "\n", $message);
        $order = new Order($id_order);
        $customer = new Customer($order->id_customer);


        if (version_compare(_PS_VERSION_, '1.7', '>=') === true) {

            $customer_thread = new CustomerThread();
            $customer_thread->id_contact = 0;
            $customer_thread->id_customer = (int) $order->id_customer;
            $customer_thread->id_shop = (int) $this->context->shop->id;
            $customer_thread->id_order = (int) $order->id;
            $customer_thread->id_lang = (int) $this->context->language->id;
            $customer_thread->email = $this->context->customer->email;
            $customer_thread->status = 'closed';
            $customer_thread->token = Tools::passwdGen(12);
            $customer_thread->add();

            $customer_message = new CustomerMessage();
            $customer_message->id_customer_thread = $customer_thread->id;
            $customer_message->id_employee = 0;
            $customer_message->message = $message;
            $customer_message->private = 1;
            $customer_message->add();
        } else {
            $msg->message = $message;
            $msg->id_order = (int)$id_order;
            $msg->private = 1;

            return $msg->add();
        }
    }
    
        
    protected function getSignature($key, $message)
    {
        $signature = '';

        if (function_exists('hash_hmac')) {
            $signature = strtoupper(hash_hmac('sha256', pack('A*', $message), pack('A*', $key)));
        } else {
            $this->_postErrors[] = $this->l($this->displayName.': Function hash_hmac doesn\'t exist on your server. Contact your webhosting provider.');
        }
          
        return $signature;
    }
}
