<?php

/**
 * 
 * Billdesk payment Integration
 * Version: 1.0.8-5e3712e
 * VirtueMart is free software. This version may have been modified pursuant
 * to the GNU General Public License, and as distributed it includes or
 * is derivative of works licensed under the GNU General Public License or
 * other free or open source software licenses.
 */

defined('_JEXEC') or die('Restricted access');
jimport('joomla.plugin.plugin');

use Joomla\CMS\Log\Log;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Psr7\Message;
use io\billdesk\client\hmacsha256\BillDeskJWEHS256Client;
use io\billdesk\client\hmacsha256\Config;
use io\billdesk\client\hmacsha256\JWESymmetricHelper;
use io\billdesk\client\hmacsha256\JWEHS256Helper;
use Joomla\CMS\Version;

require_once __DIR__ . '/vendor/autoload.php';
require_once dirname(__FILE__) . '/logger.php';
if (!class_exists('vmPSPlugin')) {
    require(VMPATH_PLUGINLIBS . DS . 'vmpsplugin.php');
}

class plgVmPaymentBilldesk extends vmPSPlugin
{
    function __construct(&$subject, $config)
    {
        parent::__construct($subject, $config);
        $this->_loggable = TRUE;
        $this->tableFields = array_keys($this->getTableSQLFields());
        $this->_tablepkey = 'id';
        $this->_tableId = 'id';
        $varsToPush = $this->getVarsToPush();
        $this->addVarsToPushCore($varsToPush, 1);
        $this->setConfigParameterable($this->_configTableFieldName, $varsToPush);
        //$this->setConvertable(array('min_amount', 'max_amount', 'cost_per_transaction', 'cost_min_transaction'));
        //$this->setConvertDecimal(array('min_amount','max_amount','cost_per_transaction','cost_min_transaction','cost_percent_total'));
    }

    /**
     * Create the table for this plugin if it does not yet exist.
     * @deprecated
     * @author Valérie Isaksen
     *
     */
    public function getVmPluginCreateTableSQL()
    {
        vmJsApi::addJScript('bildeskadmin', '/plugins/vmpayment/billdesk/assets/js/admin.js');
        return $this->createTableSQL('Payment Billdesk Table');
    }
    /**
     * Fields to create the payment table
     *
     * @return string SQL Fileds
     */
    function getTableSQLFields()
    {

        $SQLfields = array(
            'id' => 'int(1) UNSIGNED NOT NULL AUTO_INCREMENT',
            'virtuemart_order_id' => 'int(1) UNSIGNED',
            'order_number' => ' char(64)',
            'virtuemart_paymentmethod_id' => 'mediumint(1) UNSIGNED',
            'payment_name' => 'varchar(5000)',
            'payment_order_total' => 'decimal(15,5) NOT NULL DEFAULT \'0.00000\' ',
            'payment_currency' => 'char(3)',
            'billdesk_order_id' => 'varchar(100)',
            'billdesk_transation_id' => 'varchar(100)',
            'billdesk_transation_date' => 'varchar(100)',
            'billdesk_payment_status' => 'varchar(100)',
            'billdesk_refund_transation_id' => 'varchar(100)',
        );

        return $SQLfields;
    }

    function plgVmOnProductDisplayPayment($product, &$productDisplay)
    {

        $vendorId = empty($product->virtuemart_vendor_id) ? 1 : $product->virtuemart_vendor_id;
        if ($this->getPluginMethods($vendorId) === 0) {
            return FALSE;
        }
        foreach ($this->methods as $this->_currentMethod) {
            $this->_currentMethod->payment_currency = $this->getPaymentCurrency($this->_currentMethod);
        }

        return TRUE;
    }


    static function getPaymentCurrency(&$method, $selectedUserCurrency = false)
    {

        if (empty($method->payment_currency)) {
            $vendor_model = VmModel::getModel('vendor');
            $vendor = $vendor_model->getVendor($method->virtuemart_vendor_id);
            $method->payment_currency = $vendor->vendor_currency;
            return $method->payment_currency;
        } else {

            $vendor_model = VmModel::getModel('vendor');
            $vendor_currencies = $vendor_model->getVendorAndAcceptedCurrencies($method->virtuemart_vendor_id);

            if (!$selectedUserCurrency) {
                if ($method->payment_currency == -1) {
                    $mainframe = JFactory::getApplication();
                    $selectedUserCurrency = $mainframe->getUserStateFromRequest("virtuemart_currency_id", 'virtuemart_currency_id', vRequest::getInt('virtuemart_currency_id', $vendor_currencies['vendor_currency']));
                } else {
                    $selectedUserCurrency = $method->payment_currency;
                }
            }

            $vendor_currencies['all_currencies'] = explode(',', $vendor_currencies['all_currencies']);
            if (in_array($selectedUserCurrency, $vendor_currencies['all_currencies'])) {
                $method->payment_currency = $selectedUserCurrency;
            } else {
                $method->payment_currency = $vendor_currencies['vendor_currency'];
            }

            return $method->payment_currency;
        }
    }

    /*
		 * Keep backwards compatibility
		 * a new parameter has been added in the xml file
		 */

