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

defined('_JEXEC') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
use Joomla\CMS\MVC\Controller\BaseController;
use Joomla\CMS\Session\Session;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Table\Table;
use Joomla\CMS\Date\Date;

/**
 * Controller class for shopping cart.
 *
 * @package     CMGiftCard
 * @subpackage  com_cmgiftcard
 * @since       1.0.0
 */
class CMGiftCardControllerCart extends BaseController
{
	/**
	 * Add new gift card to shopping cart.
	 *
	 * @return  mixed
	 *
	 * @since   1.0.0
	 */
	public function addToCart()
	{
		Session::checkToken() or jexit(Text::_('JINVALID_TOKEN'));

		$app = Factory::getApplication();
		$session = Factory::getSession();
		$cart = $session->get('cart', array(), 'CMGiftCard');
		$data = $this->input->get('jform', array(), 'array');
		$itemId = $this->input->get('item_id', 0, 'uint');
		$context = 'com_cmgiftcard.gift_card';
		$formUrl = 'index.php?option=com_cmgiftcard&view=form';

		if (isset($data['card_type']))
		{
			if ($data['card_type'] == 'physical')
			{
				$returnUrl = $formUrl . '&type=physical';
			}
			else
			{
				$returnUrl = $formUrl . '&type=electronic';
			}
		}
		else
		{
			$this->setRedirect(CMGiftCardHelper::prepareRoute('index.php?option=com_cmgiftcard&view=default'));

			return false;
		}

		if (!isset($cart['items']))
		{
			$cart['items'] = array();
		}

		if ($itemId > 0)
		{
			if (!isset($cart['items'][$itemId - 1]))
			{
				$this->setMessage(Text::_('COM_CMGIFTCARD_ERROR_ITEM_NOT_FOUND'), 'error');
				$this->setRedirect(CMGiftCardHelper::prepareRoute('index.php?option=com_cmgiftcard&view=default'));

				return false;
			}

			$returnUrl .= '&item_id=' . $itemId;
		}

		$this->setRedirect(CMGiftCardHelper::prepareRoute($returnUrl));

		$deliveryDate = $data['deliver_date'] ?: '';

		if ($deliveryDate)
		{
			$deliveryDate = str_replace('/', '-', $deliveryDate);
			$deliveryDate = str_replace('.', '-', $deliveryDate);

			$dateParts = explode('-', $deliveryDate);

			if (count($dateParts) != 3)
			{
				$data['deliver_date'] = '';

				$app->enqueueMessage(Text::_('COM_CMGIFTCARD_ERROR_DELIVER_DATE_FORMAT'), 'warning');

				$app->setUserState($context . '.data', $data);

				return false;
			}

			$params = ComponentHelper::getParams('com_cmgiftcard');
			$dateFormat = $params->get('date_format', 'COM_CMGIFTCARD_DATE_FORMAT_2');

			// %m/%d/%Y and %m-%d-%Y
			if ($dateFormat == 'COM_CMGIFTCARD_DATE_FORMAT_5' || $dateFormat == 'COM_CMGIFTCARD_DATE_FORMAT_6')
			{
				$newDateParts = [];
				$newDateParts[] = $dateParts[2];
				$newDateParts[] = $dateParts[0];
				$newDateParts[] = $dateParts[1];

				$deliveryDate = implode('-', $newDateParts);
			}

			try {
				$date = new Date($deliveryDate);

				$deliveryDate = $date->format('Y-m-d');
			} catch (Exception $e) {
				$data['deliver_date'] = '';

				$app->enqueueMessage(Text::_('COM_CMGIFTCARD_ERROR_DELIVER_DATE_FORMAT'), 'warning');

				$app->setUserState($context . '.data', $data);

				return false;
			}

			$data['deliver_date'] = $deliveryDate;
		}

		$model = BaseDatabaseModel::getInstance('Form', 'CMGiftCardModel');
		$form = $model->getForm($data, false);

		if (!$form)
		{
			$app->enqueueMessage($model->getError(), 'error');

			return false;
		}

		$validData = $model->validate($form, $data);

		if ($validData === false)
		{
			$errors = $model->getErrors();

			for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++)
			{
				if ($errors[$i] instanceof Exception)
				{
					$app->enqueueMessage($errors[$i]->getMessage(), 'warning');
				}
				else
				{
					$app->enqueueMessage($errors[$i], 'warning');
				}
			}

			$app->setUserState($context . '.data', $data);

			return false;
		}

		$app->setUserState($context . '.data', null);

		if (!isset($data['design_title']))
		{
			$design = BaseDatabaseModel::getInstance('Design', 'CMGiftCardModel')->getDesign($data['design_id']);

			$data['design_title'] = isset($design->title) ? $design->title : '';
		}

