<?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');
JTable::addIncludePath(JPATH_ROOT . '/administrator/components/com_jbusinessdirectory/tables');

require_once BD_CLASSES_PATH.'/traits/EventBookingSummary.php';

class EventBookingService {

	use EventBookingSummary;

	/**
	 * Get number of booked tickets
	 *
	 * @param $eventId int ID of the event
	 *
	 * @return array
	 * @since 5.0.0
	 */
	public static function getNumberOfAvailableTickets($eventId) {
		$eventBookingTable = JTable::getInstance('EventBookings', 'JTable', array());
		$appSettings       = JBusinessUtil::getApplicationSettings();

		if (!empty($appSettings->event_booking_timeout)) {
			$eventBookingTable->cancelExpiredBookings($appSettings->event_booking_timeout);
		}
		$ticketsNrBookings = $eventBookingTable->getNumberOfBookings($eventId);

		$result = array();
		foreach ($ticketsNrBookings as $ticketBookings) {
			$result[$ticketBookings->id] = $ticketBookings->nr_tickets;
		}

		return $result;
	}


	/**
	 * Prepare the event booking details
	 *
	 * @since 5.0.0
	 */
	public static function getEventBooking($orderId) {

		if(empty($orderId)){
			return null;
		}

		$eventBookingTable = JTable::getInstance('EventBookings', 'JTable', array());
		$booking = $eventBookingTable->getBookingDetails($orderId);

		$eventTicketTable = JTable::getInstance('EventTickets', 'JTable', array());
		$booking->tickets = $eventTicketTable->getTicketsDetailsByBooking($orderId);
		
		$orderTable = JTable::getInstance("Order", "JTable", array());
		$booking->taxes = $orderTable->getOrderTaxes($orderId, JBD_APP_EVENT_BOOKINGS);

		$taxObject = TaxService::calculateOrderTaxes($booking->initial_amount, $booking->taxes);
		$booking->taxes = $taxObject->taxes;

		$eventTable = JTable::getInstance('Event', 'JTable', array());
		$booking->event = $eventTable->getEvent($booking->event_id);
		$booking->event->pictures = $eventTable->getEventPictures($booking->event_id);
		$booking->currency_id = $booking->event->currency_id;

		//generate the booking summary
		$booking->ticketDetailsSummary = EventBookingService::getBookingSummary($booking);

		//generate the guest details summary
		$booking->guestDetailsSummary = EventBookingService::getBuyerDetailsSummary($booking);

		return $booking;
	}


	/**
	 * Save bookings information
	 *
	 * @param $bookingDetails
	 *
	 * @return bool
	 * @throws Exception
	 * @since 5.0.0
	 */
	public static function saveBookings($bookingDetails) {
		$eventBookingTable  = JTable::getInstance('EventBookings', 'JTable');
		$bookingDetails->id = 0;
		if (!empty($bookingDetails->guestDetails->bookingId)) {
			$eventBookingTable->id = (int) $bookingDetails->guestDetails->bookingId;
		}

		// Create a booking record on the table
		$eventBookingTable->event_id    = $bookingDetails->eventId;
		$eventBookingTable->first_name  = $bookingDetails->guestDetails->first_name;
		$eventBookingTable->last_name   = $bookingDetails->guestDetails->last_name;
		$eventBookingTable->address     = $bookingDetails->guestDetails->address;
		$eventBookingTable->city        = $bookingDetails->guestDetails->city;
		$eventBookingTable->region      = $bookingDetails->guestDetails->county;
		$eventBookingTable->country_id  = $bookingDetails->guestDetails->country;
		$eventBookingTable->postal_code = $bookingDetails->guestDetails->postalCode;
		$eventBookingTable->phone       = $bookingDetails->guestDetails->phone;
		$eventBookingTable->email       = $bookingDetails->guestDetails->email;
		$eventBookingTable->user_id     = isset($bookingDetails->guestDetails->user_id)?$bookingDetails->guestDetails->user_id:0;// JBusinessUtil::getUser()->id;
		$eventBookingTable->status = EVENT_BOOKING_CREATED;
		
		$totalWithoutTax = 0;
		foreach($bookingDetails->reservedItems as $ticket){
			$totalWithoutTax += $ticket->price * $ticket->ticket_quantity;
		}

		$eventBookingTable->initial_amount = $totalWithoutTax;

		$taxObject = TaxService::calculateTaxes($eventBookingTable->initial_amount, JBD_APP_EVENT_BOOKINGS, $bookingDetails->guestDetails->country->id);
		if (empty($taxObject->taxes)) {
			$taxObject = TaxService::calculateTaxes($eventBookingTable->initial_amount, JBD_APP_EVENT_BOOKINGS);
		}

		$vatObject = TaxService::getVat($eventBookingTable->initial_amount, $bookingDetails->guestDetails->country->id);
		$eventBookingTable->vat_amount = $vatObject->vat_amount;
		$eventBookingTable->vat = $vatObject->vat;
		
		$eventBookingTable->amount = floatval((float)$eventBookingTable->initial_amount + (float)$vatObject->vat_amount + (float)$taxObject->tax_amount);

		if (!$eventBookingTable->store()) {
			$application = JFactory::getApplication();
			$application->enqueueMessage($eventBookingTable->getDbo()->getError(), 'error');
			return false;
		}

		$bookingId = $eventBookingTable->id;

		$orderTable = JTable::getInstance('Order', 'JTable');
		$orderTable->deleteOrderTaxes($bookingId, JBD_APP_EVENT_BOOKINGS);
		$orderTable->createOrderTax($bookingId, JBD_APP_EVENT_BOOKINGS ,$taxObject->taxes);

		// Save all the ticket and booking data
		if(empty($bookingDetails->guestDetails->bookingId)){
			$ticketBookingTable = JTable::getInstance('EventBookingTickets', 'JTable');
			foreach ($bookingDetails->reservedItems as $ticket) {
				$ticketBookingTable->ticket_id       = $ticket->id;
				$ticketBookingTable->booking_id      = $bookingId;
				$ticketBookingTable->ticket_quantity = $ticket->quantity;
				if (!$ticketBookingTable->store()) {
					$application = JFactory::getApplication();
					$application->enqueueMessage($eventBookingTable->getDbo()->getError(), 'error');
					return false;
				}
			}
		}

		return $bookingId;
	}