    function plgVmOnUserPaymentCancel()
    {

        if (!class_exists('VirtueMartModelOrders'))
            require(JPATH_VM_ADMINISTRATOR . DS . 'models' . DS . 'orders.php');

        $order_number = vRequest::getVar('on');
        if (!$order_number)
            return false;
        $db = JFactory::getDBO();
        $query = 'SELECT ' . $this->_tablename . '.`virtuemart_order_id` FROM ' . $this->_tablename . " WHERE  `order_number`= '" . $order_number . "'";

        $db->setQuery($query);
        $virtuemart_order_id = $db->loadResult();

        if (!$virtuemart_order_id) {
            return null;
        }
        $this->handlePaymentUserCancel($virtuemart_order_id);

        return true;
    }
    function _getTablepkeyValue($virtuemart_order_id)
    {
        $db = JFactory::getDBO();
        $q = 'SELECT ' . $this->_tablepkey . ' FROM `' . $this->_tablename . '` '
            . 'WHERE `virtuemart_order_id` = ' . $virtuemart_order_id;
        $db->setQuery($q);

        if (!($pkey = $db->loadResult())) {
            JError::raiseWarning(500, $db->getErrorMsg());
            return '';
        }
        return $pkey;
    }

    /**
     * Display stored payment data for an order
     *
     */
    function plgVmOnShowOrderBEPayment($virtuemart_order_id, $virtuemart_payment_id)
    {

        if (!$this->selectedThisByMethodId($virtuemart_payment_id)) {
            return NULL; // Another method was selected, do nothing
        }

        if (!($paymentTable = $this->getDataByOrderId($virtuemart_order_id))) {
            return NULL;
        }
        // vmLanguage::loadJLang('com_virtuemart');

        $html = '<table class="adminlist table">' . "\n";
        $html .= $this->getHtmlHeaderBE();
        $html .= $this->getHtmlRowBE('COM_VIRTUEMART_PAYMENT_NAME', $paymentTable->payment_name);
        $html .= $this->getHtmlRowBE('BILLDESK_PAYMENT_TOTAL_CURRENCY', $paymentTable->payment_order_total . ' ' . $paymentTable->payment_currency);
       if (!empty($paymentTable->email_currency)) {
            $html .= $this->getHtmlRowBE('BILLDESK_EMAIL_CURRENCY', $paymentTable->email_currency);
        }

        $html .= '</table>' . "\n";
        return $html;
    }

    function getCosts(VirtueMartCart $cart, $method, $cart_prices)
    {
        if (preg_match('/%$/', $method->cost_percent_total)) {
            $cost_percent_total = substr($method->cost_percent_total, 0, -1);
        } else {
            $cost_percent_total = $method->cost_percent_total;
        }
        return ($method->cost_per_transaction + ($cart_prices['salesPrice'] * $cost_percent_total * 0.01));
    }

    /*
	* We must reimplement this triggers for joomla 1.7
	*/

    /**
     * Create the table for this plugin if it does not yet exist.
     * This functions checks if the called plugin is active one.
     * When yes it is calling the standard method to create the tables
     *
     * @author Valérie Isaksen
     *
     */
    function plgVmOnStoreInstallPaymentPluginTable($jplugin_id)
    {

        return $this->onStoreInstallPluginTable($jplugin_id);
    }

    /**
     * This event is fired after the payment method has been selected. It can be used to store
     * additional payment info in the cart.
     *
     * @author Max Milbers
     * @author Valérie isaksen
     *
     * @param VirtueMartCart $cart: the actual cart
     * @return null if the payment was not selected, true if the data is valid, error message if the data is not vlaid
     *
     */


    /**
     * plgVmDisplayListFEPayment
     * This event is fired to display the pluginmethods in the cart (edit shipment/payment) for exampel
     *
     * @param object  $cart Cart object
     * @param integer $selected ID of the method selected
     * @return boolean True on succes, false on failures, null when this plugin was not selected.
     * On errors, JError::raiseWarning (or JError::raiseError) must be used to set a message.
     *
     * @author Valerie Isaksen
     * @author Max Milbers
     */
    public function plgVmDisplayListFEPayment(VirtueMartCart $cart, $selected, &$htmlIn)
    {
        // $logger = BillDeskLogger::logger("DisplayListFEPayment");
        // $logger->info("Virtumart payment method Id: " . ($cart->virtuemart_order_id));
        return $this->displayListFE($cart, $selected, $htmlIn);
    }

    public function plgVmOnSelectCheckPayment(VirtueMartCart $cart, &$msg)
    {
        // $logger = BillDeskLogger::logger("SelectCheckPayment");
        // $logger->info("Inside plgVmOnSelectCheckPayment");
        return $this->OnSelectCheck($cart);
    }


    /**
     * This event is fired during the checkout process. It can be used to validate the
     * method data as entered by the user.
     *
     * @return boolean True when the data was valid, false otherwise. If the plugin is not activated, it should return null.
     * @author Max Milbers

	
     */
    public function plgVmOnCheckoutCheckDataPayment(VirtueMartCart $cart)
    {
        return true;
    }

