<?php
/**
 * @package    JBusinessDirectory
 *
 * @author CMSJunkie http://www.cmsjunkie.com
 * @copyright  Copyright (C) 2007 - 2021 CMSJunkie. All rights reserved.
 * @license   https://www.gnu.org/licenses/agpl-3.0.en.html
 */
defined('_JEXEC') or die('Restricted access');

jimport('joomla.application.component.modelitem');
JTable::addIncludePath(DS.'components'.DS.'com_jbusinessdirectory'.DS.'tables');
require_once(HELPERS_PATH.'/category_lib.php');

class JBusinessDirectoryModelEvent extends JModelItem {
	public $event = null;
	
	public function __construct() {
		parent::__construct();
		$this->context="com_jbusinessdirectory.event.details";
		$this->appSettings = JBusinessUtil::getApplicationSettings();
		
		$this->eventId = JFactory::getApplication()->input->get('eventId');
		$this->eventId = intval($this->eventId);
	}

	/**
	 * Returns a Table object, always creating it
	 *
	 * @param   type	The table type to instantiate
	 * @param   string	A prefix for the table class name. Optional.
	 * @param   array  Configuration array for model. Optional.
	 * @return  JTable	A database object
	 */
	public function getTable($type = 'Event', $prefix = 'JTable', $config = array()) {
		return JTable::getInstance($type, $prefix, $config);
	}

	
	/**
	 * Method to get a cache id based on the listing id.
	 *
	 * @param unknown $params
	 * @param string $id
	 * @return string
	 */
	protected function getCacheId($id) {
		return md5($this->context . ':' . $id);
	}
	
	public function getEvent() {
		if (empty($this->eventId)) {
			return;
		}
		
		$eventData = null;
		$cacheIdentifier = $this->getCacheId($this->eventId);
		try {
			$cache = JCache::getInstance();
			if ($this->appSettings->enable_cache) {
				$eventData = $cache->get($cacheIdentifier);
				if (empty($eventData)) {
					$eventData = $this->getEventData();
					$cache->store($eventData, $cacheIdentifier);
				}
			} else {
				$eventData = $this->getEventData();
			}
		} catch (RuntimeException $e) {
			$this->setError($e->getMessage());
			return null;
		}
		

		if(!empty($eventData)){
			$_REQUEST["current_event"] = $eventData;
		}

		return $eventData;
	}
	
	/**
	 * Get item function
	 *
	 * @return void
	 */
	public function getItem($pk = NULL){
		return $this->getEvent();
	}

	public function getEventData() {
		$eventsTable = JTable::getInstance("Event", "JTable");
		$event =  $eventsTable->getActiveEvent($this->eventId);
		
		if (empty($event)) {
			return $event;
		}

		$this->event = $event;
		
		$event->pictures = $eventsTable->getEventPictures($this->eventId);
		$this->increaseViewCount($this->eventId);
		
		if (!empty($event->company_id)) {
			$companiesTable = JTable::getInstance("Company", "JTable");
			$company = $companiesTable->getCompany($event->company_id);
			$event->company=$company;
			$event->companyPackage = $this->getPackage($event->company_id);
		}
		
		if ($this->appSettings->enable_multilingual) {
			JBusinessDirectoryTranslations::updateEntityTranslation($event, EVENT_DESCRIPTION_TRANSLATION);
			if (!empty($event->company)) {
				JBusinessDirectoryTranslations::updateEntityTranslation($event->company, BUSSINESS_DESCRIPTION_TRANSLATION);
			}
			JBusinessDirectoryTranslations::getInstance()->updateMetaDataTranslation($event, EVENT_META_TRANSLATION);
		}

		$dates = '';
		if (!JBusinessUtil::emptyDate($event->booking_open_date) && !JBusinessUtil::emptyDate($event->booking_close_date) && $event->booking_open_date!=$event->booking_close_date) {
			$dates = JBusinessUtil::getDateGeneralFormat($event->booking_open_date).' - '.JBusinessUtil::getDateGeneralFormat($event->booking_close_date);
		} elseif ($event->booking_open_date==$event->booking_close_date) {
			$dates = JBusinessUtil::getDateGeneralFormat($event->booking_open_date);
		} elseif (!JBusinessUtil::emptyDate($event->booking_open_date)) {
			$dates = JText::_('LNG_STARTING_FROM').' '.JBusinessUtil::getDateGeneralFormat($event->booking_open_date);
		} elseif (!JBusinessUtil::emptyDate($event->booking_close_date)) {
			$dates = JText::_('LNG_UNTIL').' '.JBusinessUtil::getDateGeneralFormat($event->booking_close_date);
		}

		$event->dates = $dates;

		$event->attachments = JBusinessDirectoryAttachments::getAttachments(EVENTS_ATTACHMENTS, $this->eventId, true);
		if (!empty($event->attachments)) {
			$event->attachments = array_slice($event->attachments, 0, $this->appSettings->max_attachments);
			foreach ($event->attachments as $attach) {
				$attach->properties = JBusinessUtil::getAttachProperties($attach);
			}
		}

		$attributeConfig = JBusinessUtil::getAttributeConfiguration(DEFAULT_ATTRIBUTE_TYPE_LISTING);
		$event->company = JBusinessUtil::updateItemDefaultAtrributes($event->company, $attributeConfig);
		$attributeEventConfig = JBusinessUtil::getAttributeConfiguration(DEFAULT_ATTRIBUTE_TYPE_EVENT);
		$event = JBusinessUtil::updateItemDefaultAtrributes($event, $attributeEventConfig);

		if (!empty($event->categories)) {
			$event->categories = explode('#|', $event->categories);
			foreach ($event->categories as $k=>&$category) {
				$category = explode("|", $category);
			}
		}

		$maxCategories = !empty($event->categories)?count($event->categories):0;
		if (!empty($this->appSettings->max_categories)) {
			$maxCategories = $this->appSettings->max_categories;
		}

		if (!empty($event->categories)) {
			$event->categories = array_slice($event->categories, 0, $maxCategories);
		}

		//dispatch load event
		JFactory::getApplication()->triggerEvent('onAfterJBDLoadEvent', array($event));

		return $event;
	}