	/**
	 * Create user data for storing booking details
	 * @param $data
	 * @param $userData
	 * @return stdClass
	 */
	public static function createUserData($data, $userData) {
		if (empty($userData)) {
			$userData = new stdClass();
		}

		if (!isset($userData->first_name)) {
			$userData->first_name = '';
		}
		if (!isset($userData->last_name)) {
			$userData->last_name = '';
		}
		if (!isset($userData->address)) {
			$userData->address	= '';
		}
		if (!isset($userData->city)) {
			$userData->city	= '';
		}
		if (!isset($userData->state_name)) {
			$userData->state_name	= '';
		}
		if (!isset($userData->country)) {
			$userData->country	= '';
		}
		if (!isset($userData->postal_code)) {
			$userData->postal_code= '';
		}
		if (!isset($userData->phone)) {
			$userData->phone = '';
		}
		if (!isset($userData->email)) {
			$userData->email= '';
		}
		if (!isset($userData->conf_email)) {
			$userData->conf_email = '';
		}

		return $userData;
	}

	/**
	 * Initialiaze user data
	 */
	public static function initializeUserData($resetUserData = false) {
		$get = JFactory::getApplication()->input->get->getArray();
		$data = JFactory::getApplication()->input->post->getArray();
		if (count($data)==0) {
			$data = $get;
		}

		$userData =  isset($_SESSION['userData'])?$_SESSION['userData']:null;
		if (!isset($userData) || $resetUserData) {
			$userData = self::createUserData($data, $userData);
			$_SESSION['userData'] = $userData;
		}

		if (!isset($userData->guestDetails)) {
			$guestDtls = new stdClass();
			$guestDtls->first_name = "";
			$guestDtls->last_name = "";
			$guestDtls->address	= "";
			$guestDtls->city	= "";
			$guestDtls->county	= "";
			$guestDtls->country_name	= "";
			$guestDtls->postalCode= "";
			$guestDtls->phone = "";
			$guestDtls->email="";
			$userData->guestDetails = $guestDtls;
		}

		$_SESSION['userData'] = $userData;
		return $userData;
	}

	/**
	 * Get user data object created from session data
	 * @return mixed|null|stdClass
	 */
	public static function getUserData() {
		$session = self::getJoomlaSession();
		$userData =  isset($_SESSION['userData'])?$_SESSION['userData']:null;
		if (!isset($userData)) {
			$userData = self::initializeUserData();
			$_SESSION['userData'] = $userData;
		}
		if (empty($userData->eventId)) {
			$userData->eventId = 0;
			$_SESSION['userData'] = $userData;
		}

		return $userData;
	}

