<?php
/**
 * @package     CMGiftCard
 * @subpackage  plg_cmgiftcard_voguepay
 * @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\Plugin\CMSPlugin;
use Joomla\CMS\Uri\Uri;
use Joomla\CMS\Filesystem\File;

/**
 * VoguePay payment method for CMGiftCard.
 *
 * @package     CMGiftCard
 * @subpackage  plg_cmgiftcard_voguepay
 * @since       1.2.0
 */
class PlgCMGiftCardVoguePay 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 = 'voguepay';
		$this->gatewayName = 'PLG_CMGIFTCARD_VOGUEPAY_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');
		$storeId = $this->params->get('store_id');
		$currencyCode = $this->params->get('currency_code', 'USD');
		$secondsToWait = (int) $this->params->get('seconds_to_wait', 5);

		$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://voguepay.com/pay/';
		$siteUrl = str_replace(Uri::root(true), '', substr(Uri::root(), 0, -1));
		$successUrl = $siteUrl . CMGiftCardHelper::prepareRoute('index.php?option=com_cmgiftcard&view=checkout') . '?layout=success';
		$failUrl = $siteUrl . CMGiftCardHelper::prepareRoute('index.php?option=com_cmgiftcard&view=checkout') . '?layout=cancel';
		$notifyUrl = Uri::root() . 'index.php?option=com_cmgiftcard&task=callback&gateway=' . $this->gatewayId;

		$formData = array(
			'v_merchant_id'	=> $merchantId,
			'merchant_ref'	=> $data['billing']['order_number'],
			'memo'			=> $data['billing']['order_number'],
			'notify_url'	=> $notifyUrl,
			'success_url'	=> $successUrl,
			'fail_url'		=> $failUrl,
			'store_id'		=> $storeId,
			'total'			=> $data['total'],
			'cur'			=> $currencyCode,
		);

		foreach ($data['items'] as $n => $item)
		{
			$formData['price_' . ($n + 1)] = $item['amount'];
			$formData['item_' . ($n + 1)] = $item['design_title'];
		}

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

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

		return $html;
	}

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

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

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

		$environment = $this->params->get('environment', 'live');
		$test = ($environment == 'test') ? true : false;
		$transactionId = $jinput->post->get('transaction_id');
		$url = 'https://voguepay.com/?v_transaction_id=' . $transactionId . '&type=json';

		if ($test)
		{
			$url .= '&demo=true';
		}

		$json = file_get_contents($url);
		$transaction = json_decode($json, true);

		if (isset($transaction['status']) && $transaction['status'] == 'Approved')
		{
			$isValid = true;
		}
		else
		{
			$isValid = false;
			$reason = "Transaction was not completed";
		}

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

		if ($isValid)
		{
			$inputOrderId = (int) $transaction['merchant_ref'];

			$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;
				}

				$inputAmount = floatval($transaction['total']);
				$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)
		{
			$merchantId = $this->params->get('merchant_id', '');
			$inputMerchantId = $transaction['merchant_id'];

			if ($merchantId != $inputMerchantId)
			{
				$isValid = false;
				$reason = "Invalid merchant ID, expected $merchantId, got $inputMerchantId";
			}
		}

		$result['valid'] = $isValid;

		if ($isValid)
		{
			$result['gateway_id'] = $this->gatewayId;
			$result['transaction_id'] = $transactionId;
			$result['order_id'] = $order->id;
		}
		else
		{
			$transaction['failure_reason'] = $reason;

			if (!isset($transaction['transaction_id']))
			{
				$transaction['transaction_id'] = $transactionId;
			}
		}

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

		return $result;
	}
}
