<?php
/**
 * @version        4.3.0
 * @package        Joomla
 * @subpackage     Helpdesk Pro
 * @author         Tuan Pham Ngoc
 * @copyright      Copyright (C) 2013 - 2021 Ossolution Team
 * @license        GNU/GPL, see LICENSE.php
 */

namespace OSSolution\HelpdeskPro\Admin\Model;

use Joomla\Utilities\ArrayHelper;
use OSL\Container\Container;
use OSL\Model\ListModel;
use OSSolution\HelpdeskPro\Site\Helper\Helper as HelpdeskproHelper;

defined('_JEXEC') or die;

class Tickets extends ListModel
{
	/**
	 * Constructor.
	 *
	 * @param   Container  $container
	 * @param   array      $config
	 */
	public function __construct(Container $container, $config = array())
	{
		$config['search_fields'] = array('tbl.id', 'tbl.name', 'tbl.email', 'c.username', 'tbl.subject', 'tbl.message');

		$config['remember_states'] = true;

		parent::__construct($container, $config);

		$this->state->insert('filter_category_id', 'int', 0)
			->insert('filter_manager_id', 'int', 0)
			->insert('filter_status_id', 'int', -1)
			->insert('filter_priority_id', 'int', 0)
			->insert('filter_staff_id', 'int', 0)
			->insert('filter_label_id', 'int', 0)
			->setDefault('filter_order', 'tbl.modified_date')
			->setDefault('filter_order_Dir', 'DESC')
			->setDefault('published', -1);

		// Support searching for tickets from configured custom fields
		$db    = $this->getDbo();
		$query = $db->getQuery(true);
		$query->select('name')
			->from('#__helpdeskpro_fields')
			->where('published = 1')
			->where('is_searchable = 1');
		$db->setQuery($query);
		$searchableFields = $db->loadColumn();

		foreach ($searchableFields as $field)
		{
			$field = 'tbl.' . $field;

			if (!in_array($field, $this->searchFields))
			{
				$this->searchFields[] = $field;
			}
		}
	}

	/**
	 * Build the query object which is used to get list of records from database
	 *
	 * @return \JDatabaseQuery
	 */
	protected function buildListQuery()
	{
		$query = parent::buildListQuery();

		$user = $this->container->user;

		$state = $this->getState();

		$config = HelpdeskproHelper::getConfig();

		$role               = HelpdeskproHelper::getUserRole($user->id);
		$managedCategoryIds = HelpdeskproHelper::getTicketCategoryIds($user->get('username'));


		if ($this->container->app->isClient('site') && $fieldSuffix = HelpdeskproHelper::getFieldSuffix())
		{
			$query->select($this->getDbo()->quoteName('b.title' . $fieldSuffix, 'category_title'));
		}
		else
		{
			$query->select('b.title AS category_title');
		}

		// Join with other tables
		$query->select('c.username')
			->select('d.title AS label_title, d.color_code')
			->leftJoin('#__helpdeskpro_categories AS b ON tbl.category_id= b.id ')
			->leftJoin('#__users AS c ON tbl.user_id = c.id')
			->leftJoin('#__helpdeskpro_labels AS d ON tbl.label_id = d.id');

		if ($state->filter_category_id)
		{
			$query->where('tbl.category_id = ' . (int) $state->filter_category_id);
		}

		if ($state->filter_status_id)
		{
			if ($state->filter_status_id == -1)
			{
				if ($role == 'admin' || $role == 'manager' || $role == 'staff')
				{
					$statusIds = [];

					//Show open and pending tickets to admins, managers and staffs by default
					if (trim($config->manager_default_status_filters))
					{
						$statusIds = array_filter(ArrayHelper::toInteger(explode(',', $config->manager_default_status_filters)));
					}

					if (empty($statusIds))
					{
						$statusIds = [(int) $config->new_ticket_status_id, (int) $config->ticket_status_when_customer_add_comment];
					}

					$query->where('tbl.status_id IN (' . implode(',', $statusIds) . ')');
				}
				else
				{
					//Show open tickets and require feedback tickets to customers
					$query->where('tbl.status_id != ' . (int) $config->closed_ticket_status);
				}
			}
			else
			{
				$query->where('tbl.status_id = ' . (int) $state->filter_status_id);
			}
		}

		if ($state->filter_priority_id)
		{
			$query->where('tbl.priority_id = ' . $state->filter_priority_id);
		}

		if ($state->filter_label_id)
		{
			$query->where('tbl.label_id = ' . $state->filter_label_id);
		}

		if ($state->filter_staff_id)
		{
			$query->where('tbl.staff_id=' . $state->filter_staff_id);
		}

		if ($role == 'manager')
		{
			$query->where('(tbl.category_id IN (' . implode(',', $managedCategoryIds) . ') OR tbl.staff_id = ' . $user->id . ')');
		}
		elseif ($role == 'staff')
		{
			$query->where(' tbl.staff_id=' . $user->id);
		}
		elseif ($role == 'user')
		{
			$userId = $user->id;
			$email  = $user->get('email');
			$query->where("(tbl.user_id=$userId OR tbl.email='$email')");
		}


		return $query;
	}

	/**
	 * Build the query object which is used to get total records from database
	 *
	 * @return \JDatabaseQuery
	 */
	protected function buildTotalQuery()
	{
		$query = parent::buildTotalQuery();

		$query->leftJoin('#__users AS c ON tbl.user_id = c.id');

		return $query;
	}

	/**
	 * Get profile custom fields data
	 *
	 * @param   array  $fields
	 *
	 * @return array
	 */
	public function getFieldsData($fields)
	{
		$fieldsData = array();
		$rows       = $this->data;
		if (count($rows) && count($fields))
		{
			$db    = $this->getDbo();
			$query = $db->getQuery(true);

			$ids = array();

			foreach ($rows as $row)
			{
				$ids[] = $row->id;
			}

			$fieldIds = array();

			foreach ($fields as $field)
			{
				$fieldIds[] = $field->id;
			}

			$query->select('*')
				->from('#__helpdeskpro_field_value')
				->where('ticket_id IN (' . implode(',', $ids) . ')')
				->where('field_id IN (' . implode(',', $fieldIds) . ')');
			$db->setQuery($query);
			$fieldValues = $db->loadObjectList();

			foreach ($fieldValues as $fieldValue)
			{
				$fieldsData[$fieldValue->ticket_id][$fieldValue->field_id] = $fieldValue->field_value;
			}
		}

		return $fieldsData;
	}
}