<?php
/**
 * @package    Essentials for VirtueMart
 * @author     Abhishek Das <info@virtueplanet.com>
 * @copyright  Copyright (C) 2012-2024 VirtuePlanet Services LLP. All rights reserved.
 * @license    GNU General Public License version 2 or later; see LICENSE.txt
 * @link       https://www.virtueplanet.com
 */

defined('_JEXEC') or die;

/**
 * Wishlist backend model.
 *
 * @since  1.6
 */
class VMEssentialsModelItems extends JModelList
{
/**
	* Constructor.
	*
	* @param   array  $config  An optional associative array of configuration settings.
	*
	* @see        JController
	* @since      1.6
	*/
	public function __construct($config = array())
	{
		if (empty($config['filter_fields']))
		{
			$config['filter_fields'] = array(
				'id', 'a.id',
				'user_id', 'a.user_id',
				'group', 'stock',
				'virtuemart_product_id', 'p.virtuemart_product_id',
				'user_name', 'u.name',
				'product_name', 'l.product_name',
				'state', 'a.state',
				'vendor_name', 'v.vendor_name',
				'virtuemart_vendor_id', 'v.virtuemart_vendor_id',
				'count', 'COUNT(a.id)',
				'product_stock',
				'user',
				'group',
				'virtuemart_vendor_id',
				'stock',
				'created_by', 'a.created_by',
				'modified_by', 'a.modified_by',
				'datetime', 'a.datetime',
			);
		}

		parent::__construct($config);
	}

	/**
	 * Method to auto-populate the model state.
	 *
	 * Note. Calling getState in this method will result in recursion.
	 *
	 * @param   string  $ordering   Elements order
	 * @param   string  $direction  Order direction
	 *
	 * @return void
	 *
	 * @throws Exception
	 */
	protected function populateState($ordering = null, $direction = null)
	{
		// Initialise variables.
		$app = JFactory::getApplication('administrator');

		$search = $app->getUserStateFromRequest($this->context . '.filter.search', 'filter_search');
		$this->setState('filter.search', $search);
		
		$user = $app->getUserStateFromRequest($this->context . '.filter.user', 'filter_user');
		$this->setState('filter.user', $user);
		
		$user = $app->getUserStateFromRequest($this->context . '.filter.virtuemart_vendor_id', 'filter_virtuemart_vendor_id');
		$this->setState('filter.virtuemart_vendor_id', $user);

		$stock = $app->getUserStateFromRequest($this->context . '.filter.stock', 'filter_stock', '');
		$this->setState('filter.stock', $stock);

		$group = $app->getUserStateFromRequest($this->context . '.filter.group', 'filter_group', '');
		$this->setState('filter.group', $group);

		// Load the parameters.
		$params = JComponentHelper::getParams('com_vmessentials');
		$this->setState('params', $params);

		// List state information.
		parent::populateState('a.datetime', 'asc');
	}

	/**
	 * Get the filter form
	 *
	 * @param   array    $data      data
	 * @param   boolean  $loadData  load current data
	 *
	 * @return  JForm|boolean  The JForm object or false on error
	 *
	 * @since   3.2
	 */
	public function getFilterForm($data = array(), $loadData = true)
	{
		$form = parent::getFilterForm($data, $loadData);
		
		if (!empty($form))
		{
			$group = $this->getState('filter.group');
			
			if (!empty($group))
			{
				$form->removeField('user', 'filter');
			}
		}
		
		return $form;
	}

	/**
	 * Method to get a store id based on model configuration state.
	 *
	 * This is necessary because the model is used by the component and
	 * different modules that might need different sets of data or different
	 * ordering requirements.
	 *
	 * @param   string  $id  A prefix for the store id.
	 *
	 * @return   string A store id.
	 *
	 * @since    1.6
	 */
	protected function getStoreId($id = '')
	{
		// Compile the store id.
		$id .= ':' . $this->getState('filter.search');
		$id .= ':' . $this->getState('filter.user');
		$id .= ':' . $this->getState('filter.virtuemart_vendor_id');
		$id .= ':' . $this->getState('filter.stock');
		$id .= ':' . $this->getState('filter.group');

		return parent::getStoreId($id);
	}

