<?php
/**
 * @package     CMGiftCard
 * @subpackage  plg_cmgiftcard_ideal
 * @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\Router\Route;

/**
 * Eway payment method for CMGiftCard.
 *
 * @package     CMGiftCard
 * @subpackage  plg_cmgiftcard_ideal
 * @since       1.2.2
 */
class PlgCMGiftCardIdeal 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.2
	 */
	public function __construct(&$subject, $config = array())
	{
		$this->gatewayId = 'ideal';
		$this->gatewayName = 'PLG_CMGIFTCARD_IDEAL_NAME';

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

	/**
	 * Method to get payment form.
	 *
	 * @param   array  $data  Billing data.
	 *
	 * @return  array
	 *
	 * @since   1.2.2
	 */
	public function onCMGCGetPaymentForm($data)
	{
		require_once dirname(__FILE__) . '/Mollie/API/Autoloader.php';

		$gatewayId = isset($data['billing']['payment_method']) ? $data['billing']['payment_method'] : '';

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

		$app = Factory::getApplication();
		$gatewayName = $this->params->get('name', Text::_($this->gatewayName));
		$apiKey = $this->params->get('api_key');
		$secondsToWait = (int) $this->params->get('seconds_to_wait', 5);
		$description = $this->params->get('description', 'Order {order_number}');
		$description = str_replace('{order_number}', $data['billing']['order_number'], $description);

		$webhookUrl = Uri::root() . 'index.php?option=com_cmgiftcard&task=callback&gateway=' . $this->gatewayId;
		$redirectUrl = $webhookUrl . '&order_number=' . $data['billing']['order_number'];

		$mollie = new Mollie_API_Client;
		$mollie->setApiKey($apiKey);

		$payment = $mollie->payments->create(array(
			"amount"		=> $data['total'],
			"description"	=> $description,
			"redirectUrl"	=> $redirectUrl,
			"webhookUrl"	=> $webhookUrl,
			"method"		=> "ideal",
			"metadata"		=> json_encode(['order_number' => $data['billing']['order_number']]),
		));

		if (isset($payment->links->paymentUrl))
		{
			$paymentUrl = $payment->links->paymentUrl;
		}
		else
		{
			$app->enqueueMessage(Text::_('PLG_CMGIFTCARD_IDEAL_NO_PAYMENT_URL_ERROR'), 'error');
			$app->redirect(CMGiftCardHelper::prepareRoute('index.php?option=com_cmgiftcard&view=cart'));
		}

		$db = Factory::getDbo();
		$query = $db->getQuery(true)
			->select('COUNT(*)')
			->from($db->qn('#__cmgiftcard_orders'))
			->where($db->qn('transaction_id') . ' = ' . $db->q($payment->id));
		$count = $db->setQuery($query)->loadResult();

		if ($count > 0)
		{
			$app->enqueueMessage(Text::_('PLG_CMGIFTCARD_IDEAL_DUPLICATED_PAYMENT_ID_ERROR'), 'error');
			$app->redirect(CMGiftCardHelper::prepareRoute('index.php?option=com_cmgiftcard&view=cart'));
		}

		$query->clear()
			->update($db->qn('#__cmgiftcard_orders'))
			->set($db->qn('transaction_id') . ' = ' . $db->q($payment->id))
			->where($db->qn('order_number') . ' = ' . $db->q($data['billing']['order_number']));
		$db->setQuery($query)->execute();

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

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

		return $html;
	}

	/**
	 * Method to get validate Eway callback.
	 *
	 * @return  boolean
	 *
	 * @since   1.2.0
	 */
	public function onCMGCValidateCallback()
	{
		require_once dirname(__FILE__) . '/Mollie/API/Autoloader.php';

		$app = Factory::getApplication();
		$jinput = $app->input;
		$gatewayId = $jinput->get('gateway', '');

		if ($gatewayId != $this->gatewayId)
		{
			$app->redirect('index.php');
		}

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

		if (isset($_GET['order_number']))
		{
			$data = $jinput->get->getArray();
			$isCallback = false;
			$orderNumber = $jinput->get('order_number');

			$query->select('*')
				->from($db->qn('#__cmgiftcard_orders'))
				->where($db->qn('order_number') . ' = ' . $db->q($orderNumber));
			$order = $db->setQuery($query)->loadObject();

			if (!isset($order->id))
			{
				$isValid = false;
				$reason = "Order number $orderNumber not found";
			}

			if ($isValid && empty($order->transaction_id))
			{
				$isValid = false;
				$reason = "Order ID " . $order->id . " didn't contain payment ID";
			}

			if ($isValid)
			{
				$paymentId = $order->transaction_id;
			}
		}
		elseif (isset($_POST['id']))
		{
			$data = $jinput->post->get->getArray();
			$paymentId = $jinput->post->get('id');

			$query->select('*')
				->from($db->qn('#__cmgiftcard_orders'))
				->where($db->qn('transaction_id') . ' = ' . $db->q($paymentId));
			$order = $db->setQuery($query)->loadObject();

			if (!isset($order->id))
			{
				$isValid = false;
				$reason = "Order number $orderNumber not found";
			}
		}

		if ($isValid && $order->order_status == 'paid')
		{
			$reason = "Order ID " . $order->id . " was already paid.";
			$isValid = false;
		}

		if (!$isValid)
		{
			$data['failure_reason'] = $reason;

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

			if ($isCallback)
			{
				return $result;
			}
			else
			{
				$app->redirect(Route::_('/'));
			}
		}

		$apiKey = $this->params->get('api_key');
		$mollie = new Mollie_API_Client;
		$mollie->setApiKey($apiKey);
		$payment = $mollie->payments->get($paymentId);

		if ($payment->isPaid() === true)
		{
			$this->logNotification($data, $isValid);

			if ($isCallback)
			{
				$result['gateway_id'] = $this->gatewayId;
				$result['transaction_id'] = $paymentId;
				$result['order_id'] = $order->id;

				return $result;
			}
			else
			{
				$query->clear()
					->update($db->qn('#__cmgiftcard_orders'))
					->set($db->qn('order_status') . ' = ' . $db->q('paid'))
					->set($db->qn('transaction_id') . ' = ' . $db->q($paymentId))
					->set($db->qn('completed') . ' = ' . $db->q(Factory::getDate()->toSql()))
					->where($db->qn('id') . ' = ' . $db->q($order->id));
				$db->setQuery($query)->execute();

				CMGiftCardHelper::sendOrderEmail($order->id);
				CMGiftCardHelper::sendElectronicCardEmail($order->id);
				CMGiftCardHelper::sendPhysicalCardEmail($order->id);

				$app->redirect(CMGiftCardHelper::prepareRoute('index.php?option=com_cmgiftcard&view=checkout') . '?layout=success');
			}
		}
		elseif ($payment->isOpen() === false)
		{
			$isValid = false;
			$data['failure_reason'] = "Payment ID $paymentId was not paid and not opened";
			$this->logNotification($data, $isValid);

			if ($isCallback)
			{
				return $result;
			}
			else
			{
				$app->redirect(CMGiftCardHelper::prepareRoute('index.php?option=com_cmgiftcard&view=checkout') . '?layout=cancel');
			}
		}
		elseif ($payment->isOpen() === true)
		{
			$isValid = false;
			$data['failure_reason'] = "Payment ID $paymentId was still opened";
			$this->logNotification($data, $isValid);

			if ($isCallback)
			{
				return $result;
			}
			else
			{
				$app->redirect('/');
			}
		}
		else
		{
			$isValid = false;
			$data['failure_reason'] = "Unknown";
			$this->logNotification($data, $isValid);

			if ($isCallback)
			{
				return $result;
			}
			else
			{
				$app->redirect('/');
			}
		}

		return $result;
	}
}