	public function getEventAttributes() {
		$attributesTable = $this->getTable('EventAttributes');
		$categoryId = null;
		if ($this->appSettings->enable_attribute_category) {
			$categoryId = -1;
			if (!empty($this->event->main_subcategory)) {
				$categoryId = $this->event->main_subcategory;
			}
		}
		$result = $attributesTable->getEventAttributes($this->eventId, $categoryId);

		return $result;
	}

	public function getEventTickets() {
		$ticketsTable = $this->getTable("EventTickets");
		$eventTickets = $ticketsTable->getTicketsByEvent($this->eventId);

		$ticketsBooked = EventBookingService::getNumberOfAvailableTickets($this->eventId);
		$result = array();
		foreach ($eventTickets as &$eventTicket) {
			if (empty($eventTicket->max_booking) || ($eventTicket->max_booking > $eventTicket->quantity)) {
				$eventTicket->max_booking = $eventTicket->quantity;
			}
			
			if (isset($ticketsBooked[$eventTicket->id]) && $eventTicket->max_booking > ($eventTicket->quantity - $ticketsBooked[$eventTicket->id])) {
				$eventTicket->max_booking = $eventTicket->quantity - $ticketsBooked[$eventTicket->id];
			}
			
			if ($eventTicket->max_booking < 0) {
				$eventTicket->max_booking = 0;
			}
			
			if ($eventTicket->max_booking > 0) {
				$result[] = $eventTicket;
			}
		}
		
		if ($this->appSettings->enable_multilingual) {
			JBusinessDirectoryTranslations::updateEventTicketsTranslation($result);
		}

		return $result;
	}

	/**
	 * Get the events that are about to expire and send an email to the event owners
	 */
	public function checkEventsAboutToExpire() {
		$eventTable = $this->getTable("Event");
		$appSettings = JBusinessUtil::getApplicationSettings();
		$nrDays = $appSettings->expiration_day_notice;
		$events = $eventTable->getEventsAboutToExpire($nrDays);
		foreach ($events as $event) {
			echo "sending expiration e-mail to: ".$event->name."<br/>";
			$result = EmailService::sendEventExpirationEmail($event, $nrDays);
			if ($result) {
				$eventTable->updateExpirationEmailDate($event->id);
			}
		}
		exit;
	}

	public function deleteExpiredEvents() {
		$eventTable = $this->getTable("Event");
		$eventTable->deleteExpiredEvents();
		exit;
	}

	public function getPlainEvent($eventid) {
		$eventsTable = $this->getTable("Event");
		$event = $eventsTable->getEvent($eventid);
		return $event;
	}

	public function contactEventCompany($data) {
		$company = $this->getTable("Company");
		$company->load($data['companyId']);

		if (!empty($data['contact_id_event'])) {
			$company->email = $data['contact_id_event'];
		}

		$data["description"] = htmlspecialchars($data["description"], ENT_QUOTES);

		$ret = EmailService::sendContactEventCompanyEmail($company, $data);

		return $ret;
	}