   function plgVmConfirmedOrder($cart, $order)
{
    $logger = BillDeskLogger::logger("ConfirmedOrder");

    if (!($method = $this->getVmPluginMethod($order['details']['BT']->virtuemart_paymentmethod_id))) return null;
    if (!$this->selectedThisElement($method->payment_element)) return false;

    $res = $this->_createorder($method, $order, $order['details']['BT']->virtuemart_paymentmethod_id, $order['details']['BT']->order_number);

    if ($res['status'] == 'ACTIVE') {
        $url = JURI::root() . 'index.php?option=com_virtuemart&view=pluginresponse&task=pluginresponsereceived';
        ?>
        <!-- Load standalone jQuery first -->
        <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

        <script type="text/javascript">
        (function($){
            $(document).ready(function() {
                var flowtype = "payments";
                var flowConfig = {
                    merchantId: '<?php echo $res['mercid'] ?>',
                    bdOrderId: '<?php echo $res['bdorderid'] ?>',
                    authToken: '<?php echo $res['links'][1]['headers']['authorization'] ?>',
                    childWindow: '<?php echo $method->child_window ?>' === "true",
                    retryCount: Number('<?php echo $method->retry_count ?>')
                };

                var payment_category = '<?php echo $method->payment_category ?>'.split(",").map(i=>i.trim());
                if (payment_category[0].length > 0) flowConfig.prefs = { payment_categories: payment_category };

                var sdkConfig = {
                    responseHandler: function(response) {
                        var form = document.createElement('form');
                        form.method = 'POST';
                        form.action = '<?php echo $url ?>';

                        if(response.status === "111") {
                            var hidden = document.createElement('input');
                            hidden.type = 'hidden';
                            hidden.name = 'response_code';
                            hidden.value = response.status;
                            form.appendChild(hidden);
                        } else {
                            var hidden1 = document.createElement('input');
                            hidden1.type = 'hidden';
                            hidden1.name = 'response';
                            hidden1.value = response.txnResponse.transaction_response;
                            form.appendChild(hidden1);

                            var hidden2 = document.createElement('input');
                            hidden2.type = 'hidden';
                            hidden2.name = 'v_payment_id';
                            hidden2.value = '<?php echo $cart->virtuemart_paymentmethod_id ?>';
                            form.appendChild(hidden2);
                        }
                        document.body.appendChild(form);
                        form.submit();
                    },
                    merchantLogo: '<?php echo $method->merchant_logo ?>',
                    flowConfig: flowConfig,
                    flowType: flowtype
                };

                // Load SDK dynamically
                var sdkBase = '<?php echo $method->environment=="UAT"?"https://uat1.billdesk.com/merchant-uat/sdk/dist/billdesksdk/":"https://pay.billdesk.com/jssdk/v1/dist/billdesksdk/" ?>';
                var scriptModule = document.createElement('script');
                scriptModule.type = "module";
                scriptModule.src = sdkBase + 'billdesksdk.esm.js';
                document.body.appendChild(scriptModule);

                var scriptNoModule = document.createElement('script');
                scriptNoModule.nomodule = "";
                scriptNoModule.src = sdkBase + 'billdesksdk.js';
                document.body.appendChild(scriptNoModule);

                var link = document.createElement('link');
                link.rel = 'stylesheet';
                link.href = sdkBase + 'billdesksdk.css';
                document.head.appendChild(link);

                // Poll until SDK is ready
                var sdkInterval = setInterval(function() {
                    if(typeof loadBillDeskSdk === 'function') {
                        clearInterval(sdkInterval);
                        loadBillDeskSdk(sdkConfig);
                    }
                }, 200);
            });
        })(jQuery.noConflict(true));
        </script>
        <?php
        die();
    } else {
        vmError('System error occurred: ' . $res['message']);
        $app = JFactory::getApplication();
        $app->redirect(JRoute::_('index.php?option=com_virtuemart&view=cart', false));
    }
}


    public function _createorder($method, $order, $paymentmethod_id, $order_id)
    {
        $logger = BillDeskLogger::logger("Create Order");
        $logger->info("Inside Create Order: " . $paymentmethod_id);
        try {
            //$this->getPaymentCurrency($method);
            $env = $method->environment;
            $merchantid = $method->merchant_id;

            $encryption_key = $method->encryption_key;
            $signing_key = $method->signing_key;
            $keyid = $method->key_id;
            $clientid = $method->client_id;
            $iteamcode = $method->item_code;
            $childwindow = $method->child_window;
            $this->getPaymentCurrency($method);
            $currency_code_3 = shopFunctions::getCurrencyByID($method->payment_currency, 'currency_code_3');
            $currency_value = $currency_code_3;
            $arr = array(
                'INR' => '356', 'USD' => '840', 'EUR' => '978', 'JPY' => '392',
                'AUD' => '36', 'HKD' => '344', 'MYR' => '458', 'SGD' => '702',
                'NZD' => '554'
            );
            $currency = $arr[$currency_value];
            $totalInPaymentCurrency = vmPSPlugin::getAmountInCurrency($order['details']['BT']->order_total, $method->payment_currency);
            $total = $totalInPaymentCurrency['value'];
            if ($childwindow == "true") {
                $returnUrl = JURI::root() . 'index.php?option=com_virtuemart&view=pluginresponse&task=pluginnotification&tmpl=component'; //JURI::root() . 'index.php?option=com_virtuemart&view=pluginresponse&task=pluginresponsereceived';
            } else {
                $returnUrl = JURI::root() . 'index.php?option=com_virtuemart&view=pluginresponse&pm=' . $paymentmethod_id . '&task=pluginresponsereceived';
            }
            $ip = getenv('HTTP_CLIENT_IP') ?:
                getenv('HTTP_X_FORWARDED_FOR') ?:
                getenv('HTTP_X_FORWARDED') ?:
                getenv('HTTP_FORWARDED_FOR') ?:
                getenv('HTTP_FORWARDED') ?:
                getenv('REMOTE_ADDR');
            $ipaddress = strtok($ip, ",");
            $bd_version = "pluginv,1.0.8";
            $version = new Version;
            $joomla_version = $version::MAJOR_VERSION . '.' . $version::MINOR_VERSION . '.' . $version::PATCH_VERSION;
            $virtuemart_version =  vmVersion::$RELEASE;
            $userAgent = $_SERVER['HTTP_USER_AGENT'];

            $config = new Config();
			$config->setClientId(trim($clientid));
			$config->setMerchantId(trim($merchantid));
			$config->setEncryptionKeyBase64(trim($encryption_key));
			$config->setSigningKeyBase64(trim($signing_key));
			$config->setEncryptionKeyId(trim($keyid));
			$config->setSigningKeyId('AES_DIR');

            $endpoint = ($env === 'UAT')
				? 'https://uat1.billdesk.com/u2'
				: 'https://api.billdesk.com';

            // Initialize BillDesk Client
			$client = new BillDeskJWEHS256Client($config, $endpoint);
			$client->setLogger($logger);
            try {
                $request = array(
                    'mercid' => $merchantid,
                    'orderid' => uniqid(),
                    'amount' =>  $total,
                    'order_date' => date_format(new \DateTime(), DATE_W3C),
                    'currency' => $currency,
                    'ru' =>  $returnUrl,
                    'itemcode' => $iteamcode,
                    'device' => array(
                        'init_channel' => 'internet',
                        'ip' => $ipaddress,
                        'user_agent' => $userAgent
                    ),
                    'additional_info' => array(
                        'additional_info1' => $order_id,
                        'additional_info2' => $order['details']['BT']->order_total,
                        'additional_info3' => $currency,
                        'additional_info7' => 'platform,virtuemart_' . $virtuemart_version . '_joomla_' . $joomla_version."-".$bd_version,
                    ),
                );
                $response = $client->createOrder($request);
                $results = $response->getResponse();
                $res = json_decode(json_encode($results), true);
                $create_res = json_encode(($results), true);
                $logger->info('Create order response: ' . $create_res);
                return $res;
            } catch (RequestException $ex) {
                $logger->error("Exception on create order: " . $ex);
            }
        } catch (RequestException $ex) {
            if ($ex->hasResponse()) {
                $logger->error("server response with error: . Message::toString($ex->getResponse()");
                return true;
            }
        }
    }

