<?php

/**
 * @package com_spbooking
 * @author JoomShaper http://www.joomshaper.com
 * @copyright Copyright (c) 2010 - 2023 JoomShaper
 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or later
 */

// No Direct Access
defined ('_JEXEC') or die('Resticted Aceess');

use Joomla\CMS\Factory;
use Joomla\CMS\MVC\Model\ListModel;
use Joomla\CMS\Language\Multilanguage;
use Joomla\CMS\Component\ComponentHelper;

jimport( 'joomla.application.component.helper' );

class SpbookingModelAccomodations extends ListModel {

	protected function populateState($ordering = null, $direction = null) {
		$app = Factory::getApplication('site');
		$this->setState('list.start', $app->input->get('limitstart', 0, 'uint'));
		$this->setState('filter.language', Multilanguage::isEnabled());
		$cParams = ComponentHelper::getParams('com_spbooking');
		$limit = $cParams->get('accomodations_limit', 6);
		$this->setState('list.limit', $limit);
	}

	protected function getListQuery() {

		$input = Factory::getApplication()->input;
		$location 	= $input->get('destination', '', 'STRING');
		$min_price 	= $input->get('min-price', 0, 'INT');
		$max_price 	= $input->get('max-price', 0, 'INT');
		$facilities = $input->get('facilities', '', 'STRING');
		$tags 		= $input->get('tags', '', 'STRING');
		$aid 		= $input->get('accomodation', '', 'INT');
		$city		= $input->get('city', '', 'STRING');
		$country 	= $input->get('country', '', 'STRING');
		$state	 	= $input->get('state', '', 'STRING');
		$checkin 	= $input->get('checkin', '', 'STRING');
		$checkout 	= $input->get('checkout', '', 'STRING');
		$rooms 		= $input->get('rooms', 1, 'INT');
		$adult 		= $input->get('adult', 1, 'INT');
		$child 		= $input->get('child', 0, 'INT');

		$db = $this->getDbo();
		$query = $db->getQuery(true);
		$query->select('a.*, b.title as category_title');
		$query->from($db->quoteName('#__spbooking_accomodations', 'a'));
		$query->join('LEFT', $db->quoteName('#__spbooking_categories', 'b') . ' ON (' . $db->quoteName('a.category_id') . ' = ' . $db->quoteName('b.id') . ')');
		
		$conditions = array();

		
		// filter by accomodation id
		if (!empty($aid)) {
			$conditions[] = $db->quoteName('a.id') . ' = ' . $db->quote($aid);
		}

		// filter by price range
		if (isset($min_price) && isset($max_price) && $max_price != 0) {
			$ids = $this->getAccomodationsWithinPriceRange($min_price, $max_price);
			
			if (!empty($ids)) {
				$conditions[] = $db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')';
			} else {
				$conditions[] = $db->quoteName('a.id') . ' = 0';
			}
		}

		// filter by city
		if (!empty($city)) {
			$conditions[] = $db->quoteName('a.city') . ' = ' . $db->quote(base64_decode($city));
		}
		
		// filter by country
		if (!empty($country)) {
			$conditions[] = $db->quoteName('a.country') . ' = ' . $db->quote(base64_decode($country));
		}
		
		// filter by state
		if (!empty($state)) {
			$conditions[] = $db->quoteName('a.state') . ' = ' . $db->quote(base64_decode($state));
		}

		// filter by checkin checkout
		if (!empty($checkin) && !empty($checkout)) {
			$aids = SpbookingHelper::getAvailableRooms($checkin, $checkout, $aid, $rooms, $adult, $child, $country, $city, 1);
			
			if (!empty($aids)) {
				$conditions[] = $db->quoteName('a.id') . ' IN (' . implode(',', $aids) . ')';
			}
		}

		// If search by city or country
		if (!empty($location)) {
			$location = explode(" ", trim($location));
			$location = implode('|', $location);
			$conditions[] = "(" . $db->quoteName('a.city') . ' REGEXP ' . $db->quote($location) . ' OR ' .  
			$db->quoteName('a.country') . ' REGEXP ' . $db->quote($location) . ")";
		}

		// If filter by facilities
		if(!empty($facilities)) {
			$facilities = explode(',', $facilities);
			$facility_ids = implode(' OR ', array_map(function ($entry) use($db) {
				return $db->quoteName('a.extra_features') . " LIKE '%\"" . $entry . "\"%'";
			}, $facilities));
			$conditions[] = $facility_ids;
		}

		// If filtered by tags
		if (!empty($tags)) {
			$tags = explode(',', $tags);
			$tag_ids = implode(' OR ', array_map(function($tag) use($db) {
				return $db->quoteName('a.accomodation_tags') . " LIKE '%\"" . $tag . "\"%'";
			}, $tags));
			$conditions[] = $tag_ids;
		}

		$conditions[] = $db->quoteName('a.published') . ' = ' . $db->quote('1');
		$query->where($conditions);
		
        if ($this->getState('filter.language')) {
            $query->where($db->quoteName('a.language') . ' IN (' . $db->quote(Factory::getLanguage()->getTag()) . ',' . $db->quote('*') . ')');
		}
		
		return $query;
	}

