<?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\Component\ComponentHelper;
use Joomla\CMS\MVC\Model\ItemModel;
use Joomla\CMS\Table\Table;

/**
 * Model for order.
 *
 * @package     CMGiftCard
 * @subpackage  com_cmgiftcard
 * @since       1.0.0
 */
class CMGiftCardModelOrder extends ItemModel
{
	/**
	 * Method to auto-populate the model state.
	 *
	 * Note. Calling getState in this method will result in recursion.
	 *
	 * @param   string  $ordering   An optional ordering field.
	 * @param   string  $direction  An optional direction (asc|desc).
	 *
	 * @return  void
	 *
	 * @since   1.0.0
	 */
	protected function populateState($ordering = '', $direction = '')
	{
		$params = Factory::getApplication()->getParams();
		$this->setState('params', $params);

		parent::populateState($ordering, $direction);
	}

	/**
	 * Method to get create a new order.
	 *
	 * @param   array  $data  Order data.
	 *
	 * @return  mixed
	 *
	 * @since   1.0.0
	 */
	public function createOrder($data)
	{
		$data['user_id'] = Factory::getUser()->id;
		$data['created'] = Factory::getDate()->toSql();

		$params = ComponentHelper::getParams('com_cmgiftcard');
		$orderStartingNumber = (int) $params->get('order_starting_number');

		$db = $this->getDbo();
		$query = $db->getQuery(true)
			->select('MAX(' . $db->qn('order_number') . ')')
			->from($db->qn('#__cmgiftcard_orders'));
		$maxOrderNumber = $db->setQuery($query)->loadResult();

		$data['order_number'] = ($maxOrderNumber >= $orderStartingNumber) ? $maxOrderNumber + 1 : $orderStartingNumber;

		$table = Table::getInstance('Order', 'CMGiftCardTable');

		while ($table->load(array('order_number' => $data['order_number'])))
		{
			$data['order_number'] += 1;
		}

		$table->reset();

		if (!$table->bind($data))
		{
			$this->setError($table->getError());

			return false;
		}

		if (!$table->check())
		{
			$this->setError($table->getError());

			return false;
		}

		if (!$table->store())
		{
			$this->setError($table->getError());

			return false;
		}

		return array('id' => $table->id, 'number' => $data['order_number']);
	}

	/**
	 * Method to set order to Paid status.
	 *
	 * @param   integer  $orderId        Order ID.
	 * @param   string   $transactionId  Transaction ID from payment gateway.
	 *
	 * @return  boolean
	 *
	 * @since   1.0.0
	 */
	public function updatePaidOrder($orderId, $transactionId)
	{
		$db = $this->getDbo();
		$query = $db->getQuery(true)
			->update($db->qn('#__cmgiftcard_orders'))
			->set($db->qn('order_status') . ' = ' . $db->q('paid'))
			->set($db->qn('transaction_id') . ' = ' . $db->q($transactionId))
			->set($db->qn('completed') . ' = ' . $db->q(Factory::getDate()->toSql()))
			->where($db->qn('id') . ' = ' . $db->q((int) $orderId));

		return $db->setQuery($query)->execute();
	}

	/**
	 * Get an order.
	 *
	 * @param   integer  $pk  Order ID.
	 *
	 * @return  mixed
	 *
	 * @since   2.0.0-alpha1
	 */
	public function getItem($pk = null)
	{
		return $this->getOrder($pk);
	}

	/**
	 * Get an order.
	 *
	 * @param   integer  $orderId  Order ID.
	 *
	 * @return  mixed
	 *
	 * @since   1.0.0
	 */
	public function getOrder($orderId = null)
	{
		$orderName = ($orderId === null) ?  Factory::getApplication()->input->get('order', '') : '';

		$db = Factory::getDbo();

		$amountSubQuery = $db->getQuery(true)
			->select('SUM(' . $db->qn('c.amount') . ')')
			->from($db->qn('#__cmgiftcard_cards') . ' AS c')
			->where($db->qn('c.order_id') . ' = ' . $db->qn('a.id'));

		$cardSubQuery = $db->getQuery(true)
			->select('COUNT(' . $db->qn('gc.id') . ')')
			->from($db->qn('#__cmgiftcard_cards') . ' AS gc')
			->where($db->qn('gc.order_id') . ' = ' . $db->qn('a.id'));

		$query = $db->getQuery(true)
			->select('a.*')
			->select('(' . $amountSubQuery->__toString() . ') as amount')
			->select('(' . $cardSubQuery->__toString() . ') as card_quantity')
			->from($db->qn('#__cmgiftcard_orders') . ' AS a')
			->where($db->qn('user_id') . ' = ' . $db->q(Factory::getUser()->id));

		if ($orderId !== null)
		{
			$query->where($db->qn('a.id') . ' = ' . $db->q((int) $orderId));
		}
		elseif ($orderId === null && $orderName != '')
		{
			$query->where($db->qn('a.order_number') . ' = ' . $db->q($orderName));
		}
		else
		{
			$query->where($db->qn('a.id') . ' = ' . $db->q(-1));
		}

		$item = $db->setQuery($query)->loadObject();

		if (isset($item->id))
		{
			$query->clear()
				->select(
					$db->qn(
						array(
							'c.order_id', 'c.card_code', 'c.design_id', 'c.amount', 'c.message',
							'c.from_name', 'c.to_name', 'c.to_email', 'c.to_address_1',
							'c.to_address_2', 'c.to_address_3', 'c.to_postal_box',
							'c.to_city', 'c.to_state', 'c.to_postal_code', 'c.to_country',
							'c.deliver_date', 'c.delivered'
						)
					)
				)
				->select($db->qn('d.card_type'))
				->from($db->qn('#__cmgiftcard_cards', 'c'))
				->where($db->qn('c.order_id') . ' = ' . $db->q($item->id))
				->join('LEFT', $db->qn('#__cmgiftcard_designs', 'd') . ' ON ' .
					$db->qn('d.id') . ' = ' . $db->qn('c.design_id')
				);

			$item->cards = $db->setQuery($query)->loadObjectList();
		}

		return $item;
	}
}