    function getStateCode($virtuemart_state_id, $virtuemart_country_id)
    {
        if (!$virtuemart_state_id) {
            return '';
        }
        $country_2_code = ShopFunctions::getCountryByID($virtuemart_country_id, 'country_2_code');
        $state_3_code = ShopFunctions::getStateByID($virtuemart_state_id, 'state_3_code');
        //return $state_3_code;
        return $country_2_code . '-' . $state_3_code;
    }

    /*
* plgVmOnSelectedCalculatePricePayment
* Calculate the price (value, tax_id) of the selected method
* It is called by the calculator
* This function does NOT to be reimplemented. If not reimplemented, then the default values from this function are taken.
* @author Valerie Isaksen
* @cart: VirtueMartCart the current cart
* @cart_prices: array the new cart prices
* @return null if the method was not selected, false if the shiiping rate is not valid any more, true otherwise
*
*
*/

    public function plgVmOnSelectedCalculatePricePayment(VirtueMartCart $cart, array &$cart_prices, &$cart_prices_name)
    {

        return $this->onSelectedCalculatePrice($cart, $cart_prices, $cart_prices_name);
    }

    function plgVmgetPaymentCurrency($virtuemart_paymentmethod_id, &$paymentCurrencyId)
    {

        if (!($method = $this->getVmPluginMethod($virtuemart_paymentmethod_id))) {
            return NULL; // Another method was selected, do nothing
        }
        if (!$this->selectedThisElement($method->payment_element)) {
            return FALSE;
        }
        $this->getPaymentCurrency($method);

        $paymentCurrencyId = $method->payment_currency;
        return;
    }

    /**
     * plgVmOnCheckAutomaticSelectedPayment
     * Checks how many plugins are available. If only one, the user will not have the choice. Enter edit_xxx page
     * The plugin must check first if it is the correct type
     *
     * @author Valerie Isaksen
     * @param VirtueMartCart cart: the cart object
     * @return null if no plugin was found, 0 if more then one plugin was found,  virtuemart_xxx_id if only one plugin is found
     *
     */
    function plgVmOnCheckAutomaticSelectedPayment(VirtueMartCart $cart, array $cart_prices, &$paymentCounter)
    {
        return $this->onCheckAutomaticSelected($cart, $cart_prices, $paymentCounter);
    }

    /**
     * This method is fired when showing the order details in the frontend.
     * It displays the method-specific data.
     *
     * @param integer $order_id The order ID
     * @return mixed Null for methods that aren't active, text (HTML) otherwise
     * @author Max Milbers
     * @author Valerie Isaksen
     */
    public function plgVmOnShowOrderFEPayment($virtuemart_order_id, $virtuemart_paymentmethod_id, &$payment_name)
    {
        $this->onShowOrderFE($virtuemart_order_id, $virtuemart_paymentmethod_id, $payment_name);
    }

    /**
     * @param $orderDetails
     * @param $data
     * @return null
     */

    // function plgVmOnUserInvoice($orderDetails, &$data)
    // {

    //     if (!($method = $this->getVmPluginMethod($orderDetails['virtuemart_paymentmethod_id']))) {
    //         return NULL; // Another method was selected, do nothing
    //     }
    //     if (!$this->selectedThisElement($method->paymentorderDetails_element)) {
    //         return NULL;
    //     }
    //     //vmdebug('plgVmOnUserInvoice',$orderDetails, $method);

    //     if (!isset($method->send_invoice_on_order_null) or $method->send_invoice_on_order_null == 1 or $orderDetails['order_total'] > 0.00) {
    //         return NULL;
    //     }

    //     if ($['order_salesPrice'] == 0.00) {
    //         $data['invoice_number'] = 'reservedByPayment_' . $orderDetails['order_number']; // Nerver send the invoice via email
    //     }
    // }
    /**
     * @param $virtuemart_paymentmethod_id
     * @param $paymentCurrencyId
     * @return bool|null
     */
    function plgVmgetEmailCurrency($virtuemart_paymentmethod_id, $virtuemart_order_id, &$emailCurrencyId)
    {

        if (!($method = $this->getVmPluginMethod($virtuemart_paymentmethod_id))) {
            return NULL; // Another method was selected, do nothing
        }
        if (!$this->selectedThisElement($method->payment_element)) {
            return FALSE;
        }

        if (empty($method->email_currency)) {
        } else if ($method->email_currency == 'vendor') {
            $vendor_model = VmModel::getModel('vendor');
            $vendor = $vendor_model->getVendor($method->virtuemart_vendor_id);
            $emailCurrencyId = $vendor->vendor_currency;
        } else if ($method->email_currency == 'payment') {
            $emailCurrencyId = $this->getPaymentCurrency($method);
        }
    }

