<?php

/**
 * @package     Joomla.Administrator
 * @subpackage  com_formea
 *
 * @copyright   Copyright (C) 2010-2025 Feseur Sdn Bhd. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 * @version     1.3.0
 */

namespace Joomla\Component\Formea\Administrator\Model;

defined('_JEXEC') or die;

use Joomla\CMS\Application\CMSApplicationInterface;
use Joomla\CMS\Factory;
use Joomla\CMS\MVC\Model\ListModel;
use Joomla\Database\DatabaseDriver;
use Joomla\Database\DatabaseQuery;
use RuntimeException;

/**
 * Methods supporting a list of formea records.
 *
 * @since  1.0
 */
class SubmissionsModel extends ListModel
{
	/**
	 * @var CMSApplicationInterface|null
	 * @since 1.0.0
	 */
	protected $app;

	/**
	 * Constructor.
	 *
	 * @param   array  $config  An optional associative array of configuration settings.
	 *
	 * @see     \JControllerLegacy
	 * @since   1.0
	 */
	public function __construct($config = [])
	{
		if (empty($config['filter_fields'])) {
			$config['filter_fields'] = [
				'id',
				'a.id',
				'form_id',
				'a.form_id',
				'user_id',
				'a.user_id',
				'language',
				'a.language',
				'ip_address',
				'a.ip_address',
				'state',
				'a.state',
				'checked_out',
				'a.checked_out',
				'checked_out_time',
				'a.checked_out_time',
				'publish_up',
				'a.publish_up',
				'publish_down',
				'a.publish_down',
				'created_date',
				'a.created_date',
				'created_by',
				'a.created_by',
				'modified_date',
				'a.modified_date',
				'modified_by',
				'a.modified_by',
				'user_email_sent',
				'a.user_email_sent',
				'user_email',
				'a.user_email',
				'admin_email_sent',
				'a.admin_email_sent',
				'admin_email',
				'a.admin_email',
			];
		}

		parent::__construct($config);
		$this->app = Factory::getApplication();
	}

	/**
	 * Method to get a DatabaseQuery object for retrieving the data set from a database.
	 *
	 * @return  DatabaseQuery  A DatabaseQuery object to retrieve the data set.
	 *
	 * @since   1.6
	 */
	protected function getListQuery()
	{
		$columns = [
			'a.id',
			'a.form_id',
			'a.user_id',
			'a.language',
			'a.ip_address',
			'a.state',
			'a.checked_out',
			'a.checked_out_time',
			'a.publish_up',
			'a.publish_down',
			'a.created_date',
			'a.created_by',
			'a.modified_date',
			'a.modified_by',
			'a.user_email_sent',
			'a.user_email',
			'a.admin_email_sent',
			'a.admin_email'
		];
		// Create a new query object.
		$db    = $this->getDatabase();
		$query = $db->getQuery(true);

		// Select the required fields from the table.
		$query->select(
			$db->quoteName(
				explode(
					', ',
					$this->getState(
						'list.select',
						implode(', ', $columns)
					)
				)
			)
		);
		$query->select(['b.title AS form_title']);
		$query->from($db->quoteName('#__formea_submissions', 'a'));
		$query->join(
			'INNER',
			$db->quoteName('#__formea_forms', 'b') . ' ON ' .
				$db->quoteName('a.form_id') . ' = ' . $db->quoteName('b.id')
		);

		//_users

		// Join over the users for the registered user.
		$query->select($db->quoteName('ru.name', 'registered_submitter'))
			->join(
				'LEFT',
				$db->quoteName('#__users', 'ru') . ' ON ' . $db->quoteName('ru.id') . ' = ' . $db->quoteName('a.user_id')
			);

		// Join over the users for the checked out user.
		$query->select($db->quoteName('uc.name', 'editor'))
			->join(
				'LEFT',
				$db->quoteName('#__users', 'uc') . ' ON ' . $db->quoteName('uc.id') . ' = ' . $db->quoteName('a.checked_out')
			);

		// Filter by published state
		$published = (string) $this->getState('filter.published');
		if (is_numeric($published)) {
			$query->where($db->quoteName('a.state') . ' = ' . (int) $published);
		} elseif ($published === '') {
			$query->where('(' . $db->quoteName('a.state') . ' = 0 OR ' . $db->quoteName('a.state') . ' = 1)');
		}


		// Filter by search in name.
		$search = $this->getState('filter.search');

		if (!empty($search)) {
			if (stripos($search, 'id:') === 0) {
				$query->where('a.id = ' . (int) substr($search, 3));
			} else {
				$search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%'));
				$query->where(
					'(' . $db->quoteName('a.name') . ' LIKE ' . $search . ')'
				);
			}
		}

		//filter by form id
		$form_id = (int)$this->getState('filter.form_id');
		if ($form_id > 0) {
			$query->where($db->quoteName('a.form_id') . ' = ' . $db->quote($form_id));
		}


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

		$query->order($db->escape($orderCol . ' ' . $orderDirn));

		return $query;
	}

	/**
	 * Method to autopopulate 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
	 */
	protected function populateState($ordering = 'a.id', $direction = 'desc')
	{
		$app = Factory::getApplication();

		$forcedLanguage = $app->input->get('forcedLanguage', '', 'cmd');

		// Adjust the context to support modal layouts.
		if ($layout = $app->input->get('layout')) {
			$this->context .= '.' . $layout;
		}

		// Adjust the context to support forced languages.
		if ($forcedLanguage) {
			$this->context .= '.' . $forcedLanguage;
		}

		// List state information.
		parent::populateState($ordering, $direction);

		// Force a language.
		if (!empty($forcedLanguage)) {
			$this->setState('filter.language', $forcedLanguage);
		}
	}

	public function getItems()
	{
		// Get a storage key.
		$store = $this->getStoreId();

		// Try to load the data from internal storage.
		if (isset($this->cache[$store])) {
			return $this->cache[$store];
		}

		try {
			// Load the list items and add the items to the internal cache.
			$items = $this->_getList($this->_getListQuery(), $this->getStart(), $this->getState('list.limit'));
			if (!empty($items)) {
				$totalItems = count($items);
				for ($i = 0; $i < $totalItems; $i++) {
					$items[$i]->submitted_data = [];
					$formId                    = $this->state->get('filter.form_id', 0);
					if ($formId > 0) {
						/** @var DatabaseDriver $db */
						$db    = $this->getDatabase();
						$query = $db->getQuery(true);
						$query->select([
							'a.field_id',
							'a.field_name',
							'a.field_text',
							'a.field_caption',
							'a.field_value',
							'a.is_link',
							'a.link_path'
						]);
						$query->from($db->quoteName('#__formea_submission_data', 'a'));
						$query->where($db->quoteName('a.form_id') . ' = ' . $db->quote($formId));
						$query->where($db->quoteName('a.submission_id') . ' = ' . $db->quote($items[$i]->id));
						$db->setQuery($query);
						$results = $db->loadObjectList('field_id');
						if (!empty($results)) {
							$items[$i]->submitted_data = $results;
						}
					}
				}
			}
			$this->cache[$store] = $items;
		} catch (RuntimeException $e) {
			//	var_dump($e->getMessage());
			$this->app->enqueueMessage($e->getMessage(), 'error');

			return false;
		}

		return $this->cache[$store];
	}
}
