<?php

if (!defined("ROOT_PATH"))
{
	header("HTTP/1.1 403 Forbidden");
	exit;
}
class pjFrontPublic extends pjFront
{
	public function __construct()
	{
		parent::__construct();
		
		$this->setAjax(true);
		
		$this->setLayout('pjActionEmpty');
	}
	
	public function pjActionCart()
	{
		if ($this->isXHR() || $this->_get->check('_escaped_fragment_'))
		{
			$this->set('cart_arr', $this->getCart($this->getForeignId()));
		}
	}
	

	public function pjActionCheckout()
	{ 	
		// print_r($this->_post);
		// print_r($this->_get); die('po');
		if ($this->isXHR() || $this->_get->check('_escaped_fragment_'))
		{
			if ($this->cart->isEmpty())
			{
				$this->set('status', 'ERR');
				$this->set('code', '101'); //Empty cart
				return;
			}
			
			if ($this->_post->check('as_checkout'))
			{   
				$_SESSION[$this->defaultForm] = array_merge($_SESSION[$this->defaultForm], $this->_post->raw());
				self::jsonResponse(array('status' => 'OK', 'code' => 211, 'text' => __('system_211', true)));
			}
			
			if (in_array($this->option_arr['o_bf_country'], array(2,3)))
			{
				$this->set('country_arr', pjBaseCountryModel::factory()
					->select('t1.*, t2.content AS name')
					->join('pjMultiLang', "t2.model='pjBaseCountry' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
					->where('t1.status', 'T')
					->orderBy('`name` ASC')
					->findAll()
					->getData()
				);
			}
			
			$cart = $this->cart->getAll();
			$cart_arr = $this->getCart($this->getForeignId());
			// print_r($this->_post);
	
			if ($this->option_arr['o_allow_bank'] == '1')
			{
				$bank_account = pjMultiLangModel::factory()->select('t1.content')
				->where('t1.model','pjOption')
				->where('t1.locale', $this->getLocaleId())
				->where('t1.field', 'o_bank_account')
				->limit(1)
				->findAll()->getDataIndex(0);
				$this->set('bank_account', $bank_account['content']);
			}
			
			if(pjObject::getPlugin('pjPayments') !== NULL)
			{
				$this->set('payment_option_arr', pjPaymentOptionModel::factory()->getOptions(NULL));
				$this->set('payment_titles', pjPayments::getPaymentTitles($this->getForeignId(), $this->getLocaleId()));
			}
			else
			{
				$this->set('payment_titles', __('payment_methods', true));
			}
			
			if (isset($_SESSION[$this->defaultFilter]['subservices']) && count($_SESSION[$this->defaultFilter]['subservices']) > 0) {
				$this->set('subservice_arr', pjSubserviceModel::factory()
					->select('t1.*, t2.content AS `name`')
					->join('pjMultiLang', "t2.model='pjSubservice' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
					->where('t1.status', 'T')
					->whereIn('t1.id', $_SESSION[$this->defaultFilter]['subservices'])
					->orderBy('t2.content ASC')
					->findAll()
					->getData()
				);
			}
		
			$this->set('status', 'OK');
			$this->set('terms_arr', $this->getTerms($this->getForeignId()));
			$this->set('summary', $this->getSummary());
			$this->set('cart', $cart);
			$this->set('cart_arr', $cart_arr);
			
		}
	}
	
	public function pjActionService()
	{
		if ($this->isXHR() || $this->_get->check('_escaped_fragment_'))
		{
			$service_id = null;
			$employee_id = null;
			$date = date('Y-m-d');
				
			if($this->_get->check('date'))
			{
				$date = $this->_get->toString('date');
			}
			
			if ($this->_get->check('service_id') && $this->_get->toInt('service_id') > 0 && $this->_get->check('employee_id') && $this->_get->toInt('employee_id') > 0){
				$service_id = $this->_get->toInt('service_id');
				$employee_id = $this->_get->toInt('employee_id');
			}elseif ($this->_get->check('service_id') && $this->_get->toInt('service_id') > 0){
				$service_id = $this->_get->toInt('service_id');
			}elseif ($this->_get->check('_escaped_fragment_')) {
				preg_match('/\/Service\/(\d+)/', $this->_get->toString('_escaped_fragment_'), $matches);
				if (isset($matches[1]))
				{
					$service_id = $matches[1];
				}
				preg_match('/\/Service\/(\d+)\/(\d+)/', $this->_get->toString('_escaped_fragment_'), $matches);
				if (isset($matches[1]))
				{
					$service_id = $matches[1];
				}
				if (isset($matches[2]))
				{
					$employee_id = $matches[2];
				}
			
				preg_match('@^/Service/[\w\-]+\-(\d+)\.html$@', $this->_get->toString('_escaped_fragment_'), $matches);
				if ($matches)
				{
					$service_id = $matches[1];
				}
			
				preg_match('@^/Service/\d{4}/\d{2}/\d{2}/[\w\-]+\-(\d+)/[\w\-]+\-(\d+)\.html$@', $this->_get->toString('_escaped_fragment_'), $matches);
				if ($matches)
				{
					$service_id = $matches[1];
					$employee_id = $matches[2];
				}
			}
			
			list($year, $month, $day) = explode("-", $this->_get->toString('date'));
			$dates = $this->getDates($this->getForeignId(), $year, $month);
			$this->set('calendar', $this->getCalendar($dates[0], $year, $month, $day));
			
			$_employee_arr = pjEmployeeModel::factory()
				->select("t1.*, t2.content AS `name`")
				->join('pjMultiLang', "t2.model='pjEmployee' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
				->where('t1.calendar_id', $this->getForeignId())
				->where("t1.id IN (SELECT TES.employee_id FROM `".pjEmployeeServiceModel::factory()->getTable()."` AS TES WHERE TES.service_id='".$service_id."') ")
				->where('t1.is_active', 'T')
				->orderBy('t1.order ASC, t2.content ASC')
				->findAll()
				->getData();
			$employee_arr = array();
			foreach($_employee_arr as $k => $v)
			{
				$app_info = pjAppController::getAppointmentInfo($v['id'], $service_id, $this->getForeignId(), $date, $this->getLocaleId(), $this->option_arr);
				if (!$app_info['employee']['t_arr'])
				{
					unset($_employee_arr[$k]);
				}else{
					$employee_arr[] = $v;
				}
			}
			if(count($employee_arr) == 1)
			{
				$employee_id = $employee_arr[0]['id'];
			}
			if($service_id != null && $employee_id != null)
			{
			    $app_info = pjAppController::getAppointmentInfo($employee_id, $service_id, $this->getForeignId(), $date, $this->getLocaleId(), $this->option_arr);
				$this->set('service', $app_info['service']);
				$this->set('employee', $app_info['employee']);
			}
			
			if ($this->cart->isEmpty())
			{
				$this->set('status', 'ERR');
				$this->set('code', '101');
			}
			
			$this->set('date', $date);
			
			$this
				->set('service_arr', pjServiceModel::factory()
					->select("t1.*, t2.content AS `name`, t3.content AS `description`")
					->join('pjMultiLang', "t2.model='pjService' AND t2.foreign_id=t1.id AND t2.locale='".$this->getLocaleId()."' AND t2.field='name'", 'left outer')
					->join('pjMultiLang', "t3.model='pjService' AND t3.foreign_id=t1.id AND t3.locale='".$this->getLocaleId()."' AND t3.field='description'", 'left outer')
					->where('t1.calendar_id', $this->getForeignId())
					->where('t1.is_active', 1)
					->where('t1.hide_on_frontend', 'F')
					->orderBy('`name` ASC')
					->findAll()
					->getData()
				)
				->set('employee_arr', $employee_arr)
				->set('cart_arr', $this->getCart($this->getForeignId()));
			
			if((int) $this->option_arr['o_booking_days_earlier'] > 0)
			{
				$today_ts = strtotime(date('Y-m-d 00:00:00', time()));
				$days_earlier = $this->option_arr['o_booking_days_earlier'] * 24 * 60 * 60;
				$ahead_ts = $today_ts + $days_earlier;
				$selected_ts = strtotime($this->_get->toString('date') . ' 00:00:00');
				
				if($selected_ts > $ahead_ts)
				{
					$this->set('unavailable', true);
				}
			}
		}
	}
	
	protected function getFilters() {
		$FILTER = isset($_SESSION[$this->defaultFilter]) ? $_SESSION[$this->defaultFilter] : array();
		
		if (isset($FILTER['gender']) && !empty($FILTER['gender'])) {
			$category_arr = pjCategoryModel::factory()->select("t1.*, t2.content AS name")
				->join('pjMultiLang', sprintf("t2.foreign_id = t1.id AND t2.model = 'pjCategory' AND t2.locale = '%u' AND t2.field = 'name'", $this->getLocaleId()), 'left')
				->where('t1.gender', $FILTER['gender'])
				->where('t1.status', 'T')
				->orderBy('t1.order ASC, t2.content ASC')
				->findAll()->getData();
			$this->set('category_arr', $category_arr);
		}
		
		if (isset($FILTER['gender']) && !empty($FILTER['gender']) && isset($FILTER['category']) && (int)$FILTER['category'] > 0) {
			$pjServiceModel = pjServiceModel::factory()
				->where('t1.id IN (SELECT `service_id` FROM `'.pjServiceCategoryModel::factory()->getTable().'` WHERE `category_id`='.(int)$FILTER['category'].')');
				
			$filter_service_arr = $pjServiceModel
				->select("t1.*, t2.content AS `name`, t3.content AS `description`")
				->join('pjMultiLang', "t2.model='pjService' AND t2.foreign_id=t1.id AND t2.locale='".$this->getLocaleId()."' AND t2.field='name'", 'left outer')
				->join('pjMultiLang', "t3.model='pjService' AND t3.foreign_id=t1.id AND t3.locale='".$this->getLocaleId()."' AND t3.field='description'", 'left outer')
				->where('t1.calendar_id', $this->getForeignId())
				->where('t1.is_active', 1)
				->where('t1.hide_on_frontend', 'F')
				->where('t1.gender', $FILTER['gender'])
				->orderBy('t1.order ASC, t2.content ASC')
				->findAll()
				->getData();
			$this->set('filter_service_arr', $filter_service_arr);
		}
		
		if (isset($FILTER['gender']) && !empty($FILTER['gender']) && isset($FILTER['services']) && count($FILTER['services']) > 0) {
			$pjEmployeeModel = pjEmployeeModel::factory(); 
			foreach ($FILTER['services'] as $service_id) {
				$pjEmployeeModel->where('t1.id IN (SELECT `employee_id` FROM `'.pjEmployeeServiceModel::factory()->getTable().'` WHERE `service_id`='.$service_id.')');
			}
			$filter_employee_arr = $pjEmployeeModel
				->select("t1.*, t2.content AS `name`")
				->join('pjMultiLang', "t2.model='pjEmployee' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
				->where('t1.calendar_id', $this->getForeignId())
				->where('t1.is_active', 'T')
				->where('t1.category', 'employee')
				->orderBy('t1.order ASC, t2.content ASC')
				->findAll()
				->getData();
			$this->set('filter_employee_arr', $filter_employee_arr);
			
			$this->set('filter_subservice_arr', pjSubserviceModel::factory()
				->select('t1.*, t2.content AS `name`')
				->join('pjMultiLang', "t2.model='pjSubservice' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
				->where('t1.status', 'T')
				->where('t1.id IN (SELECT `subservice_id` FROM `'.pjServiceSubserviceModel::factory()->getTable().'` WHERE `service_id` IN ('.implode(',', $FILTER['services']).'))')
				->orderBy('t2.content ASC')
				->findAll()
				->getData()
			);
		}
	}
	
	protected function getAvailableSlotPerDay0($date, $option_arr) {

		//$bookedSlot = pjBookingModel::factory()->whereIn('t1.date', $date)->findAll()->getData();
		//	$this->set('bookedSlot', $bookedSlot);
		//print_r($bookedSlot);	echo "bookedSlot";
		$available_slot_arr = array();
		// Define your time slots
		$slots = [
			"09:00 – 12:00",
			"14:00 – 17:00",
			"19:00 – 22:00",
			"09:00 – 17:00",
			"17:00 – 22:00"
		];
		// Convert time slots into timestamps
		foreach ($slots as $slot) {
			$timeParts = explode(" – ", $slot); // Split time range correctly
			if (count($timeParts) === 2) {
				$startTime = strtotime("$date " . trim($timeParts[0])); // Trim to remove extra spaces
				$endTime = strtotime("$date " . trim($timeParts[1]));
				$available_slot_arr[] = "$startTime|$endTime";
				
			}
		}
	
		return $available_slot_arr;
	}

	protected function getAvailableSlotPerDay10($date, $option_arr) 
	{
		// Fetch booked slots for the given date
		$bookedSlot = pjBookingModel::factory()->where('t1.date', $date)->findAll()->getData();
		$this->set('bookedSlot', $bookedSlot);
		
		$available_slot_arr = [];

			// Define time slots as a list of strings
			$slots = [
				"09:00 - 12:00",
				"14:00 - 17:00",
				"19:00 - 22:00",
				"09:00 - 17:00",
				"17:00 - 22:00"
			];

			//print_r($bookedSlot);

			// Extract booked slots into an array
			$bookedSlotsArr = [];
			foreach ($bookedSlot as $booking) {
				if (!empty($booking['booked_slot_id']) && is_string($booking['booked_slot_id'])) {
					$bookedSlotsArr[] = trim($booking['booked_slot_id']);
				}
			}

			// Check if "09:00 - 17:00" is booked
			$isFullDayBooked = in_array("09:00 - 17:00", $bookedSlotsArr);

			// Check if "17:00 - 22:00" is booked
			$isEveningBooked = in_array("17:00 - 22:00", $bookedSlotsArr);

			

			// Process each slot
			foreach ($slots as $slot) {
				if (!is_string($slot)) {
					continue; // Skip invalid entries
				}

				// Split the slot range correctly
				$timeParts = array_map('trim', explode("-", $slot));
				if (count($timeParts) === 2) {
					$startTime = strtotime("$date " . $timeParts[0]);
					$endTime = strtotime("$date " . $timeParts[1]);

					// Check if slot is booked
					$status = in_array($slot, $bookedSlotsArr) ? "booked" : "available";

					// If "09:00 - 17:00" is booked, also mark "09:00 - 12:00" and "14:00 - 17:00" as booked
					if ($isFullDayBooked && in_array($slot, ["09:00 - 12:00", "14:00 - 17:00"])) {
						$status = "booked";
					}

					// If "17:00 - 22:00" is booked, also mark "19:00 - 22:00" as booked
					if ($isEveningBooked && $slot === "19:00 - 22:00") {
						$status = "booked";
					}
						
					// Store slot data
					$available_slot_arr[] = [
						"slot" => $slot,
						"start_time" => $startTime,
						"end_time" => $endTime,
						"status" => $status
					];
				}
			}
		return $available_slot_arr;
	}

	protected function getAvailableSlotPerDay($date, $option_arr) 
	{
		$bookedSlot = pjBookingModel::factory()->where('t1.date', $date)->findAll()->getData();
		$this->set('bookedSlot', $bookedSlot);
		
		$available_slot_arr = [];
		
		$slots = [
			"09:00 - 12:00",
			"14:00 - 17:00",
			"19:00 - 22:00",
			"09:00 - 17:00",
			"17:00 - 22:00"
		];
		
		$bookedSlotsArr = [];
		foreach ($bookedSlot as $booking) {
			if (!empty($booking['booked_slot_id']) && is_string($booking['booked_slot_id'])) {
				$bookedSlotsArr[] = trim($booking['booked_slot_id']);
			}
		}
		
		// Individual slot bookings
		$isMorningBooked = in_array("09:00 - 12:00", $bookedSlotsArr);
		$isAfternoonBooked = in_array("14:00 - 17:00", $bookedSlotsArr);
		$isFullDayBooked = in_array("09:00 - 17:00", $bookedSlotsArr);
		$isEveningBooked = in_array("17:00 - 22:00", $bookedSlotsArr);
		$isNightBooked = in_array("19:00 - 22:00", $bookedSlotsArr);
	
		if ($isMorningBooked || $isAfternoonBooked) {
			$isFullDayBooked = true;
		}
	
		if ($isFullDayBooked && !$isMorningBooked && !$isAfternoonBooked) {
			$isMorningBooked = true;
			$isAfternoonBooked = true;
		}
	
		if ($isNightBooked) {
			$isEveningBooked = true;
		}
	
		if ($isEveningBooked) {
			$isNightBooked = true;
		}
	
		foreach ($slots as $slot) {
			if (!is_string($slot)) continue;
	
			$timeParts = array_map('trim', explode("-", $slot));
			if (count($timeParts) === 2) {
				$startTime = strtotime("$date " . $timeParts[0]);
				$endTime = strtotime("$date " . $timeParts[1]);
	
				$status = "available";
	
				if (
					($slot === "09:00 - 12:00" && $isMorningBooked) ||
					($slot === "14:00 - 17:00" && $isAfternoonBooked) ||
					($slot === "09:00 - 17:00" && ($isMorningBooked || $isAfternoonBooked || $isFullDayBooked)) ||
					($slot === "17:00 - 22:00" && $isEveningBooked) ||
					($slot === "19:00 - 22:00" && $isNightBooked)
				) {
					$status = "booked";
				}
	
				$available_slot_arr[] = [
					"slot" => $slot,
					"start_time" => $startTime,
					"end_time" => $endTime,
					"status" => $status
				];
			}
		}
		return $available_slot_arr;
	}
	
	protected function getAvailableSlotPerEmployee($employee_id, $date, $option_arr) {
		$FILTER = isset($_SESSION[$this->defaultFilter]) ? $_SESSION[$this->defaultFilter] : array();
		$service_arr = pjServiceModel::factory()
			->where('t1.calendar_id', $this->getForeignId())
			->where('t1.is_active', 1)
			->where('t1.hide_on_frontend', 'F')
			->whereIn('t1.id', $FILTER['services'])
			->orderBy('t1.order ASC')
			->findAll()
			->getData();
			
		$wt_arr = pjAppController::getWTimePerEmployee($employee_id, $this->getForeignId(), $option_arr, $date);
		$employee = pjEmployeeModel::factory()
			->find($employee_id)
			->getData();
		$employee['t_arr'] = $wt_arr['t_arr'];
		$employee['bs_arr'] = $wt_arr['bs_arr'];
		$available_slot_arr = $service_length_arr = array();
		if ($employee['t_arr'])
		{
			$service_available_slot_arr = array();
			$step = $option_arr['o_step'] * 60;
			$hour_earlier = $option_arr['o_booking_earlier'] * 60 * 60;
			# Fix for 24h support
			$offset = $employee['t_arr']['end_ts'] <= $employee['t_arr']['start_ts'] ? 86400 : 0;				
			foreach ($service_arr as $service) {
				$service_total = $service['total'] * 60;
				$service_length = $service['length'] * 60;
				$service_before = $service['before'] * 60;
				$service_length_arr[$service['id']] = $service_total - $service_before;
				for ($i = $employee['t_arr']['start_ts']; $i <= $employee['t_arr']['end_ts'] + $offset - $step; $i += $step)
				{
					$is_free = true;
					$allow_double_booking = true;
					foreach ($employee['bs_arr'] as $item) {
						if ($i >= $item['start_ts'] && $i < $item['start_ts'] + $item['total'] * 60 && ($item['allow_double_booking'] == 'F' || $item['service_id'] == $service['id']))
						{
							$allow_double_booking = false;
							break;
						}
					}
					if (!$allow_double_booking) {
						foreach ($employee['bs_arr'] as $item)
						{
							if ($i >= $item['start_ts'] && $i < $item['start_ts'] + $item['total'] * 60)
							{
								$is_free = false;
								break;
							}
						}
					}
					if ($i < time() + $hour_earlier)
					{
						$is_free = false;
					}
			
					if ($i >= $employee['t_arr']['lunch_start_ts'] && $i < $employee['t_arr']['lunch_end_ts'])
					{
						$is_free = false;
					}
			
					# Before lunch break
					if ($i + $service_total - $service_before > $employee['t_arr']['lunch_start_ts'] && $i < $employee['t_arr']['lunch_end_ts'])
					{
						$is_free = false;
					}
					if ($is_free)
					{
						if (!$allow_double_booking) {
							foreach ($employee['bs_arr'] as $item)
							{
								if ($i + $service_total - $service_before > $item['start_ts'] && $i <= $item['start_ts'])
								{
									// before booking
									$is_free = false;
									break;
								}
							}
						}
						if ($i + $service_total - $service_before > $employee['t_arr']['end_ts'] + $offset)
						{
							// end of working day
							$is_free = false;
						}
					}
					if ($is_free) {
						$service_available_slot_arr[$service['id']][] = $i;
					}
				}				
			}
			foreach ($service_available_slot_arr as $service_id => $times) {
				foreach ($times as $k => $v) {
					$arr = array();
					$arr[] = $v.'|'.($v + $service_length_arr[$service_id]).'|'.$service_id.'|'.$employee_id;
					$time = $v + $service_length_arr[$service_id];
					foreach ($service_available_slot_arr as $_service_id => $_times) {
						if ($_service_id != $service_id) {
							foreach ($_times as $_k => $_v) {
								if ($_v == $time) {
									$arr[] = $_v.'|'.($_v + $service_length_arr[$_service_id]).'|'.$_service_id.'|'.$employee_id;
									$time = $_v + $service_length_arr[$_service_id];
									break;
								}
							}
						}
					}
					if (count($arr) == count($service_arr)) {
						$available_slot_arr[] = implode("~:~", $arr);
					}
				}
				break;
			}
		}
		return $available_slot_arr;
	}
	
	protected function getAvailableSlotAnyEmployee($date, $option_arr) {
		$available_slot_arr = array();
		$FILTER = isset($_SESSION[$this->defaultFilter]) ? $_SESSION[$this->defaultFilter] : array();
		$service_arr = pjServiceModel::factory()
			->where('t1.calendar_id', $this->getForeignId())
			->where('t1.is_active', 1)
			->where('t1.hide_on_frontend', 'F')
			->whereIn('t1.id', $FILTER['services'])
			->orderBy('t1.order ASC')
			->findAll()
			->getData();

		$pjEmployeeModel = pjEmployeeModel::factory(); 
		foreach ($FILTER['services'] as $service_id) {
			$pjEmployeeModel->where('t1.id IN (SELECT `employee_id` FROM `'.pjEmployeeServiceModel::factory()->getTable().'` WHERE `service_id`='.$service_id.')');
		}
		$employee_arr = $pjEmployeeModel
			->where('t1.calendar_id', $this->getForeignId())
			->where('t1.category', 'employee')
			->where('t1.is_active', 'T')
			->orderBy('t1.order ASC')
			->findAll()
			->getData();
			
		$step = $option_arr['o_step'] * 60;
		$hour_earlier = $option_arr['o_booking_earlier'] * 60 * 60;		
		foreach ($employee_arr as $empl) {
			$wt_arr = pjAppController::getWTimePerEmployee($empl['id'], $this->getForeignId(), $option_arr, $date);
			if ($wt_arr['t_arr']) {
				$service_available_slot_arr = $service_length_arr = array();
				foreach ($service_arr as $service) {
					$service_total = $service['total'] * 60;
					$service_length = $service['length'] * 60;
					$service_before = $service['before'] * 60;
					$service_length_arr[$service['id']] = $service_total - $service_before;
					# Fix for 24h support
					$offset = $wt_arr['t_arr']['end_ts'] <= $wt_arr['t_arr']['start_ts'] ? 86400 : 0;			
					for ($i = $wt_arr['t_arr']['start_ts']; $i <= $wt_arr['t_arr']['end_ts'] + $offset - $step; $i += $step)
					{
						$is_free = true;
						$allow_double_booking = true;
						foreach ($wt_arr['bs_arr'] as $item) {
							if ($i >= $item['start_ts'] && $i < $item['start_ts'] + $item['total'] * 60 && ($item['allow_double_booking'] == 'F' || $item['service_id'] == $service['id']))
							{
								$allow_double_booking = false;
								break;
							}
						}
						if (!$allow_double_booking) {
							foreach ($wt_arr['bs_arr'] as $item)
							{
								if ($i >= $item['start_ts'] && $i < $item['start_ts'] + $item['total'] * 60)
								{
									$is_free = false;
									break;
								}
							}
						}
						if ($i < time() + $hour_earlier)
						{
							$is_free = false;
							$class = "pjAsTimeUnavailable";
						}
				
						if ($i >= $wt_arr['t_arr']['lunch_start_ts'] && $i < $wt_arr['t_arr']['lunch_end_ts'])
						{
							$is_free = false;
						}
				
						# Before lunch break
						if ($i + $service_total - $service_before > $wt_arr['t_arr']['lunch_start_ts'] && $i < $wt_arr['t_arr']['lunch_end_ts'])
						{
							$is_free = false;
						}
						if ($is_free)
						{
							if (!$allow_double_booking) {
								foreach ($wt_arr['bs_arr'] as $item)
								{
									if ($i + $service_total - $service_before > $item['start_ts'] && $i <= $item['start_ts'])
									{
										// before booking
										$is_free = false;
										break;
									}
								}
								
							}
							if ($i + $service_total - $service_before > $wt_arr['t_arr']['end_ts'] + $offset)
							{
								// end of working day
								$is_free = false;
							}
						}					
						if ($is_free) {
							$service_available_slot_arr[$service['id']][] = $i;
						}
					}
				}
				
				foreach ($service_available_slot_arr as $service_id => $times) {
					foreach ($times as $k => $v) {
						$arr = array();
						$arr[] = $v.'|'.($v + $service_length_arr[$service_id]).'|'.$service_id.'|'.$empl['id'];
						$time = $v + $service_length_arr[$service_id];
						foreach ($service_available_slot_arr as $_service_id => $_times) {
							if ($_service_id != $service_id) {
								foreach ($_times as $_k => $_v) {
									if ($_v == $time) {
										$arr[] = $_v.'|'.($_v + $service_length_arr[$_service_id]).'|'.$_service_id.'|'.$empl['id'];
										$time = $_v + $service_length_arr[$_service_id];
										break;
									}
								}
							}
						}
						if (count($arr) == count($service_arr)) {
							$available_slot_arr[] = implode("~:~", $arr);
						}
					}
					break;
				}
			}
			if ($available_slot_arr) {
				break;
			}
		}
		
		return $available_slot_arr;
	}
	
	public function pjActionServices()
	{
		//print_r($this->_get);
		//die('okk');
		if ($this->isXHR() || $this->_get->check('_escaped_fragment_'))
		{
			$FILTER = isset($_SESSION[$this->defaultFilter]) ? $_SESSION[$this->defaultFilter] : array();
			// if (isset($FILTER['gender']) && !empty($FILTER['gender']) && isset($FILTER['services']) && count($FILTER['services']) > 0) {
			// 	$this->getFilters();
			// } else {
			// 	pjAppController::jsonResponse(array('status' => 'MISSING_PARAMATERS'));
			// }
			$_SESSION[$this->defaultFilter]['employee'] = $this->_get->toString('employee');
			
			$date = date('Y-m-d');				
			if($this->_get->check('date'))
			{
				$date = $this->_get->toString('date');
			}
			$extraHours = pjExtraHoursModel::factory()->findAll()->getData();
			$this->set('extraHours', $extraHours);
		
			// if ($this->_get->toInt('employee') > 0) {
			// 	$available_slote_arr = $this->getAvailableSlotPerEmployee($this->_get->toInt('employee'), $date, $this->option_arr);
			// } else {
			// 	$available_slote_arr = $this->getAvailableSlotAnyEmployee($date, $this->option_arr);				
			// }
			$available_slote_arr = $this->getAvailableSlotPerDay($date, $this->option_arr);
			// print_r($available_slote_arr); die('getAvailableSlotPerDay');
			$this->set('available_slote_arr', $available_slote_arr);
			
			$this->set('cart_arr',  $this->getCart($this->getForeignId()));
			$this->set('date', $date);
			
			list($year, $month, $day) = explode("-", $date);
			$dates = $this->getDates($this->getForeignId(), $year, $month);
			$this->set('calendar', $this->getCalendar($dates[0], $year, $month, $day));
			
			if((int) $this->option_arr['o_booking_days_earlier'] > 0)
			{
				$today_ts = strtotime(date('Y-m-d 00:00:00', time()));
				$days_earlier = $this->option_arr['o_booking_days_earlier'] * 24 * 60 * 60;
				$ahead_ts = $today_ts + $days_earlier;
				$selected_ts = strtotime($this->_get->toString('date') . ' 00:00:00');
				
				if($selected_ts > $ahead_ts)
				{
					$this->set('unavailable', true);
				}
			}
			switch ($this->_get->toString('layout'))
			{
				case 2:
					$this->setTemplate('pjFrontPublic', 'pjActionServices');
					break;
				case 1:
				default:
					$this->setTemplate('pjFrontPublic', 'pjActionEmployees');
					break;
			}
		}
	}
	
	public function pjActionEmployee()
	{
		if ($this->isXHR() || $this->_get->check('_escaped_fragment_'))
		{
			$service_id = null;
			$employee_id = null;
			$date = date('Y-m-d');
	
			if($this->_get->check('date'))
			{
				$date = $this->_get->toString('date');
			}
				
			if ($this->_get->check('service_id') && (int) $this->_get->toInt('service_id') > 0 && $this->_get->check('employee_id') && $this->_get->toInt('employee_id') > 0){
				$service_id = (int) $this->_get->toInt('service_id');
				$employee_id = $this->_get->toInt('employee_id');
			}elseif ($this->_get->check('employee_id') && $this->_get->toInt('employee_id') > 0){
				$employee_id = $this->_get->toInt('employee_id');
			}elseif ($this->_get->check('_escaped_fragment_')) {
				preg_match('/\/Employee\/(\d+)/', $this->_get->toString('_escaped_fragment_'), $matches);
				if (isset($matches[1]))
				{
					$employee_id = $matches[1];
				}
				preg_match('/\/Employee\/(\d+)\/(\d+)/', $this->_get->toString('_escaped_fragment_'), $matches);
				if (isset($matches[1]))
				{
					$employee_id = $matches[1];
				}
				if (isset($matches[2]))
				{
					$service_id = $matches[2];
				}
					
				preg_match('@^/Employee/[\w\-]+\-(\d+)\.html$@', $this->_get->toString('_escaped_fragment_'), $matches);
				if ($matches)
				{
					$employee_id = $matches[1];
				}
					
				preg_match('@^/Employee/\d{4}/\d{2}/\d{2}/[\w\-]+\-(\d+)/[\w\-]+\-(\d+)\.html$@', $this->_get->toString('_escaped_fragment_'), $matches);
				if ($matches)
				{
					$employee_id = $matches[1];
					$service_id = $matches[2];
				}
			}
				
			list($year, $month, $day) = explode("-", $this->_get->toString('date'));
			$dates = $this->getDates($this->getForeignId(), $year, $month);
			$this->set('calendar', $this->getCalendar($dates[0], $year, $month, $day));

			$service_arr = pjServiceModel::factory()
				->select("t1.*, t2.content AS `name`")
				->join('pjMultiLang', "t2.model='pjService' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
				->where('t1.calendar_id', $this->getForeignId())
				->where("t1.id IN (SELECT TES.service_id FROM `".pjEmployeeServiceModel::factory()->getTable()."` AS TES WHERE TES.employee_id='".$employee_id."') ")
				->where('t1.is_active', 1)
				->where('t1.hide_on_frontend', 'F')
				->findAll()
				->getData();
			
			if(count($service_arr) == 1)
			{
				$service_id = $service_arr[0]['id'];
			}
			if($service_id != null && $employee_id != null)
			{
			    $app_info = pjAppController::getAppointmentInfo($employee_id, $service_id, $this->getForeignId(), $date, $this->getLocaleId(), $this->option_arr);
				$this->set('service', $app_info['service']);
				$this->set('employee', $app_info['employee']);
			}
			if ($this->cart->isEmpty())
			{
				$this->set('status', 'ERR');
				$this->set('code', '101');
			}
			
			$this->set('date', $date);
				
			$_employee_arr = pjEmployeeModel::factory()
				->select("t1.*, t2.content AS `name`,
							(
								SELECT GROUP_CONCAT(TL.content SEPARATOR ',')
								FROM `".pjServiceModel::factory()->getTable()."` AS TS LEFT OUTER JOIN `".pjMultiLangModel::factory()->getTable()."` AS TL ON TL.model='pjService' AND TL.foreign_id=TS.id AND TL.locale='".$this->getLocaleId()."' AND TL.field='name'
								WHERE TS.is_active='1' AND TS.hide_on_frontend='F' AND TS.id IN (
						                         	SELECT TES.service_id
													FROM `".pjEmployeeServiceModel::factory()->getTable()."` AS TES
													WHERE TES.employee_id = t1.id
												)
							) AS services")
				->join('pjMultiLang', "t2.model='pjEmployee' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
				->where('t1.calendar_id', $this->getForeignId())
				->where('t1.is_active', 'T')
				->orderBy('t1.order ASC, t2.content ASC')
				->findAll()
				->getData();

			$employee_arr = array();
			foreach($_employee_arr as $k => $v)
			{
				$wt_arr = pjAppController::getRawSlotsPerEmployee($v['id'], $date,  $this->getForeignId());
				if($wt_arr == false)
				{
					unset($_employee_arr[$k]);
				}else{
					$employee_arr[] = $v;
				}
			}
			if((int) $this->option_arr['o_booking_days_earlier'] > 0)
			{
				$today_ts = strtotime(date('Y-m-d 00:00:00', time()));
				$days_earlier = $this->option_arr['o_booking_days_earlier'] * 24 * 60 * 60;
				$ahead_ts = $today_ts + $days_earlier;
				$selected_ts = strtotime($this->_get->toString('date') . ' 00:00:00');
					
				if($selected_ts > $ahead_ts)
				{
					$this->set('unavailable', true);
				}
			}
			
			$this
				->set('employee_arr', $employee_arr)
				->set('service_arr', $service_arr)
				->set('cart_arr', $this->getCart($this->getForeignId()));
		}
	}
	
	public function pjActionBooking()
	{
		if ($this->isXHR() || $this->_get->check('_escaped_fragment_'))
		{
			$this->set('status', 'OK');
			
			if ($this->_get->check('booking_uuid') && $this->_get->toString('booking_uuid') != '')
			{
				$booking_uuid = $this->_get->toString('booking_uuid');
			} elseif ($this->_get->check('_escaped_fragment_')) {
				preg_match('/\/Booking\/([A-Z]{2}\d{10})/', $this->_get->toString('_escaped_fragment_'), $matches);
				if (isset($matches[1]))
				{
					$booking_uuid = $matches[1];
				}
			}
			
			$booking_arr = pjBookingModel::factory()->where('t1.uuid', $booking_uuid)->findAll()->limit(1)->getData();
			if (!empty($booking_arr))
			{
				$booking_arr = $booking_arr[0];
				
				if(pjObject::getPlugin('pjPayments') !== NULL)
				{
					$pjPlugin = pjPayments::getPluginName($booking_arr['payment_method']);
					if(pjObject::getPlugin($pjPlugin) !== NULL)
					{
						$this->set('params', $pjPlugin::getFormParams(array('payment_method' => $booking_arr['payment_method']), array(
								'locale_id'	 => $this->getLocaleId(),
								'return_url'	=> $this->option_arr['o_thankyou_page'],
								'id'			=> $booking_arr['id'],
								'foreign_id'	=> NULL,
								'uuid'		  => $booking_arr['uuid'],
								'name'		  => $booking_arr['c_name'],
								'email'		 => $booking_arr['c_email'],
								'phone'		 => $booking_arr['c_phone'],
								'amount'		=> $booking_arr['booking_deposit'],
								'cancel_hash'   => sha1($booking_arr['uuid'].strtotime($booking_arr['created']).PJ_SALT),
								'currency_code' => $this->option_arr['o_currency'],
						)));
					}
				
					if ($booking_arr['payment_method'] == 'bank')
					{
						$bank_account = pjMultiLangModel::factory()->select('t1.content')
						->where('t1.model','pjOption')
						->where('t1.locale', $this->getLocaleId())
						->where('t1.field', 'o_bank_account')
						->limit(1)
						->findAll()->getDataIndex(0);
						$this->set('bank_account', $bank_account['content']);
					}
				}
				
				$this->set('booking_arr', $booking_arr);
			}
		}
	}
	
	public function pjActionPreview()
		{ //print_r($this->_get); die('oo');
			if ($this->isXHR() || $this->_get->check('_escaped_fragment_'))
			{
				if ($this->cart->isEmpty())
				{
					$this->set('status', 'ERR');
					$this->set('code', '101'); //Empty cart
					return;
				}
				
				if (!isset($_SESSION[$this->defaultForm]) || empty($_SESSION[$this->defaultForm]))
				{
					$this->set('status', 'ERR');
					$this->set('code', '102'); //Checkout form not filled
					return;
				}
				
				if (in_array($this->option_arr['o_bf_country'], array(2,3)) && (int) @$_SESSION[$this->defaultForm]['c_country_id'] > 0)
				{
					$this->set('country_arr', pjBaseCountryModel::factory()
						->select('t1.*, t2.content AS name')
						->join('pjMultiLang', "t2.model='pjBaseCountry' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
						->find($_SESSION[$this->defaultForm]['c_country_id'])
						->getData()
					);
				}
				$cart = $this->cart->getAll();
				$cart_arr = $this->getCart($this->getForeignId());
				
				if(pjObject::getPlugin('pjPayments') !== NULL)
				{
					$this->set('payment_option_arr', pjPaymentOptionModel::factory()->getOptions(NULL));
					$this->set('payment_titles', pjPayments::getPaymentTitles($this->getForeignId(), $this->getLocaleId()));
				}
				else
				{
					$this->set('payment_titles', __('payment_methods', true));
				}
				
				if ($this->option_arr['o_allow_bank'] == '1')
				{
					$bank_account = pjMultiLangModel::factory()->select('t1.content')
					->where('t1.model','pjOption')
					->where('t1.locale', $this->getLocaleId())
					->where('t1.field', 'o_bank_account')
					->limit(1)
					->findAll()->getDataIndex(0);
					$this->set('bank_account', $bank_account['content']);
				}
				
				
				if (isset($_SESSION[$this->defaultFilter]['subservices']) && count($_SESSION[$this->defaultFilter]['subservices']) > 0) {
					$this->set('subservice_arr', pjSubserviceModel::factory()
						->select('t1.*, t2.content AS `name`')
						->join('pjMultiLang', "t2.model='pjSubservice' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
						->where('t1.status', 'T')
						->whereIn('t1.id', $_SESSION[$this->defaultFilter]['subservices'])
						->orderBy('t2.content ASC')
						->findAll()
						->getData()
					);
				}
				
				$this->set('status', 'OK');
				$this->set('summary', $this->getSummary());
				$this->set('cart', $cart);
				$this->set('cart_arr', $cart_arr);
			}
		}
		
	public function pjActionLoadCart()
	{	
		$this->setAjax(true);
		
		if ($this->isXHR() || $this->_get->check('_escaped_fragment_'))
		{
			if ($this->cart->isEmpty())
			{
				$this->set('status', 'ERR');
				$this->set('code', '101');
				return;
			}
			$this->set('status', 'OK');
			$this->set('cart_arr', $this->getCart($this->getForeignId()));
			$this->setTemplate('pjFrontPublic', 'pjActionLoadCart');
		}
	}
	
	public function pjActionRouter()
	{
		$this->setAjax(false);

		if ($this->_get->check('_escaped_fragment_'))
		{
			$templates = array('Checkout', 'Preview', 'Service', 'Services', 'Booking', 'Cart', 'Appointment');
			preg_match('/^\/(\w+).*/', $this->_get->toString('_escaped_fragment_'), $m);
			if (isset($m[1]) && in_array($m[1], $templates))
			{
				$template = 'pjAction'.$m[1];
			
				if (method_exists($this, $template))
				{
					$this->$template();
				}
				$this->setTemplate('pjFrontPublic', $template);
			}
		}
	}
	
	public function pjActionMain()
	{
		//print_r($this->_get);die('ook');

		if ($this->isXHR() || $this->_get->check('_escaped_fragment_'))
		{
			$this->pjActionServices();
		}
	}
}
?>