    /**
     * This method is fired when showing when priting an Order
     * It displays the the payment method-specific data.
     *
     * @param integer $_virtuemart_order_id The order ID
     * @param integer $method_id  method used for this order
     * @return mixed Null when for payment methods that were not selected, text (HTML) otherwise
     * @author Valerie Isaksen
     */
    function plgVmOnShowOrderPrintPayment($order_number, $method_id)
    {
        return $this->onShowOrderPrint($order_number, $method_id);
    }
    function plgVmDeclarePluginParamsPayment($name, $id, &$data)
    {
        return $this->declarePluginParams('payment', $name, $id, $data);
    }
    function plgVmDeclarePluginParamsPaymentVM3(&$data)
    {
        Log::add('Inside plgVmDeclarePluginParamsPaymentVM3 method', Log::INFO);
        return $this->declarePluginParams('payment', $data);
    }
    function plgVmSetOnTablePluginParamsPayment($name, $id, &$table)
    {
        return $this->setOnTablePluginParams($name, $id, $table);
    }

    //Notice: We only need to add the events, which should work for the specific plugin, when an event is doing nothing, it should not be added

    /**
     * Save updated order data to the method specific table
     *
     * @param array   $_formData Form data
     * @return mixed, True on success, false on failures (the rest of the save-process will be
     * skipped!), or null when this method is not actived.
     *
     */

    public function plgVmOnUpdateOrderPayment(&$order, $old_order_statusa)
    {
        $logger = BillDeskLogger::logger("Refund Order Process ");
        $logger->info("Inside refund function: $order->virtuemart_paymentmethod_id");

        if (!($method = $this->getVmPluginMethod($order->virtuemart_paymentmethod_id))) {
            return null; // Another method was selected, do nothing
        }
        if (!$this->selectedThisElement($method->payment_element)) {
            return false;
        }

        if (!($payments = $this->getDatasByOrderId($order->virtuemart_order_id))) {
            return null;
        }
        //Load only when updating status to shipped
        if ($order->order_status != $method->status_capture and $order->order_status != $method->status_refunded) {
            //return null;
        }
        ?>
        <script type="text/javascript">
            $(document).ready(function() {
                alert('Hi...');
                var status = document.getElementById('order_status0').value;
                console.log(status);
            });
        </script>


        <?php

        $payment = $payments[0];
        $this->setPluginConfig($method);
        $this->setPaymentMethod($payment->payment_method);

        $oModel = VmModel::getModel('orders');
        $orderModelData = $oModel->getOrder($order->virtuemart_order_id);
       $this->_currentMethod = $method;
       $this->_currentMethod->payment_currency = $this->getPaymentCurrency($method, $orderModelData['details']['BT']->payment_currency_id);
        $payment = end($payments);

        $payment_total = 0;
        $payment_status = "";
        $payment_currency = "";
        $billdesk_order_id = "";
        $billdesk_transation_id = "";
        $billdesk_transation_date = "";


        $db = JFactory::getDBO();
        $query = $db->getQuery(true);
        $query->select('payment_order_total,billdesk_payment_status,payment_currency,billdesk_order_id,billdesk_transation_id,billdesk_transation_date');
        $query->from($db->quoteName('#__virtuemart_payment_plg_billdesk'));
        $query->where($db->quoteName('virtuemart_order_id') . " = " . $order->virtuemart_order_id);
        $db->setQuery($query);
        $options = $db->loadObjectList();
        foreach ($options as $row) {
            $logger->info("Order payment status: $row->payment_status");
            $payment_total = $row->payment_order_total;
            $payment_status = $row->billdesk_payment_status;
            $payment_currency = $row->payment_currency;
            $billdesk_order_id = $row->billdesk_order_id;
            $billdesk_transation_id = $row->billdesk_transation_id;
            $billdesk_transation_date = $row->billdesk_transation_date;
        }
        $environment = $method->environment;
        $merchantid = $method->merchant_id;
        //$merchantkey = $method->merchant_key;
        $encryption_key = $method->encryption_key;
        $signing_key = $method->signing_key;

        $clientid = $method->client_id;
        $keyid = $method->key_id;
        $iteamcode = $method->item_code;
        $childwindow = $method->child_window;

		$config = new Config();
        $config->setMerchantId($merchantid);
        $config->setClientId($clientid);
        $config->setEncryptionKeyId($keyid);
		$config->setSigningKeyId('AES_DIR');
        $config->setEncryptionKeyBase64($encryption_key);
        $config->setSigningKeyBase64($signing_key);
        $base_url = ($environment == 'UAT') ? 'https://uat1.billdesk.com/u2' : 'https://api.billdesk.com';


        if ($old_order_statusa == "C") {
            try {
                $client = new BillDeskJWEHS256Client($config, $base_url);
		        $client->setLogger($logger);

                $request = array(
                    'transactionid' => $billdesk_transation_id,
                    'orderid' => $billdesk_order_id,
                    'mercid' => $merchantid,
                    'transaction_date' => $billdesk_transation_date,
                    'txn_amount' =>  number_format((float)$payment_total, 2, '.', ''),
                    'refund_amount' => number_format((float)$payment_total, 2, '.', ''),
                    'currency' => $payment_currency,
                    'merc_refund_ref_no' => uniqid()
                );
                $response = $client->refundTransaction($request);
                $results = $response->getResponse();
                $res = json_decode(json_encode($results), true);
                $create_res = json_encode(($results), true);
                $logger->info("Response of refund order: $create_res");

                if ($res['status'] == 401 || $res['status'] == 404 || $res['status'] == 500 || $res['status'] == 422 || $res['status'] == 400) {
                    vmError('System error occurred: ' . $res['message']);
                    return false;
                } else {
                    $refund = 'PAYMENT_REFUNDED';
                    $query = $db->getQuery(true);
                    $query->UPDATE($db->quoteName('#__virtuemart_payment_plg_billdesk'))
                        ->set($db->quoteName('billdesk_payment_status')  . ' = ?')
                        ->set($db->quoteName('billdesk_refund_transation_id')  . ' = ?')
                        ->where($db->quoteName('billdesk_order_id') . ' = ?')
                        ->bind(1, $refund)
                        ->bind(2, $res['refundid'])
                        ->bind(3, $billdesk_order_id);
                    $db->setQuery($query)->execute();
                }
                return true;
            } catch (Exception $e) {
                $logger->error("BillDesk Error In Refund function: %1.", array($e->getMessage()));
            }
        } else {
        }
        return null;
    }