	/**
	 * Method that gets the appointment data from the form and saves them in the table
	 *
	 * @param $data array holding the data input from the user
	 * @return bool
	 */
	public function leaveAppointment($data) {
		$eventsTable = $this->getTable("Event");
		$data["date"] = JBusinessUtil::convertToMysqlFormat($data["date"]);
		$data["time"] = JBusinessUtil::convertTimeToMysqlFormat($data["time"]);

		if ($eventsTable->storeAppointment($data)) {
			return true;
		}
		return false;
	}
	
	
	/**
	 * Retrieve the associated companies related to this particular event
	 *
	 * @return mixed
	 */
	public function getAssociatedCompanies() {
		$table = $this->getTable("EventAssociatedCompanies");
		
		$searchDetails = array();
		$searchDetails["eventId"] = $this->eventId;

		$companies = $table->getAssociatedCompaniesDetails($searchDetails);
		return $companies;
	}

	/**
	 * Method to retrieve all companies belonging to a certain user
	 *
	 * @return mixed
	 */
	public function getCompaniesByUserId() {
		$user = JBusinessUtil::getUser();
		if ($user->id == 0) {
			return null;
		}

		$appSettings = JBusinessUtil::getApplicationSettings();

		$searchDetails = array();
		$searchDetails['userId'] = $user->id;
		$searchDetails['enablePackages'] = $appSettings->enable_packages;
		$searchDetails['showPendingApproval'] = ($appSettings->enable_item_moderation=='0' || ($appSettings->enable_item_moderation=='1' && $appSettings->show_pending_approval == '1'));

		$companiesTable = $this->getTable("Company");
		$companies =  $companiesTable->getCompaniesByNameAndCategories($searchDetails);

		return $companies;
	}

	/**
	 * Retrieve the associated companies which belong to a certain user
	 * and related to this particular event
	 *
	 * @param $eventId int ID of the event
	 * @return mixed
	 */
	public function getUserAssociatedCompanies($eventId=null) {
		$user = JBusinessUtil::getUser();
		if ($user->id == 0) {
			return null;
		}

		$table = $this->getTable("EventAssociatedCompanies");
		if (empty($eventId)) {
			$eventId = $this->eventId;
		}
		$searchDetails = array();

		$searchDetails["eventId"] = $eventId;
		$searchDetails["userId"] = $user->id;

		$companies = $table->getAssociatedCompaniesDetails($searchDetails);

		return $companies;
	}

	/**
	 * Method that gets a list of company ids and the ID of the event, and creates
	 * new associations between the companies and the event. Sends an email to the event owner
	 * notifying about the new associations
	 *
	 * @param $eventId int ID of the event
	 * @param $companyIds string concatenated ID's of companies
	 */
	public function associateCompaniesAjax($eventId, $companyIds) {
		$companyIds = explode(',', $companyIds);

		if (empty($eventId)) {
			return;
		}
		$user = JBusinessUtil::getUser();
		$companies = $this->getAssociatedCompanies();
		
		$excludedIds = array();
		foreach($companies as $company){
			if($company->userId == $user->id && !in_array($company->id, $companyIds)){
				$excludedIds[] = $company->id;
			}
		}

		$associatedTable = $this->getTable('EventAssociatedCompanies', 'JTable');
		$associatedTable->storeAssociatedCompanies($eventId, $companyIds, $excludedIds);

		$companies = $this->getUserAssociatedCompanies($eventId);

		$eventsTable = JTable::getInstance("Event", "JTable");
		$event =  $eventsTable->getEvent($eventId);

		if (!empty($companies)) {
			// prepare the company names to be sent in the email
			$companyNames = '';
			foreach ($companies as $company) {
				$companyNames .= '<p>';
				$companyLink = '<a href="'.JBusinessUtil::getCompanyLink($company).'">'.$company->name.'</a>';
				$companyNames .= $companyLink;
				$companyNames .= '<p>';
			}

			// send email to event owner
			//EmailService::sendCompanyAssociationNotification($event, $companyNames);
		}
	}

	/**
	 * Get all event videos
	 *
	 * @return mixed
	 */
	public function getEventVideos() {
		$table = $this->getTable("EventVideos");
		$videos = $table->getEventVideos($this->eventId);

		if (!empty($videos)) {
			foreach ($videos as $video) {
				$data = JBusinessUtil::getVideoDetails($video->url);
				$video->url = $data['url'];
				$video->videoType = $data['type'];
				$video->videoThumbnail = $data['thumbnail'];
			}
		}

		return $videos;
	}

