<?php
/**
 * @package     CMGiftCard
 * @subpackage  plg_cmgiftcard_mygate
 * @copyright   Copyright (C) 2016-2024 CMExension
 * @license     GNU General Public License version 2 or later
 */

defined('_JEXEC') or die;

require_once JPATH_ROOT . '/administrator/components/com_cmgiftcard/helpers/plugin/cmgiftcard.php';

use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Uri\Uri;
use Joomla\CMS\MVC\Model\BaseDatabaseModel;

/**
 * MyGate payment method for CMGiftCard.
 *
 * @package     CMGiftCard
 * @subpackage  plg_cmgiftcard_mygate
 * @since       1.2.0
 */
class PlgCMGiftCardMyGate extends CMGiftCardPlugin
{
	/**
	 * Constructor
	 *
	 * @param   object  &$subject  The object to observe
	 * @param   array   $config    An optional associative array of configuration settings.
	 *                             Recognized key values include 'name', 'group', 'params', 'language'
	 *                             (this list is not meant to be comprehensive).
	 *
	 * @since   1.2.0
	 */
	public function __construct(&$subject, $config = array())
	{
		$this->gatewayId = 'mygate';
		$this->gatewayName = 'PLG_CMGIFTCARD_MYGATE_NAME';

		parent::__construct($subject, $config);
	}

	/**
	 * Method to get payment form.
	 *
	 * @param   array  $data  Billing data.
	 *
	 * @return  array
	 *
	 * @since   1.2.0
	 */
	public function onCMGCGetPaymentForm($data)
	{
		$gatewayId = isset($data['billing']['payment_method']) ? $data['billing']['payment_method'] : '';

		if ($gatewayId != $this->gatewayId)
			return false;

		$gatewayName = $this->params->get('name', Text::_($this->gatewayName));
		$merchantId = $this->params->get('merchant_id');
		$applicationId = $this->params->get('application_id');
		$currencyCode = $this->params->get('currency_code', 'USD');
		$mode = $this->params->get('mode', 1);
		$secondsToWait = (int) $this->params->get('seconds_to_wait', 5);
		$description = $this->params->get('description', '');

		$clickHereLink = '<a href="#" onClick="document.checkOutForm.submit(); return false;">' . Text::_('COM_CMGIFTCARD_CLICK_HERE') . '</a>';
		$checkoutMessage = Text::sprintf('COM_CMGIFTCARD_CHECKOUT_MESSAGE', $gatewayName, $secondsToWait, $clickHereLink);

		$url = 'https://virtual.mygateglobal.com/PaymentPage.cfm';

		$returnUrl = Uri::root() . 'index.php?option=com_cmgiftcard&task=callback&gateway=' . $this->gatewayId;

		$formData = array(
			'Mode'						=> $mode,
			'txtMerchantID'				=> $merchantId,
			'txtApplicationID'			=> $applicationId,
			'txtMerchantReference'		=> $data['billing']['order_number'],
			'txtPrice'					=> $data['total'],
			'txtCurrencyCode'			=> $currencyCode,
			'txtDisplayPrice'			=> $data['total'],
			'txtDisplayCurrencyCode'	=> $currencyCode,
		);

		foreach ($formData as $key => $value)
		{
			$formData[$key] = htmlspecialchars($value, ENT_QUOTES);
		}

		$formData['txtRedirectSuccessfulURL'] = $returnUrl;
		$formData['txtRedirectFailedURL'] = $returnUrl;

		@ob_start();
		include dirname(__FILE__) . '/form.php';
		$html = @ob_get_clean();

		return $html;
	}

	/**
	 * Method to get validate MyGate callback.
	 *
	 * @return  boolean
	 *
	 * @since   1.2.0
	 */
	public function onCMGCValidateCallback()
	{
		$app = Factory::getApplication();
		$jinput = $app->input;
		$gatewayId = $jinput->get('gateway', '');

		$result = array(
			'validation'		=> false,
			'gateway_id'		=> '',
			'transaction_id'	=> '',
			'order_id'			=> ''
		);

		if ($gatewayId != $this->gatewayId)
		{
			return $result;
		}

		$postData = $jinput->post->getArray();
		$postResult = $postData['_RESULT'];

		$inputAmount = floatval($postData['_AMOUNT']);
		$inputCurrencyCode = strtoupper($postData['_CURRENCYCODE']);
		$inputOrderId = (int) $postData['_MERCHANTREFERENCE'];
		$inputTransactionId = $postData['_TRANSACTIONINDEX'];
		$bankErrorMessage = $postData['_BANK_ERROR_MESSAGE'];

		if ($postResult >= 0)
		{
			$isValid = true;
		}
		else
		{
			$isValid = false;
			$reason = $bankErrorMessage;
		}

		$db = Factory::getDbo();
		$query = $db->getQuery(true);

		if ($isValid)
		{
			$query->clear()
				->select('*')
				->from($db->qn('#__cmgiftcard_orders'))
				->where($db->qn('order_number') . ' = ' . $db->q($inputOrderId));
			$db->setQuery($query);
			$order = $db->loadObject();

			if (!isset($order->id))
			{
				$isValid = false;
				$reason = "Order number $orderId didn't exist";
			}
		}

		if ($isValid)
		{
			$query->clear()
				->select('*')
				->from($db->qn('#__cmgiftcard_cards'))
				->where($db->qn('order_id') . ' = ' . $db->quote($order->id));
			$db->setQuery($query);
			$cards = $db->loadObjectList();

			if (count($cards))
			{
				$amount = 0;

				foreach ($cards as $card)
				{
					$amount += $card->amount;
				}

				$isValid = ($amount- $inputAmount) < 0.01;

				if (!$isValid)
				{
					$reason = "Invalid paid amount, expected $amount, got $inputAmount";
				}
			}
			else
			{
				$isValid = false;
				$reason = "No gift cards found";
			}
		}

		if ($isValid)
		{
			$currencyCode = strtoupper($this->params->get('currency_code', ''));

			if ($currencyCode != $inputCurrencyCode)
			{
				$isValid = false;
				$reason = "Invalid currency, expected $currencyCode, got $inputCurrencyCode";
			}
		}

		$result['valid'] = $isValid;
		$siteUrl = str_replace(Uri::root(true), '', substr(Uri::root(), 0, -1));

		if ($isValid)
		{
			$redirectUrl = $siteUrl . CMGiftCardHelper::prepareRoute('index.php?option=com_cmgiftcard&view=checkout') . '?layout=success';

			require_once JPATH_SITE . '/components/com_cmgiftcard/models/order.php';
			require_once JPATH_SITE . '/administrator/components/com_cmgiftcard/helpers/cmgiftcard.php';

			$orderModel = BaseDatabaseModel::getInstance('Order', 'CMGiftCardModel');
			$queryResult = $orderModel->updatePaidOrder($order->id, $inputTransactionId);

			if ($queryResult)
			{
				CMGiftCardHelper::sendOrderEmail($order->id);
			}
		}
		else
		{
			$redirectUrl = $siteUrl . CMGiftCardHelper::prepareRoute('index.php?option=com_cmgiftcard&view=checkout') . '?layout=cancel';

			if ($bankErrorMessage != '')
			{
				$app->enqueueMessage($bankErrorMessage);
			}
		}

		$this->logNotification($postData, $isValid);

		$app->redirect($redirectUrl);

		return $result;
	}
}