    public function setPluginConfig($pluginConfig)
    {
        $this->pluginConfig = $pluginConfig;
    }

    public function setPaymentMethod($paymentMethod)
    {
        $this->paymentMethod = $paymentMethod;
    }

    /**
     * Save updated orderline data to the method specific table
     *
     * @param array   $_formData Form data
     * @return mixed, True on success, false on failures (the rest of the save-process will be
     * skipped!), or null when this method is not actived.
     *
	public function plgVmOnUpdateOrderLine(  $_formData) {
	return null;
	}

	/**
     * plgVmOnEditOrderLineBE
     * This method is fired when editing the order line details in the backend.
     * It can be used to add line specific package codes
     *
     * @param integer $_orderId The order ID
     * @param integer $_lineId
     * @return mixed Null for method that aren't active, text (HTML) otherwise
     *
	public function plgVmOnEditOrderLineBEPayment(  $_orderId, $_lineId) {
	return null;
	}

	/**
     * This method is fired when showing the order details in the frontend, for every orderline.
     * It can be used to display line specific package codes, e.g. with a link to external tracking and
     * tracing systems
     *
     * @param integer $_orderId The order ID
     * @param integer $_lineId
     * @return mixed Null for method that aren't active, text (HTML) otherwise
     *
	public function plgVmOnShowOrderLineFE(  $_orderId, $_lineId) {
	return null;
	}

	/**
     * This event is fired when the  method notifies you when an event occurs that affects the order.
     * Typically,  the events  represents for payment authorizations, Fraud Management Filter actions and other actions,
     * such as refunds, disputes, and chargebacks.
     *
     * NOTE for Plugin developers:
     *  If the plugin is NOT actually executed (not the selected payment method), this method must return NULL
     *
     * @param         $return_context: it was given and sent in the payment form. The notification should return it back.
     * Used to know which cart should be emptied, in case it is still in the session.
     * @param int     $virtuemart_order_id : payment  order id
     * @param char    $new_status : new_status for this order id.
     * @return mixed Null when this method was not selected, otherwise the true or false
     *
     * @author Valerie Isaksen
     *
     *
	public function plgVmOnPaymentNotification() {
	return null;
	}

	/**
     * plgVmOnPaymentResponseReceived
     * This event is fired when the  method returns to the shop after the transaction
     *
     *  the method itself should send in the URL the parameters needed
     * NOTE for Plugin developers:
     *  If the plugin is NOT actually executed (not the selected payment method), this method must return NULL
     *
     * @param int     $virtuemart_order_id : should return the virtuemart_order_id
     * @param text    $html: the html to display
     * @return mixed Null when this method was not selected, otherwise the true or false
     *
     * @author Valerie Isaksen
     *
     *
	function plgVmOnPaymentResponseReceived(, &$virtuemart_order_id, &$html) {
	return null;
	}
     */
    function plgVmOnPaymentResponseReceived(&$html)
    {
        $logger = BillDeskLogger::logger("OnPaymentResponseReceived");
        $status = vRequest::getInt('response_code', 0);
        if ($status == "111") {
            vmError('Model closed by user.');
            $app = JFactory::getApplication();
            $app->redirect(JRoute::_('index.php?option=com_virtuemart&view=cart', false));
        } else {
            $transation_response = vRequest::getString('response', null);
            $logger->info('Transation response: ' . $transation_response);
            $v_payment_id = vRequest::getInt('v_payment_id', 0);
            $logger->info('v_payment_id: ' . $v_payment_id);

            if ($transation_response != "" || $transation_response != null) {
                if (!$v_payment_id) {
                    return;
                }
                if (!($method1 = $this->getVmPluginMethod($v_payment_id))) {
                    return null; // Another method was selected, do nothing
                }
                if (!$this->selectedThisElement($method1->payment_element)) {
                    return false;
                }

               // $merchantkey = $method1->merchant_key;
                $clientid = $method1->client_id;
                //$merchantkey = $method->merchant_key;
                $encryption_key = $method1->encryption_key;
                $signing_key = $method1->signing_key;
                $encryptionKeyId     = $method1->key_id;//"HMAC";
				$signingKeyId       = "AES_DIR";
                $client = new JWESymmetricHelper(
                                 $encryption_key,
                                 $clientid,
                                 $encryptionKeyId,
                                 $logger,
                                 $signing_key,
                                 $signingKeyId
                             );
               $logger->debug("Raw transaction_response: $transation_response");

                $jws = $client->verifyAndDecrypt($transation_response);
                $txn = json_decode($jws);
                $logger->debug("Encrypted_response :" . json_encode($txn));



                $orderTotal = $txn->additional_info->additional_info2;
                $virtuemart_order_id = VirtueMartModelOrders::getOrderIdByOrderNumber($txn->additional_info->additional_info1);
                $logger->info('virtuemart_order_id: ' . $virtuemart_order_id);
                $orderModel = VmModel::getModel('orders');
                $order = $orderModel->getOrder($virtuemart_order_id);
                $order['virtuemart_order_id'] = $virtuemart_order_id;

                $date = JFactory::getDate();
                $today = $date->toSQL();
                $order['customer_notified'] = 1;
                if ($txn->auth_status === '0300') {
                    $order['order_status'] = $method1->status_success;
                    $order['paid_on'] = $today;
                    $order['paid'] = $orderTotal;

                    $dbValues['virtuemart_order_id'] = $virtuemart_order_id;
                    $dbValues['payment_name'] = $this->renderPluginName($method1);
                    $dbValues['order_number'] = $txn->additional_info->additional_info1;
                    $dbValues['virtuemart_paymentmethod_id'] = $v_payment_id;
                    $dbValues['payment_order_total'] = $orderTotal;
                    $dbValues['payment_currency'] = $txn->additional_info->additional_info3;
                    $dbValues['billdesk_order_id'] = $txn->orderid;
                    $dbValues['billdesk_transation_id'] = $txn->transactionid;
                    $dbValues['billdesk_transation_date'] = $txn->transaction_date;
                    $success = 'PAYMENT_SUCCESS';
                    $dbValues['billdesk_payment_status'] = $success;
                    $this->storePSPluginInternalData($dbValues);

                    $cart = VirtueMartCart::getCart();
                    $cart->emptyCart();
                } else if ($txn->auth_status === '0200') {
                    $order['order_status'] = $method1->status_pending;
                } else if ($txn->auth_status === '0399') {
                    $order['order_status'] = $method1->status_canceled;
                }
                $orderModel->updateStatusForOneOrder($virtuemart_order_id, $order, false);
                $link =    JRoute::_("index.php?option=com_virtuemart&view=orders&layout=details&order_number=" . $order['details']['BT']->order_number . "&order_pass=" . $order['details']['BT']->order_pass, false);
                $html .= '<br />
                            <a class="vm-button-correct" href="' . $link . '">' . vmText::_('COM_VIRTUEMART_ORDER_VIEW_ORDER') . '</a>';
                return true;
            } else {
                $virtuemart_paymentmethod_id = vRequest::getInt('pm', 0);
                if (!$virtuemart_paymentmethod_id) {
                    return;
                }
                if (!($method = $this->getVmPluginMethod($virtuemart_paymentmethod_id))) {
                    return null; // Another method was selected, do nothing
                }
                if (!$this->selectedThisElement($method->payment_element)) {
                    return false;
                }

                //$merchantkey = $method->merchant_key;
                $clientid = $method->client_id;
               $encryption_key = $method->encryption_key;
                $signing_key = $method->signing_key;
                $encryptionKeyId     = $method->key_id;//"HMAC";
				$signingKeyId       = "AES_DIR";
                $response = array_shift(array_values($_POST));
                $logger->info('transation response: ' . $response);

                
                $client = new JWESymmetricHelper(
                                 $encryption_key,
                                 $clientid,
                                 $encryptionKeyId,
                                 $logger,
                                 $signing_key,
                                 $signingKeyId
                             );
               $logger->debug("Raw transaction_response: $response");

                $jws = $client->verifyAndDecrypt($response);
                $txn = json_decode($jws);
                $logger->debug("Encrypted_response :" . json_encode($txn));
              /*   $client = new JWEHS256Helper($merchantkey, $clientid);
                $jws = $client->verifyAndDecrypt($response);
                $txn = json_decode($jws); */

                $orderTotal = $txn->additional_info->additional_info2;
                $virtuemart_order_id = VirtueMartModelOrders::getOrderIdByOrderNumber($txn->additional_info->additional_info1);
                $logger->info('virtuemart_order_id: ' . $virtuemart_order_id);
                $orderModel = VmModel::getModel('orders');
                $order = $orderModel->getOrder($virtuemart_order_id);
                $order['virtuemart_order_id'] = $virtuemart_order_id;
                //$order['comments'] = '';
                $date = JFactory::getDate();
                $today = $date->toSQL();
                $order['customer_notified'] = 1;
                if ($txn->auth_status === '0300') {
                    $order['order_status'] = $method->status_success;
                    $order['paid_on'] = $today;
                    $order['paid'] = $orderTotal;
                    $dbValues['virtuemart_order_id'] = $virtuemart_order_id;
                    $dbValues['payment_name'] = $this->renderPluginName($method);
                    $dbValues['order_number'] = $txn->additional_info->additional_info1;
                    $dbValues['virtuemart_paymentmethod_id'] = $virtuemart_paymentmethod_id;
                    $dbValues['payment_order_total'] = $orderTotal;
                    $dbValues['payment_currency'] = $txn->additional_info->additional_info3;
                    $dbValues['billdesk_order_id'] = $txn->orderid;
                    $dbValues['billdesk_transation_id'] = $txn->transactionid;
                    $dbValues['billdesk_transation_date'] = $txn->transaction_date;
                    $success = 'PAYMENT_SUCCESS';
                    $dbValues['billdesk_payment_status'] = $success;
                    $this->storePSPluginInternalData($dbValues);

                    $cart = VirtueMartCart::getCart();
                    $cart->emptyCart();
                } else if ($txn->auth_status === '0200') {
                    $order['order_status'] = $method->status_pending;
                } else if ($txn->auth_status === '0399') {
                    $order['order_status'] = $method->status_canceled;
                }

                $orderModel->updateStatusForOneOrder($virtuemart_order_id, $order, TRUE);
                $link =    JRoute::_("index.php?option=com_virtuemart&view=orders&layout=details&order_number=" . $order['details']['BT']->order_number . "&order_pass=" . $order['details']['BT']->order_pass, false);
                $html .= '<br />
                    <a class="vm-button-correct" href="' . $link . '">' . vmText::_('COM_VIRTUEMART_ORDER_VIEW_ORDER') . '</a>';
                return true;
            }
        }
    }
    function plgVmOnPaymentNotification()
    {
        $logger = BillDeskLogger::logger("Payment Notification");
        $logger->info('Child window false case function:');

        $merchant_id = vRequest::getString('merchant_id', null);
        $merchant_key = vRequest::getString('merchant_key', null);
        
        $encryption_key = vRequest::getString('encryption_key', null);
        $signing_key = vRequest::getString('signing_key', null);

        $key_id = vRequest::getString('key_id', null);

        $client_key = vRequest::getString('client_key', null);
        $item_code = vRequest::getString('item_code', null);
        $env = vRequest::getString('env', null);
        if ($merchant_id != "" || $merchant_id != null || $encryption_key != "" || $encryption_key != null || $signing_key != "" || $signing_key != null ||$client_key != "" || $client_key != null || $item_code != "" || $item_code != null) {
            try {
                $ip = getenv('HTTP_CLIENT_IP') ?:
                    getenv('HTTP_X_FORWARDED_FOR') ?:
                    getenv('HTTP_X_FORWARDED') ?:
                    getenv('HTTP_FORWARDED_FOR') ?:
                    getenv('HTTP_FORWARDED') ?:
                    getenv('REMOTE_ADDR');
                $ipaddress = strtok($ip, ",");

                $userAgent = $_SERVER['HTTP_USER_AGENT'];

                $returnUrl = JURI::root() . 'index.php?option=com_virtuemart&view=pluginresponse&task=pluginnotification&tmpl=component'; //JURI::root() . 'index.php?option=com_virtuemart&view=pluginresponse&task=pluginresponsereceived';

                $config = new Config();
                $config->setClientId(trim($client_key));
                $config->setMerchantId(trim($merchant_id));
                $config->setEncryptionKeyBase64(trim($encryption_key));
                $config->setSigningKeyBase64(trim($signing_key));
                $config->setEncryptionKeyId($key_id);
                $config->setSigningKeyId('AES_DIR');

                $endpoint = ($env === 'UAT')
				? 'https://uat1.billdesk.com/u2'
				: 'https://api.billdesk.com';

            // Initialize BillDesk Client
			$client = new BillDeskJWEHS256Client($config, $endpoint);
			$client->setLogger($logger);

                try {
                    $request = array(
                        'mercid' => $merchant_id,
                        'orderid' => uniqid(),
                        'amount' => '300', //$total,
                        'order_date' => date_format(new \DateTime(), DATE_W3C),
                        'currency' => '356',
                        'ru' =>  $returnUrl,
                        'itemcode' => $item_code,
                        'device' => array(
                            'init_channel' => 'internet',
                            'ip' => $ipaddress,
                            'user_agent' => $userAgent
                        ),
                    );
                    $response = $client->createOrder($request);
                    $results = $response->getResponse();
                    $res = json_decode(json_encode($results), true);
                    $create_res = json_encode(($results), true);
                    $logger->info('Create order test response: ' . $create_res);
        ?> <?php echo $create_res ?>
            <?php
                    die();
                    return $res;
                } catch (RequestException $ex) {
                    $logger->error("Exception on create order test: " . $ex);
                }
            } catch (RequestException $ex) {
                if ($ex->hasResponse()) {
                    $logger->error("server response with error: . Message::toString($ex->getResponse()");
                    return true;
                }
            }
        } else {
            ?>
            <html>

            <head>
                <script>
                    function closeWindow() {
                        window.close();
                    }
                </script>
            </head>

            <body onload="closeWindow()">
            </body>

            </html>
<?php
        }
    }
    // function _getPaymentResponseHtml($method, $order, $payments)
    // {
    //     // vmLanguage::loadJLang('com_virtuemart_orders', TRUE);
    //     if (!class_exists('CurrencyDisplay')) {
    //         require(VMPATH_ADMIN . DS . 'helpers' . DS . 'currencydisplay.php');
    //     }

    //     if (!class_exists('VirtueMartCart')) {
    //         require(VMPATH_SITE . DS . 'helpers' . DS . 'cart.php');
    //     }

    //     // vmLanguage::loadJLang('com_virtuemart_orders', TRUE);

    //     $totalInPaymentCurrency = vmPSPlugin::getAmountInCurrency($order['details']['BT']->order_total, $order['details']['BT']->order_currency);
    //     $cart = VirtueMartCart::getCart();
    //     $currencyDisplay = CurrencyDisplay::getInstance($cart->pricesCurrency);

    //     $payment = end($payments);
    //     $pluginName = $this->renderPluginName($method, $where = 'post_payment');
    //     $html = $this->renderByLayout('post_payment', array(
    //         'order' => $order,
    //         'paymentInfos' => $payment,
    //         'pluginName' => $pluginName,
    //         'displayTotalInPaymentCurrency' => $totalInPaymentCurrency['display']
    //     ));
    //     return $html;
    // }
}