	/**
	 * Method to increase the view count of the event, both on the
	 * event and statistics table
	 *
	 * @param $eventId int ID of the event
	 * @return bool
	 */
	public function increaseViewCount($eventId) {
		$eventsTable = $this->getTable();
		$eventsTable->increaseViewCount($eventId);

		// prepare the array with the table fields
		$data = array();
		$data["id"] = 0;
		$data["item_id"] = $eventId;
		$data["item_type"] = STATISTIC_ITEM_EVENT;
		$data["date"] = JBusinessUtil::convertToMysqlFormat(date('Y-m-d')); //current date
		$data["type"] = STATISTIC_TYPE_VIEW;
		$statisticsTable = $this->getTable("Statistics", "JTable");
		if (!$statisticsTable->save($data)) {
			return false;
		}

		return true;
	}

	public function saveEventMessages($data) {
		$data["name"] = $data["firstName"];
		$data["surname"] = $data["lastName"];
		$data["message"] = $data["description"];
		$data["item_id"] = $data["event_id"];
		$data["type"] = MESSAGE_TYPE_EVENT;
		$data["user_id"] = JBusinessUtil::getUser()->id;
		$data["read"] = '0';

		$table = $this->getTable("Messages");

		$data["message"] = htmlspecialchars($data["message"], ENT_QUOTES);
		
		// Bind the data.
		if (!$table->bind($data)) {
			$this->setError($table->getError());
			dump($table->getError());
			return false;
		}

		// Check the data.
		if (!$table->check()) {
			$this->setError($table->getError());
			dump($table->getError());
			return false;
		}

		// Store the data.
		if (!$table->store()) {
			$this->setError($table->getError());
			dump($table->getError());
			return false;
		}

		return true;
	}

	/*
	 * Retrieve the currect active package for a listing
	 */
	public function getPackage($companyId=null) {
		if (empty($companyId)) {
			$companyId = $this->companyId;
		}
		$table = $this->getTable("Package");
		$package = $table->getCurrentActivePackage($companyId);

		return $package;
	}

	public function getEventsDetailsICS(){
		$eventDetails = $this->getItem();

		$event = array(
			'title' => $eventDetails->name,
			'description' => $eventDetails->description,
			'start_date' => strtotime($eventDetails->start_date),
			'start_time' => strtotime($eventDetails->start_time),
			'end_date' => strtotime($eventDetails->end_date),
			'end_time' => strtotime($eventDetails->end_time),
			'address' => $eventDetails->address,
		);

		$ical = 'BEGIN:VCALENDAR';
		$ical .= "\r\n";
		$ical .= 'PRODID:-//JBusinessDirectory//NONSGML Event Calendar//EN';
		$ical .= "\r\n";
		$ical .= 'VERSION:2.0';
		$ical .= "\r\n";
		$ical .= 'CALSCALE:GREGORIAN';
		$ical .= "\r\n";
		$ical .= 'BEGIN:VEVENT';
		$ical .= "\r\n";
		$ical .= 'DTSTART:' . date('Ymd',$event['start_date']). 'T' .date('His',$event['start_time']);
		$ical .= "\r\n";
		$ical .= 'DTEND:' . date('Ymd',$event['end_date']) . 'T' . date('His',$event['end_time']);
		$ical .= "\r\n";
		$ical .= 'UID:' . md5($event['title']);
		$ical .= "\r\n";
		$ical .= 'DTSTAMP:' . date('Ymd') . 'T' . date('His') . 'Z';
		$ical .= "\r\n";
		$ical .= 'LOCATION:' . $event['address'];
		$ical .= "\r\n";
		$ical .= 'DESCRIPTION:' . str_replace(array("\r\n", "\r", "\n"), '',strip_tags($event['description']));
		$ical .= "\r\n";
		$ical .= 'SUMMARY:' . $event['title'];
		$ical .= "\r\n";
		$ical .= 'END:VEVENT';
		$ical .= "\r\n";
		$ical .= 'END:VCALENDAR';

		return $ical;
	}

	public function exportEventsDetailsICS() {
		$ical = $this->getEventsDetailsICS();
		$eventName = $this->getItem()->name;

		$fileName = $eventName . "-calendar";
		header('Content-type: text/calendar');
		header('Content-Disposition: attachment; filename="'.$fileName.'.ics"');
		print $ical;
	}
}
?>