	/**
	 * @param $eventId int ID of the event
	 * @param $reservedItems array of reserved items so far
	 * @param $current identification for rooms that have the same current are considered as 1
	 * @return string returns reserved Items by user on reservation steps
	 */
	public static function reserveTickets() {
		$log = Logger::getInstance(JPATH_COMPONENT."/logs/site-log-".date("d-m-Y").'.log', 1);

		unset($_SESSION['userData']);
		$userData = self::initializeUserData(true);
		
		$eventsTable = JTable::getInstance("Event", "JTable");
		$eventId = JFactory::getApplication()->input->get('eventId');
		
		$event = $eventsTable->getEvent($eventId);
		
		$ticket_quantity = JFactory::getApplication()->input->get('ticket_quantity');
		$ticket_id = JFactory::getApplication()->input->get('ticket_id');
		$tickets = array();
		$totalTickets = 0;
		foreach ($ticket_quantity as $key => $val) {
			if ($val>0) {
				$ticket = new stdClass();
				$ticket->id = $ticket_id[$key];
				$ticket->quantity = $val;
				$tickets[] = $ticket;
				$totalTickets+=$val;
			}
		}
		
		$ticketsBooked = EventBookingService::getNumberOfAvailableTickets($eventId);
		
		$totalTicketsBooked = 0;
		foreach ($ticketsBooked as $t) {
			$totalTicketsBooked+=$t;
		}
		
		if ($totalTickets>($event->total_tickets-$totalTicketsBooked)) {
			JFactory::getApplication()->enqueueMessage(JText::_('LNG_TICKET_MAX_NUMBER_EXCEED'), 'error');
			return false;
		}
		
		if ($totalTickets>($event->total_tickets-$totalTicketsBooked)) {
			JFactory::getApplication()->enqueueMessage(JText::_('LNG_TICKET_MAX_NUMBER_EXCEED'), 'error');
			return false;
		}
		
		if (empty($tickets)) {
			JFactory::getApplication()->enqueueMessage(JText::_('LNG_NO_TICKET_SELECTED'), 'error');
			return false;
		}

		$ticketsTable = JTable::getInstance("EventTickets", "JTable"); 
		$totAmount = 0;
		$currency = '';

		foreach ($tickets as &$ticket) {
			$tckt = $ticketsTable->getTicket((int)$ticket->id);
			$ticket->name = $tckt->name;
			$ticket->ticket_quantity = $ticket->quantity;
			$ticket->price = (float)$tckt->price;
			$totAmount += $ticket->quantity * $ticket->price;
			$currency = $tckt->currency;
		}
		
		$userData->eventId = $eventId;
		$userData->amount = $totAmount;
		$userData->currency = $currency;
		
		$userData->reservedItems = $tickets;
		$log->LogDebug("Reserved items eventId= $eventId: ".serialize($userData->reservedItems));

		$_SESSION['userData'] = $userData;

		return true;
	}

	/**
	 * @param $guestDetails
	 */
	public static function saveGuestDetails($guestDetails) {
		//dump($guestDetails);
		$userData =  $_SESSION['userData'];
		$guestDtls = new stdClass();
		$guestDtls->first_name = ucfirst($guestDetails["first_name"]);
		$guestDtls->last_name = ucfirst($guestDetails["last_name"]);
		$guestDtls->address	= ucfirst($guestDetails["address"]);
		$guestDtls->city	= $guestDetails["city"];
		$guestDtls->county	= $guestDetails["region"];
		
		if(!is_object($guestDetails["country"])){
			$guestDetails["country"] = JBusinessUtil::getCountry($guestDetails["country"]);
		}

		$guestDtls->country = $guestDetails["country"];
		$guestDtls->country_name = !empty($guestDetails["country"])?$guestDetails["country"]->country_name:"";
		
		$guestDtls->postalCode= strtoupper($guestDetails["postal_code"]);
		$guestDtls->phone = $guestDetails["phone"];
		$guestDtls->email= $guestDetails["email"];
		$guestDtls->user_id= $guestDetails["user_id"];

		$bookingId = JFactory::getApplication()->input->get("bookingId", null);
		$guestDtls->bookingId = $bookingId;

		$userData->guestDetails = $guestDtls;

		$_SESSION['userData'] = $userData;
	}

	/**
	 *
	 * @param unknown_type $currencyName
	 * @param unknown_type $currencySymbol
	 */
	public static function setCurrency($currencyName, $currencySymbol) {
		$currency = new stdClass();
		$currency->name = $currencyName;
		$currency->symbol = $currencySymbol;

		$session = self::getJoomlaSession();
		$userData =  $_SESSION['userData'];
		$userData->currency = $currency;

		if ($userData->user_currency=="") {
			$userData->user_currency = $currency->name;
		}
		$_SESSION['userData'] = $userData;
	}

	private static function getJoomlaSession() {
		$session = JFactory::getSession();
		if ($session->getState() !== 'active') {
			$app = JFactory::getApplication();
			$msg = "Your session has expired";
			$app->redirect('index.php?option='.JBusinessUtil::getComponentName().'&view=events', $msg);
			$app->enqueueMessage("Your session has expired", 'warning');
		} else {
			return $session;
		}
	}
}
