<?php
// phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound

// Don't load directly
if (!defined('ABSPATH')) { exit; }

// Require object
if (empty($ics_data)) { return false; }

global $R34ICS;

$start_of_week = get_option('start_of_week', 0);

$date_format = r34ics_date_format($args['format'], true);

$today = r34ics_date('Ymd');

$fc_func_uid = r34ics_uid();

$ics_calendar_classes = apply_filters('r34ics_calendar_classes', array('nomobile notranslate'), $args, true);

// Tabs list may be a string *or* an array, and we need both at different times
$fc_tabs_string = esc_attr(implode(',', (array)$args['fc_tabs']));
// This seems stupid but it's not (adds type flexibility for $args['fc_tabs'])
$fc_tabs_array = explode(',', $fc_tabs_string);
$fc_tabs_mobile_string = esc_attr(implode(',', (array)$args['fc_tabs_mobile']));
$fc_tabs_mobile_array = explode(',', $fc_tabs_mobile_string);

// Feed colors custom CSS
if (!empty($ics_data['colors']) && function_exists('r34ics_feed_colors_css')) {
	r34ics_feed_colors_css($ics_data, true);
}

// Additional template-specific dynamic CSS
if (!empty($args['zoom'])) {
	?>
	<style>
	.ics-calendar#<?php echo esc_attr($ics_data['guid']); ?> .fc {
		--r34ics--fc--fc-timegrid-slot--height-ratio: <?php echo floatval($args['zoom']); ?>;
	}
	</style>
	<?php
}

// Prepare event details toggle lightbox
if ($args['toggle'] === 'lightbox') {
	r34ics_lightbox_container();
}
?>

<section class="<?php echo esc_attr($ics_calendar_classes); ?>" id="<?php echo esc_attr($ics_data['guid']); ?>"<?php
if (!empty($fc_tabs_mobile_string)) {
	echo ' data-tabs-mobile="' . esc_attr($fc_tabs_mobile_string) . '"';
}
if (!empty($args['fc_tab_default_mobile'])) {
	echo ' data-tab-default-mobile="' . esc_attr($args['fc_tab_default_mobile']) . '"';
}
?>>

	<?php
	// Actions before rendering calendar wrapper (can include additional template output)
	do_action('r34ics_display_calendar_before_wrapper', $view, $args, $ics_data);

	// Print
	if (!empty($args['print'])) {
		echo wp_kses($R34ICS->print_button_html($args), r34ics_color_key_allowed());
	}

	// Color code key
	if (!empty(trim(@$args['color'], '|')) && (empty($args['legendposition']) || $args['legendposition'] == 'above')) {
		echo wp_kses(($R34ICS->color_key_html($args, $ics_data) ?: ''), r34ics_color_key_allowed());
	}
	?>

	<div id="r34icspro_<?php echo esc_attr($ics_data['guid']); ?>_fc"></div>

	<?php
	// Color code key
	if (!empty(trim(@$args['color'], '|')) && !empty($args['legendposition']) && $args['legendposition'] == 'below') {
		echo wp_kses(($R34ICS->color_key_html($args, $ics_data) ?: ''), r34ics_color_key_allowed());
	}

	// Actions after rendering calendar wrapper (can include additional template output)
	do_action('r34ics_display_calendar_after_wrapper', $view, $args, $ics_data);
	?>

</section>