		if ($itemId <= 0)
		{
			$cart['items'][] = $data;
		}
		else
		{
			$cart['items'][$itemId - 1] = $data;
		}

		$session->set('cart', $cart, 'CMGiftCard');

		$this->setRedirect(CMGiftCardHelper::prepareRoute('index.php?option=com_cmgiftcard&view=cart'));

		return true;
	}

	/**
	 * Remove a gift card from cart.
	 *
	 * @return  mixed
	 *
	 * @since   1.0.0
	 */
	public function removeFromCart()
	{
		Session::checkToken() or jexit(Text::_('JINVALID_TOKEN'));

		$app = Factory::getApplication();
		$session = Factory::getSession();
		$cart = $session->get('cart', array(), 'CMGiftCard');
		$index = $this->input->get('index', 0, 'uint');

		if (!isset($cart['items']))
		{
			$cart['items'] = array();
		}
		elseif(isset($cart['items'][$index]))
		{
			unset($cart['items'][$index]);
		}

		if (count($cart['items']))
		{
			$items = array();

			foreach ($cart['items'] as $item)
			{
				$items[] = $item;
			}

			$cart['items'] = $items;
		}

		$session->set('cart', $cart, 'CMGiftCard');

		$this->setRedirect(CMGiftCardHelper::prepareRoute('index.php?option=com_cmgiftcard&view=cart'));

		return true;
	}

	/**
	 * Empty shopping cart.
	 *
	 * @return  mixed
	 *
	 * @since   1.0.0
	 */
	public function emptyCart()
	{
		Session::checkToken() or jexit(Text::_('JINVALID_TOKEN'));

		Factory::getSession()->set('cart', [], 'CMGiftCard');

		$this->setRedirect(CMGiftCardHelper::prepareRoute('index.php?option=com_cmgiftcard&view=cart'));

		return true;
	}

	/**
	 * Checkout
	 *
	 * @return  mixed
	 *
	 * @since   1.0.0
	 */
	public function checkout()
	{
		Session::checkToken() or jexit(Text::_('JINVALID_TOKEN'));

		$app = Factory::getApplication();
		$session = Factory::getSession();
		$cart = $session->get('cart', array(), 'CMGiftCard');

		$this->setRedirect(CMGiftCardHelper::prepareRoute('index.php?option=com_cmgiftcard&view=cart'));

		if (empty($cart))
		{
			return false;
		}

		$data = $this->input->get('jform', array(), 'array');
		$context = 'com_cmgiftcard.shopping_cart';

		$model = BaseDatabaseModel::getInstance('Cart', 'CMGiftCardModel');
		$form = $model->getForm($data, false);

		if (!$form)
		{
			$app->enqueueMessage($model->getError(), 'error');

			return false;
		}

		$app->setUserState($context . '.data', $data);

		$validData = $model->validate($form, $data);

		if ($validData === false)
		{
			$errors = $model->getErrors();

			for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++)
			{
				if ($errors[$i] instanceof Exception)
				{
					$app->enqueueMessage($errors[$i]->getMessage(), 'warning');
				}
				else
				{
					$app->enqueueMessage($errors[$i], 'warning');
				}
			}

			return false;
		}

		PluginHelper::importPlugin('cmgiftcard');

		$payments = $app->triggerEvent('onCMGCGetPaymentIdentity');

		if (count($payments) == 1 && ComponentHelper::getParams('com_cmgiftcard')->get('hide_lone_payment_method', 0) == 1)
		{
			$data['payment_method'] = $payments[0]['id'];
			$validData['payment_method'] = $payments[0]['id'];
		}

		Table::addIncludePath(JPATH_COMPONENT . '/tables');

		$orderModel = BaseDatabaseModel::getInstance('Order', 'CMGiftCardModel');
		$orderData = $orderModel->createOrder($data);

		if ($orderData !== null)
		{
			$cardModel = BaseDatabaseModel::getInstance('Card', 'CMGiftCardModel');

			foreach ($cart['items'] as $card)
			{
				$result = $cardModel->createCard($card, $orderData['id']);

				if (!$result)
				{
					$app->enqueueMessage($cardModel->getError(), 'error');

					return false;
				}
			}

			$validData['order_number'] = $orderData['number'];
			$app->setUserState($context . '.data', $validData);

			$this->setRedirect(CMGiftCardHelper::prepareRoute('index.php?option=com_cmgiftcard&view=checkout'));
		}
		else
		{
			$app->enqueueMessage($orderModel->getError(), 'error');

			return false;
		}

		return true;
	}
}