	private function getAccomodationsWithinPriceRange($min_price, $max_price) {
		$aids = array();
		$min_price = (int)$min_price;
		$max_price = (int)$max_price;

		$db = Factory::getDbo();
		$query = $db->getQuery(true);
		$query->select('id, accomodation_id, price')
		->from($db->quoteName('#__spbooking_rooms'))
		->where($db->quoteName('published') . ' = 1');
		
		// language filter
		if ($this->getState('filter.language')) {
            $query->where($db->quoteName('language') . ' IN (' . $db->quote(Factory::getLanguage()->getTag()) . ',' . $db->quote('*') . ')');
		}
		
		$db->setQuery($query);
		$rooms = $db->loadObjectList();
		
		if (!empty($rooms)) {
			foreach($rooms as $room) {
				if (!empty($room->price) && is_string($room->price)) {
					$price = json_decode($room->price, true);
					$min = min($price);
					$max = max($price);
					
					if ($min >= $min_price && $min <= $max_price) {
						if (!in_array($room->accomodation_id, $aids)) {
							$aids[] = $room->accomodation_id;
						}
					}
				}
			}
		}
		return $aids;
	}

	public function getKeywordSearchInfo($input, $type = 'aid', $search_for = 'accomodation') {
		$output = '';
		if (empty($input)) {
			return $output;
		}

		$db = Factory::getDbo();
		$query = $db->getQuery(true);
		if ($search_for == 'accomodation') {
			$query->select('id, title, city, country, state')
			->from($db->quoteName('#__spbooking_accomodations'));
		} else if ($search_for == 'package') {
			$query->select('id, title, city, country, state')
			->from($db->quoteName('#__spbooking_packages'));
		} else if ($search_for == 'transport') {
			$query->select('id, title, city, country, state')
			->from($db->quoteName('#__spbooking_transports'));
		} else if ($search_for == 'place') {
			$query->select('id, title, city, country, state')
			->from($db->quoteName('#__spbooking_places'));
		}

		if ($type == 'aid') {
			$query->where($db->quoteName('id') . ' = ' . $db->quote($input));
		} else if ($type == 'city') {
			$query->where($db->quoteName('city') . ' = ' . $db->quote($input));
		} else if ($type == 'state') {
			$query->where($db->quoteName('state') . ' = ' . $db->quote($input));
		}

		// language filter
		if ($this->getState('filter.language')) {
            $query->where($db->quoteName('language') . ' IN (' . $db->quote(Factory::getLanguage()->getTag()) . ',' . $db->quote('*') . ')');
		}

		$db->setQuery($query);

		$result = $db->loadObject();
		if (!empty($result)) {
			if ($type == 'aid') {
				$output = $result->title . ', ' . $result->city . ', ' . $result->country;
			} else if ($type == 'city') {
				$output = $result->city . ', ' . $result->country;
			} else if ($type == 'state') {
				$output = $result->state . ', ' . $result->country;
			}
			return $output;
		}
		return '';
	}

	
}
    