	/**
	 * Build an SQL query to load the list data.
	 *
	 * @return   JDatabaseQuery
	 *
	 * @since    1.6
	 */
	protected function getListQuery()
	{
		// Create a new query object.
		$db    = $this->getDbo();
		$query = $db->getQuery(true);

		// Select the required fields from the table.
		$query->select(
			$this->getState(
				'list.select', 'a.id, a.user_id, a.created_by, a.datetime'
			)
		);
		
		$query->from('#__vmessentials_wishlist AS a');
		
		$query->select('p.virtuemart_product_id, p.virtuemart_vendor_id, (p.product_in_stock - p.product_ordered) AS product_stock');
		$query->join('INNER', '#__virtuemart_products AS p ON p.virtuemart_product_id = a.virtuemart_product_id');
		
		$langFback  = (!VmConfig::get('prodOnlyWLang', false) && VmConfig::$defaultLang != VmConfig::$vmlang && VmConfig::$langCount > 1);
		$selectLang = '';
		$method     = 'INNER';
		$useJLback  = false;
		
		$search = $this->getState('filter.search');
		
		if (!empty($search) && stripos($search, 'id:') === 0)
		{
			$query->where('p.virtuemart_product_id = ' . (int) substr($search, 3));
			$search = '';
		}
		
		if ($langFback)
		{
			if (VmConfig::$defaultLang != VmConfig::$jDefLang)
			{
				$query->join($method, '#__virtuemart_products_' . VmConfig::$jDefLang . ' as ljd ON ON ljd.virtuemart_product_id = p.virtuemart_product_id');
				$method = 'LEFT';
				$useJLback = true;
			}
			
			$query->join($method, '#__virtuemart_products_' . VmConfig::$defaultLang . ' as ld ON ld.virtuemart_product_id = p.virtuemart_product_id');
			$query->join('LEFT', '#__virtuemart_products_' . VmConfig::$vmlang . ' as l ON l.virtuemart_product_id = p.virtuemart_product_id');
			
			$expr = 'ld.product_name';
			
			if ($useJLback)
			{
				$expr = 'IFNULL(ld.product_name, ljd.product_name)';
				
				if (!empty($search))
				{
					$query->where('(' . 'l.product_name LIKE ' . $db->quote('%' . $search . '%') . ' OR ld.product_name LIKE ' . $db->quote('%' . $search . '%') . ' OR ljd.product_name LIKE ' . $db->quote('%' . $search . '%') .')');
				}
			}
			else
			{
				if (!empty($search))
				{
					$query->where('(l.product_name LIKE ' . $db->quote('%' . $search . '%') . ' OR ld.product_name LIKE ' . $db->quote('%' . $search . '%') . ')');
				}
			}
				
			$query->select('IFNULL(l.product_name, ' . $expr . ') as product_name');
		}
		else
		{
			$query->select('l.product_name');
			$query->join('INNER', '#__virtuemart_products_' . VmConfig::$vmlang . ' as l ON l.virtuemart_product_id = p.virtuemart_product_id');
			
			if (!empty($search))
			{
				$query->where('l.product_name LIKE ' . $db->quote('%' . $search . '%'));
			}
		}

		// Join over the user field 'user_id'
		$query->select('u.name AS user_name');
		$query->join('INNER', '#__users AS u ON u.id = a.user_id');

		// Join over the user field 'created_by'
		$query->select('cu.name AS created_by_name');
		$query->join('LEFT', '#__users AS cu ON cu.id = a.created_by');
		
		$query->select('v.vendor_name');
		$query->join('LEFT', '#__virtuemart_vendors AS v ON v.virtuemart_vendor_id = p.virtuemart_vendor_id');
		
		// Filter by vendor
		$vendor = $this->getState('filter.virtuemart_vendor_id');
		
		if (!empty($vendor))
		{
			$query->where('p.virtuemart_vendor_id = ' . (int) $vendor);
		}
		
		// Group by products
		$group = $this->getState('filter.group');
		
		if (!empty($group))
		{
			$query->group('p.virtuemart_product_id');
			$query->select('COUNT(a.id) AS count');
		}
		else
		{
			// Filter by User
			$filterUser = $this->getState('filter.user');
			
			if (!empty($filterUser))
			{
				if (stripos($filterUser, 'id:') === 0)
				{
					$query->where('u.id = ' . (int) substr($filterUser, 3));
				}
				else
				{
					$query->where('(u.username LIKE ' . $db->quote('%' . $filterUser . '%') . ' OR u.name LIKE ' . $db->quote('%' . $filterUser . '%') . ')');
				}
			}
		}
		
		// Filter by stock
		$stock = $this->getState('filter.stock');

		if ($stock !== '' && $stock !== null)
		{
			if ($stock == '1')
			{
				$query->where('(p.product_in_stock - p.product_ordered) > 0');
			}
			else
			{
				$query->where('(p.product_in_stock - p.product_ordered) <= 0');
			}
		}

		// Add the list ordering clause.
		$orderCol  = $this->state->get('list.ordering');
		$orderDirn = $this->state->get('list.direction');

		if ($orderCol && $orderDirn)
		{
			$query->order($db->escape($orderCol . ' ' . $orderDirn));
		}

		return $query;
	}
	
	public function delete(&$pks, $by_product)
	{
		$pks = (array) $pks;
		$table = $this->getTable();
		
		if ($by_product)
		{
			$db = $this->getDbo();
			$query = $db->getQuery(true);
			
			$query->select('id')
				->from('#__vmessentials_wishlist')
				->where('virtuemart_product_id IN (' . implode(',', array_map('intval', $pks)) . ')');
			$db->setQuery($query);
			$pks = $db->loadColumn();
			
			if (empty($pks))
			{
				$this->setError('Wishlist ID not found.');
				return false;
			}
		}
		
		foreach ($pks as $i => $pk)
		{
			if ($table->load($pk))
			{
				if (!$table->delete($pk))
				{
					$this->setError($table->getError());
					return false;
				}
			}
			else
			{
				$this->setError($table->getError());
				return false;
			}
		}
		
		// Clear the component's cache
		$this->cleanCache();
		return true;
	}
	
	public function getTable($name = 'Wishlist', $prefix = 'VMEssentialsTable', $options = array())
	{
		return parent::getTable($name, $prefix, $options);
	}

	/**
	 * Get an array of data items
	 *
	 * @return mixed Array of data items on success, false on failure.
	 */
	public function getItems()
	{
		$items = parent::getItems();

		return $items;
	}
	
	public function getAllItems()
	{
		$db    = $this->getDbo();
		$query = $this->getListQuery();

		try
		{
			$db->setQuery($query);
			$data = $db->loadAssocList();
		} 
		catch (Exception $e)
		{
			$this->setError($e->getMessage());
			return false;
		}
		
		return $data;
	}
}