<script>
	if (typeof r34icspro_fc == 'undefined') { var r34icspro_fc = []; }

	function r34icspro_fc_<?php echo esc_attr($fc_func_uid); ?>() {
		var guid = '<?php echo esc_attr($ics_data['guid']); ?>';
		var views = [<?php
		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		echo '"' . implode('","', $fc_tabs_array) . '"';
		?>];
		var initialView = "<?php
			if (!empty($args['fc_tab_default']) && in_array($args['fc_tab_default'], $fc_tabs_array)) {
				echo esc_attr($args['fc_tab_default']);
			}
			elseif (!empty($fc_tabs_array[0])) {
				echo esc_attr($fc_tabs_array[0]);
			}
			else {
				echo 'dayGridMonth';
			}
			?>";

		r34icspro_fc[guid] = [];
		r34icspro_fc[guid]['el'] = document.getElementById('r34icspro_' + guid + '_fc');
		r34icspro_fc[guid]['cont_id'] = jQuery('#r34icspro_' + guid + '_fc').closest('.ics-calendar').attr('id');
		if (typeof jQuery('#' + r34icspro_fc[guid]['cont_id']).data('r34icsymd') != 'undefined') {
			// Needs to be cast as a string!
			r34icspro_fc[guid]['r34icsymd'] = '' + jQuery('#' + r34icspro_fc[guid]['cont_id']).data('r34icsymd');
		}
		else {
			r34icspro_fc[guid]['r34icsymd'] = "<?php echo wp_kses_post(intval(r34ics_date('Ymd'))); ?>";
		}
		
		r34icspro_fc[guid]['fc'] = new FullCalendar.Calendar(r34icspro_fc[guid]['el'], {
	
			// Hardcoded properties
			allDayText: "<?php esc_attr_e('All Day', 'ics-calendar-pro'); ?>",
			buttonText: {
				day: "<?php esc_attr_e('day', 'ics-calendar-pro'); ?>",
				list: "<?php esc_attr_e('list', 'ics-calendar-pro'); ?>",
				month: "<?php esc_attr_e('month', 'ics-calendar-pro'); ?>",
				today: "<?php esc_attr_e('today', 'ics-calendar-pro'); ?>",
				week: "<?php esc_attr_e('week', 'ics-calendar-pro'); ?>",
				year: "<?php esc_attr_e('year', 'ics-calendar-pro'); ?>",
			},
			closeHint: "<?php esc_attr_e('Close', 'ics-calendar-pro'); ?>",
			dayHeaders: true,
			dayMaxEvents: 999, <?php /* @todo Make editable with $args['limit_in_table'] after glitchy CSS is fixed */ ?>
			editable: false,
			eventHint: "<?php esc_attr_e('Event', 'ics-calendar-pro'); ?>",
			eventShortHeight: 30,
			expandRows: true,
			fixedWeekCount: <?php echo intval(apply_filters('r34icspro_fc_fixed_week_count', true)); ?>, <?php /* @todo Make a configurable option instead of a filter */ ?>
			height: (jQuery('body').hasClass('r34ics-print-calendar') ? "auto" : "<?php echo ($args['fc_height'] ? intval($args['fc_height']) . 'vh' : 'auto'); ?>"),
			locale: "<?php echo esc_attr(strtolower(str_replace('_','-',get_locale()))); ?>",
			moreLinkText: "<?php esc_attr_e('More', 'ics-calendar-pro'); ?>",
			navLinks: <?php echo in_array('timeGridDay', $fc_tabs_array) ? 'true' : 'false'; ?>,
			noEventsText: "<?php esc_attr_e('No events found.', 'ics-calendar-pro'); ?>",
			nowIndicator: true,
			selectable: false,
			showNonCurrentDates: <?php echo intval(apply_filters('r34icspro_fc_show_non_current_dates', true)); ?>, <?php /* @todo Make a configurable option instead of a filter */ ?>
			themeSystem: "standard",
			timeHint: "<?php esc_attr_e('Time', 'ics-calendar-pro'); ?>",
			weekText: "",
			weekTextLong: "",
		
			// Configurable properties
			allDaySlot: <?php echo (r34ics_boolean_check($args['fc_hide_alldayslot']) ? 'false' : 'true'); ?>,
			displayEventEnd: <?php echo (r34ics_boolean_check($args['showendtimes']) ? 'true' : 'false'); ?>,
			displayEventTime: <?php echo (r34ics_boolean_check($args['hidetimes']) ? 'false' : 'true'); ?>,
			eventMinHeight: 15,
			eventTimeFormat: <?php
			// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			echo r34icspro_timeformat_to_fc($args['timeformat']);
			?>,
			firstDay: <?php echo (!in_array('dayGridMonth', $fc_tabs_array) && $args['limitdays'] <= 8 ? intval(r34ics_date('w', $ics_data['earliest'])) : intval($start_of_week)); ?>,
			headerToolbar: {
				left: "title",
				center: (views.length > 1 ? views.join(",") : ''),
				right: "<?php
				// We exclude "today" if the current date is outside the date range
				if ($today < $ics_data['earliest'] || $today > $ics_data['latest']) {
					echo 'prev,next';
				}
				else {
					echo 'today prev,next';
				}
				?>",
			},
			initialDate: (typeof r34icspro_fc[guid]['r34icsymd'] != 'undefined' && r34icspro_fc[guid]['r34icsymd'] != '')
				? r34icspro_fc[guid]['r34icsymd']
				: "<?php echo wp_kses_post(r34ics_date('Y-m-d', (!empty($args['r34icsymd']) ? intval($args['r34icsymd']) : ''))); ?>",
			initialView: initialView,
			<?php
			if (!empty($args['fc_no_overlap'])) {
				?>
				slotEventOverlap: false,
				<?php
			}
			?>
			<?php
			if (!empty($args['zoom']) && $args['zoom'] > 1.2) {
				?>
				slotLabelInterval: "00:30",
				<?php
			}
			?>
			timeZone: "<?php echo esc_attr($args['tz']); ?>",
			validRange: {
				start: "<?php echo esc_attr(r34ics_date('Y-m-d', $ics_data['earliest'])); ?>",
				end: "<?php echo esc_attr(r34ics_date('Y-m-d', $ics_data['latest'])); ?>",
			},
			views: {
				<?php
				if (in_array('dayGridMonth', $fc_tabs_array)) {
					?>
					dayGridMonth: {
						dayHeaderFormat: {
							weekday: "<?php echo esc_attr(empty($ics_data['day_header_format']) ? 'long' : $ics_data['day_header_format']); ?>",
						},
						titleFormat: <?php
						// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
						echo r34icspro_dateformat_to_fc($args['formatmonthyear']);
						?>,
					},
					<?php
				}
				if (in_array('timeGridWeek', $fc_tabs_array)) {
					?>
					timeGridWeek: {
						dayHeaderFormat: {
							day: "numeric",
							month: "short",
							weekday: "<?php echo esc_attr(empty($ics_data['day_header_format']) ? 'short' : $ics_data['day_header_format']); ?>",
						},
						<?php
						// If we're only showing one week, start on whatever the first day is
						if ($args['limitdays'] <= 8) {
							echo 'firstDay: ' . esc_attr(r34ics_date('w', $ics_data['earliest'])) . ',';
						}
						?>
						titleFormat: <?php
						// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
						echo r34icspro_dateformat_to_fc($date_format);
						?>,
					},
					<?php
				}
				if (in_array('timeGridDay', $fc_tabs_array)) {
					?>
					timeGridDay: {
						titleFormat: <?php
						// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
						echo r34icspro_dateformat_to_fc($date_format);
						?>,
					},
					<?php
				}
				if (in_array('listMonth', $fc_tabs_array)) {
					?>
					listMonth: {
						listDayFormat: <?php
						// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
						echo r34icspro_dateformat_to_fc($date_format);
						?>,
						listDaySideFormat: false,
						titleFormat: <?php
						// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
						echo r34icspro_dateformat_to_fc($args['formatmonthyear']);
						?>,
					},
					<?php
				}
				if (in_array('multiMonthYear', $fc_tabs_array)) {
					?>
					multiMonthYear: {
						multiMonthMaxColumns: <?php echo intval($args['fc_year_tab_max_columns'] ?? 3); ?>,
						multiMonthTitleFormat: <?php
						// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
						echo r34icspro_dateformat_to_fc($args['formatmonthyear']);
						?>,
						validRange: {
							start: "<?php echo esc_attr(r34ics_date('Y', $ics_data['earliest'])); ?>-01-01",
							end: "<?php echo esc_attr(r34ics_date('Y', $ics_data['latest'])); ?>-12-31",
						},
					},
					<?php
				}
				?>
			},
			visibleRange: {
				start: "<?php echo esc_attr(r34ics_date('Y-m-d', $ics_data['earliest'])); ?>",
				end: "<?php echo esc_attr(r34ics_date('Y-m-d', $ics_data['latest'])); ?>",
			},
			weekends: <?php echo (r34ics_boolean_check($args['hideweekends']) ? 'false' : 'true'); ?>,
			weekNumbers: <?php echo (r34ics_boolean_check($args['weeknumbers']) ? 'true' : 'false'); ?>,
		
			// Conditionally-loaded properties
			<?php
			if (!empty($args['fc_business_days']) || !empty($args['hours'])) {
				?>
				businessHours: {
					<?php
					if (!empty($args['fc_business_days'])) {
						?>
						daysOfWeek: [<?php echo esc_attr($args['fc_business_days']); ?>],
						<?php
					}
					if (!empty($args['hours'])) {
						?>
						startTime: "<?php echo esc_attr(substr($args['hours'],0,2) . ':' . substr($args['hours'],2,2)); ?>",
						endTime: "<?php echo esc_attr(substr($args['hours'],5,2) . ':' . substr($args['hours'],7,2)); ?>",
						<?php
					}
					?>
				},
				<?php
			}
			if (!empty($args['hours'])) {
				?>
				scrollTime: "<?php echo esc_attr(substr($args['hours'],0,2) . ':' . substr($args['hours'],2,2)); ?>",
				<?php
				if (empty($args['fc_timegrid_all_hours'])) {
					?>
					slotMinTime: "<?php echo esc_attr(substr($args['hours'],0,2) . ':' . substr($args['hours'],2,2)); ?>",
					slotMaxTime: "<?php echo esc_attr(substr($args['hours'],5,2) . ':' . substr($args['hours'],7,2)); ?>",
					<?php
				}
			}
			?>

			// Methods
			eventClick: function(arg) {
				<?php
				// Open all links in a new tab
				if (@$args['sametab'] == 'none') {
					?>
					if (typeof arg.event.url != 'undefined' && arg.event.url != '') {
						arg.jsEvent.preventDefault();
						window.open(arg.event.url);
					}
					<?php
				}
				// Open offsite links in a new tab
				if (@$args['sametab'] == 'local') {
					?>
					if (typeof arg.event.url != 'undefined' && arg.event.url.indexOf('http') == 0 && arg.event.url.indexOf('//'+location.hostname) == -1) {
						arg.jsEvent.preventDefault();
						window.open(arg.event.url);
					}
					<?php
				}
				if (r34icspro_full_show_descloc($args)) {
					?>
					jQuery(document).find('.ics-calendar.layout-full .descloc').remove();
					if (jQuery(arg.el).find('.descloc')) {
						if (typeof arg.event.extendedProps.event_description_html != 'undefined' && arg.event.extendedProps.event_description_html != '') {
							if (jQuery(arg.el).find('td').length > 0) {
								jQuery(arg.el).find('td:last-child').append(arg.event.extendedProps.event_description_html);
							}
							else {
								jQuery(arg.el).append(arg.event.extendedProps.event_description_html);
							}
						}
					}
					<?php
				}
				?>
			},
			eventDidMount: function(arg) {
				jQuery(arg.el).attr('data-feed-key', arg.event.groupId).attr('tabindex', '0');
			},
			eventMouseEnter: function(arg) {
				arg.jsEvent.preventDefault();
				<?php
				if (r34icspro_full_show_descloc($args)) {
					?>
					jQuery(document).find('.ics-calendar.layout-full .descloc').remove();
					if (typeof arg.event.extendedProps.event_description_html != 'undefined' && arg.event.extendedProps.event_description_html != '') {
						if (jQuery(arg.el).find('td').length > 0) {
							jQuery(arg.el).find('td:last-child').append(arg.event.extendedProps.event_description_html);
						}
						else {
							jQuery(arg.el).append(arg.event.extendedProps.event_description_html);
						}
						r34icspro_fc_descloc_offsite_links();
					}
					<?php
				}
				?>
			},
			eventMouseLeave: function(arg) {
				arg.jsEvent.preventDefault();
				<?php
				if (r34icspro_full_show_descloc($args)) {
					?>
					jQuery(document).find('.ics-calendar.layout-full .descloc').remove();
					<?php
				}
				?>
			},
			moreLinkContent: function(arg) { return arg.num; },
			// viewClassNames runs any time the view changes... we're taking advantage of that
			viewClassNames: function(arg) {
				// @todo Make this more concise... if possible
				var current_start = arg.view.currentStart;
				var current_start_y = '' + current_start.getUTCFullYear();
				var current_start_m = '' + (current_start.getUTCMonth() + 1);
				if (current_start_m.length == 1) { current_start_m = '0' + current_start_m; }
				var current_start_d = '' + current_start.getUTCDate();
				if (current_start_d.length == 1) { current_start_d = '0' + current_start_d; }
				var r34icsymd = current_start_y + current_start_m + current_start_d;
				r34icspro_fc[guid]['r34icsymd'] = r34icsymd;
				jQuery('#r34icspro_' + guid + '_fc').attr('data-r34icsymd', r34icsymd);
				jQuery('#r34icspro_' + guid + '_fc').attr('data-tab-selected', arg.view.type);
			},
			viewDidMount: function(arg) {
				// Scroll list view to "today," if present in the selected date range
				if (arg.view.type == 'listMonth') {
					var scroller = jQuery(document).find('#' + guid + ' .fc-listMonth-view .fc-scroller');
					if (scroller.length > 0) {
						// Today has events
						var scroller_today = scroller.find('.fc-day-today');
						// If today doesn't have events, find the next day that does
						// @todo This is a bit crude; can it be optimized?
						if (scroller_today.length == 0) {
							var d = '';
							for (var j = <?php echo intval(r34ics_date('j')); ?>; j <= 31; j++) {
								d = (j < 10) ? '0' + j : '' + j; // Make sure we have a leading zero when needed
								scroller_today = scroller.find('.fc-day[data-date="<?php echo esc_attr(r34ics_date('Y-m')); ?>-' + d + '"]');
								if (scroller_today.length > 0) { break; }
							}
						}
						// We've found a date; scroll to it
						if (scroller_today.length > 0) {
							scroller.animate({ scrollTop: scroller_today.offset().top - scroller.offset().top }, 0);
						}
					}
				}
			},

			// Events data
			events: <?php
			// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			echo html_entity_decode($ics_data['events_json']);
			?>
		});

		r34icspro_fc[guid]['fc'].render();

	}
	
	<?php
	// This needs to exactly match conditional in R34ICS::shortcode() method!
	if (!isset($args['ajax']) || $args['ajax'] !== false) {
		?>
		if (typeof r34icspro_fc_<?php echo esc_attr($fc_func_uid); ?> === 'function' && typeof FullCalendar != '') {
			r34icspro_fc_<?php echo esc_attr($fc_func_uid); ?>();
		}
		<?php
	}
	else {
		?>
		document.addEventListener('DOMContentLoaded', r34icspro_fc_<?php echo esc_attr($fc_func_uid); ?>);
		<?php
	}
	?>
	
</script>

<?php
// Note: This is handled here because FullCalendar's data is structured differently than other views
if (!empty($args['jsonld']) && !empty($ics_data['events'])) {
	?>
	<script type="application/ld+json">
	[
	<?php
	ob_start();
	foreach ((array)$ics_data['events'] as $event) {
		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		echo r34ics_event2jsonld($event) . ',';
	}
	echo wp_kses(rtrim(ob_get_clean(), ','), data);
	?>
	]
	</script>
	<?php
}
?>
