<?php

/**
 * @package         Google Structured Data
 * @version         5.6.8 Pro
 *
 * @author          Tassos Marinos <info@tassos.gr>
 * @link            http://www.tassos.gr
 * @copyright       Copyright © 2021 Tassos Marinos All Rights Reserved
 * @license         GNU GPLv3 <http://www.gnu.org/licenses/gpl.html> or later
 */

defined('_JEXEC') or die('Restricted access');

use GSD\Helper;
use GSD\PluginBaseEvent;
use GSD\MappingOptions;
use NRFramework\Functions;

/**
 *  Event Booking Google Structured Data Plugin
 */
class plgGSDEventBooking extends PluginBaseEvent
{
	/**
	 *  Get article's data
	 *
	 *  @return  array
	 */
	public function viewEvent()
	{	
		// Make sure we have a valid ID
		if (!$id = $this->getThingID())
		{
			return;
		}

		// Load current item via model
		$item = EventbookingHelperDatabase::getEvent($id);

		if (!is_object($item))
		{
			return;
		}

		// EventBooking doesn't save dates into the database in UTC format.
		$publish_up   = Functions::dateToUTC($item->publish_up);
		$publish_down = Functions::dateToUTC($item->publish_down);
		$startDate    = Functions::dateToUTC($item->event_date);
		$endDate      = Functions::dateToUTC($item->event_end_date);
		$regDate      = !empty($item->registration_start_date && $item->registration_start_date != '0000-00-00 00:00:00') ? Functions::dateToUTC($item->registration_start_date) : $startDate;

		// Array data
		$payload = [
			'id'   		  		  => $item->id,
			'alias'       		  => $item->alias,
			'headline'    		  => $item->title,
			'description' 		  => empty($item->short_description) ? $item->description : $item->short_description,
			'introtext'   		  => $item->short_description,
			'fulltext'   	      => $item->description,
			'image'       		  => $item->image,
			'imagetext'	   		  => Helper::getFirstImageFromString($item->short_description . $item->description),
			'startDate'	  		  => $startDate,
			'endDate'	  		  => $endDate, 
			'created_by'  		  => $item->created_by,
			'publish_up'  		  => $publish_up,
			'publish_down'        => $publish_down,
			'metakey'	  		  => $item->meta_keywords,
			'metadesc'	  		  => $item->meta_description,
			'offerStartDate' 	  => $regDate,
			'offerPrice'    	  => $item->individual_price,
			'offerCurrency'       => $item->currency_code,
			'offerInventoryLevel' => $item->event_capacity
		];

		if ($location = EventbookingHelperDatabase::getLocation($item->location_id))
		{
			$payload['locationName'] = $location->name;
			$payload['locationAddress'] = $location->address;
			$payload['addressLocality'] = $location->address;
			$payload['addressCountry'] = $location->country;
			$payload['postalCode'] = $location->zip;
			$payload['addressRegion'] = $location->state;
			$payload['gsd_venue_mapping'] = isset($location->gsd_venue_mapping) ? $location->gsd_venue_mapping : '';
		}

		return $payload;
	}

	/**
	 * Listening to the onAfterRender Joomla event
	 *
	 * @return void
	 */
	public function onAfterRender()
	{
		$this->removeMicrodata();
	}

	/**
	 * Helper method to remove the extra and incomplete Event microdata generated by the Event Booking extension
	 *
	 * @return void
	 */
	private function removeMicrodata()
	{
		if ((bool) !$this->params->get('removemicrodata', true))
		{
			return;
		}

		if (!$this->passContext() || $this->getView() != 'event')
		{
			return;
		}
		
		// Get document buffer
		$body = $this->app->getBody();

		// Simple check to decide whether the plugin should procceed or not.
		if (\Joomla\String\StringHelper::strpos($body, 'schema.org/Event') === false)
		{
			return;
		}

		// Replacement patterns
		$patterns = [
			'/itemscope itemtype=(\"?)http(s?):\/\/schema.org\/(Event|AggregateOffer)(\"?)/',
			'/<meta itemprop="(startDate|endDate|url)"[^>]+>/',
			'/itemprop="(lowPrice|offers)"/'
		];

		$body = preg_replace_callback($patterns, function($match) use (&$result)
		{
			return '';
		}, $body);

		$this->app->setBody($body);
	}

	/**
	 * The MapOptions Backend Event. Triggered by the mappingoptions fields to help each integration add its own map options.
	 *  
	 * @param	string	$plugin
	 * @param	array	$options
	 *
	 * @return	void
	 */
	public function onMapOptions($plugin, &$options)
	{
		parent::onMapOptions($plugin, $options);

		if ($plugin != $this->_name)
		{
			return;
		}

		// Remove undeeded default mapping options values
		$remove_options = [
			'performerType',
			'performerName',
			'performerURL',
			'organizerType',
			'organizerName',
			'organizerURL'
		];

		// Remove unsupported mapping options
		foreach ($remove_options as $option)
		{
			unset($options['GSD_INTEGRATION']['gsd.item.' . $option]);
		}

		// Add Event based options
		$new_options = [
			'gsd_venue_mapping' => 'GSD Venue Mapping',
		];

		MappingOptions::add($options, $new_options, 'GSD_INTEGRATION', 'gsd.item.');
	}
}
