<?php
/**
 * List view shortcode.
 *
 * @package EventimUSEventListings
 */

defined( 'ABSPATH' ) || exit;

global $evuselConfig;
add_shortcode( $evuselConfig::SHORTCODE_LIST_VIEW, 'evusel_list_view_shortcode' );
/**
 * Render list view shortcode.
 *
 * @param array $atts Shortcode attributes.
 * @return string Shortcode output.
 */
function evusel_list_view_shortcode( $atts ) {

	global $evuselConfig;

	$listViewClasses = isset( $atts['withcalendar'] ) ? 'with-calendar ' : '';
	$string          = '<div class="list-view-events ' . esc_attr( $listViewClasses ) . '">';

	$templateType = $atts['type'] ?? 'list';
	$listType     = $templateType === 'list' ? 'l' : 'g'; // This is for legacy reasons

	if ( wp_doing_ajax() ) {
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reading sanitized GET parameter for pagination
		$evusel_lists_in_content_counter = isset( $_GET['currentList'] ) ? intval( $_GET['currentList'] ) : 1;
	} else {
		global $evusel_lists_in_content_counter;

		if ( empty( $evusel_lists_in_content_counter ) ) {
			$evusel_lists_in_content_counter = 1;
		} else {
			++$evusel_lists_in_content_counter;
		}
	}

    // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reading sanitized GET parameter for pagination
	if ( isset( $_GET[ 'list' . $evusel_lists_in_content_counter . 'page' ] ) ) {
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reading sanitized GET parameter for pagination
		$page = intval( $_GET[ 'list' . $evusel_lists_in_content_counter . 'page' ] );
	} else {
		$page = 1;
	}

	$limit        = $evuselConfig->get( 'shortcodes.list_view.per_page' );
	$offset       = ( $page - 1 ) * $limit;
	$columnAmount = $evuselConfig->get( 'shortcodes.list_view.column_amount' );

	$listNavigationType = $evuselConfig->get( 'shortcodes.list_view.navigation_for_list' );
	$gridNavigationType = $evuselConfig->get( 'shortcodes.list_view.navigation_for_grid' );

	$hideRepeating = $evuselConfig->get( 'show_repeating_events' ) === false;

	$getPosts = new WP_Query();

	$args = array(
		'posts_per_page' => $limit,
		'offset'         => $offset,
		'post_type'      => 'seetickets-event',
		'post_status'    => array( 'publish' ),
		'meta_query'     => array( 'relation' => 'AND' ),
		'orderby'        => 'meta_value',
		'order'          => 'ASC',
		'meta_key'       => 'event_time',
		'meta_type'      => 'datetime',
		'post_parent'    => 0,
	);

	evusel_add_passed_meta_criteria( $args );

	$events = $getPosts->query( $args );

	if ( empty( $events ) ) {
		$fallback_args = array(
			'posts_per_page' => $limit,
			'offset'         => $offset,
			'post_type'      => 'seetickets-event',
			'post_status'    => array( 'publish' ),
			'meta_query'     => array( 'relation' => 'AND' ),
			'orderby'        => 'meta_value',
			'order'          => 'ASC',
			'meta_key'       => 'sort_date',
			'meta_type'      => 'DATE',
			'post_parent'    => 0,
		);
		evusel_add_passed_meta_criteria( $fallback_args );
		$events = $getPosts->query( $fallback_args );
	}

	if ( empty( $events ) ) {
		$simple_args = array(
			'posts_per_page' => $limit,
			'offset'         => $offset,
			'post_type'      => 'seetickets-event',
			'post_status'    => array( 'publish' ),
			'post_parent'    => 0,
		);
		$events      = $getPosts->query( $simple_args );
	}

	$totalPages = $getPosts->max_num_pages;

	$dimensionsPerColumn = $evuselConfig->get( 'imageDimensionsPerColumn' );

	$mainClasses  = 'seetickets-list-events ';
	$mainClasses .= $listType === 'l' ? '' : 'grid-container display-flex grid-cols-' . (int) $columnAmount . ' ';

	$string .= '<span id="list-view-event"></span>';
	$string .= '<div class="' . esc_attr( $mainClasses ) . '">';
	foreach ( $events as $index => $event ) {

		// if ($hideRepeating && has_post_parent($event)) {

		// $parent = get_post_parent($event);
		// $repeatingDates = $parent->repeating_dates;
		// $lastRepeatingDate = end($repeatingDates);
		// $sortDateTime = DateTime::createFromFormat('Ymd', $event->sort_date);

		// if ($lastRepeatingDate != $sortDateTime->format('m/d/Y')) {
		// continue; // Skip all repeating event,s except for the last one.
		// }
		// }

		$eventDateTime = evusel_get_event_display_date_time( $event->ID );

		$eventImage = evusel_get_event_image( $event->ID );

		$alternate        = $evuselConfig->get( 'shortcodes.list_view.use_alternating_view' ) === 'on' && ( $index % 2 ) !== 0 && $listType === 'l' ? '_alternate' : '';
		$ticketLink       = evusel_get_ticket_link( $event );
		$ticketButtonLink = evusel_get_ticket_link( $event, true );
		$eventTitle       = get_post_meta( $event->ID, 'event_title', true );

		$btnText   = evusel_get_ticket_status_button_text( $event );
		$ariaLabel = evusel_get_ticket_button_aria_label( false, $eventTitle, $eventDateTime );

		$classes = evusel_get_ticket_status_button_classes( $event );

		$materialStyle = $evuselConfig->get( 'shortcodes.list_view.material_list_style' );
		if ( $materialStyle !== 'outlined' && $materialStyle !== 'elevated' ) {
			$materialStyle = 'outlined';
		}
		$containerClasses  = 'seetickets-list-event-container mdc-card ';
		$containerClasses .= $listType === 'g' ? 'grid-item ' : '';
		$containerClasses .= $materialStyle === 'outlined' ? 'mdc-card--outlined ' : 'mdc-card--elevated ';

		$gridImageContainerStyle  = $listType === 'l' ? 'width: 275px; height: 275px; ' : 'width: 100%; aspect-ratio: 1 / 1; ';
		$gridImageContainerStyle .= $evuselConfig->get( 'event_image_style' ) === 'square' ?
			'object-fit: cover; ' :
			'object-fit: contain; ';

		$socialClasses = $evuselConfig->get( 'social_icon_circles' ) === 'on' ? 'social-circle ' : 'social-icon ';

		$openEventPageToNewTab = $evuselConfig->get( 'open_event_page_to_new_tab' );

		$seeticketEventButtonTarget = '';
		if ( $openEventPageToNewTab == 'on' ) {
			$seeticketEventButtonTarget = "target='_blank'";
		}

		$seeticketEventButton = "<a href='" . esc_url( $ticketButtonLink ) . "' " . esc_attr( $seeticketEventButtonTarget ) . " aria-label='" . esc_attr( $ariaLabel ) . "' class='seetickets-buy-btn fs-16 " . esc_attr( $classes ) . "'>" . esc_html( $btnText ) . '</a>';

		$listElementTemplate = str_replace(
			array(
				'{%image%}',
				'{%cardLabels%}',
				'{%buttonClasses%}',
				'{%eventButtonText%}',
				'{%eventContainerClass%}',
				'{%eventContainerStyle%}',
				'{%pluginDirUrl%}',
				'{%facebookShareText%}',
				'{%twitterSharetext%}',
				'{%ticketLink%}',
				'{%socialClasses%}',
				'{%ariaLabel%}',
				'{%facebookIcon%}',
				'{%twitterIcon%}',
				'{%openEventPageToNewTab%}',
			),
			array(
				evusel_anchorize( '<img src="' . esc_url( $eventImage ) . '" style="' . esc_attr( $gridImageContainerStyle ) . '" class="seetickets-list-view-event-image">', $event ),
				evusel_getCardLabelsHtml( $event, $eventTitle, 'list', false, $eventDateTime ),
				esc_attr( $classes ),
				esc_html( $btnText ),
				esc_attr( $containerClasses ),
				'',
				esc_url( EVUSEL_PLUGIN_DIR_URL ),
				esc_url( urldecode( $ticketLink ) ),
				esc_url( urldecode( $ticketLink ) ),
				esc_url( $ticketButtonLink ),
				esc_attr( $socialClasses ),
				esc_attr( $ariaLabel ),
				'<span class="d-inline-block ' . esc_attr( $socialClasses ) . '">' . file_get_contents( EVUSEL_PLUGIN_DIR . '/images/facebook-icon.svg' ) . '</span>',
				'<span class="d-inline-block ' . esc_attr( $socialClasses ) . '">' . file_get_contents( EVUSEL_PLUGIN_DIR . '/images/x-twitter-brands-solid.svg' ) . '</span>',
				$seeticketEventButton,
			),
			file_get_contents( EVUSEL_PLUGIN_DIR . "includes/templates/event_{$templateType}_element$alternate.html" )
		);

		$string .= $listElementTemplate;
	}

	if ( empty( $events ) ) {
		$string .= file_get_contents( EVUSEL_PLUGIN_DIR . 'includes/templates/no_events_found.html' );
	}

	$string .= '</div>';

	// Load More
	if (
		( ( $listType === 'g' && $gridNavigationType === 'loadmore' ) || ( $listType === 'l' && $listNavigationType === 'loadmore' ) )
		&& $totalPages > $page
	) {
		$string .=
			'<div class="display-flex justify-center">
                <button class="seetickets-list-view-load-more-button"
                    class="seetickets-load-more-btn"
                    data-see-ajax-page="2"
                    data-see-total-pages="' . esc_attr( $totalPages ) . '"
                    data-list-type="' . esc_attr( $templateType ) . '"
                    >
                    + LOAD MORE EVENTS
                    <img src="' . esc_url( EVUSEL_PLUGIN_DIR_URL . '/images/spinner.svg' ) . '" alt="" id="convert-webp-spinner">
                </button>
            </div>';
	}

	// Pagination
	$string .= evusel_generate_list_view_pagination( $listType, $gridNavigationType, $listNavigationType, $totalPages, $page, $templateType );

	$string .= '</div>';

	return $string;
}

add_action( 'wp_ajax_evusel_list_view_events', 'evusel_list_view_events' );
add_action( 'wp_ajax_nopriv_evusel_list_view_events', 'evusel_list_view_events' );
/**
 * Fetch list view events via AJAX.
 *
 * @return void
 */
function evusel_list_view_events() {
	$nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ) : '';
	if ( empty( $nonce ) || ! wp_verify_nonce( $nonce, 'evusel-nonce' ) ) {
		wp_send_json_error( esc_html__( 'Security check failed', 'eventim-us-event-listings' ) );
		return;
	}

	global $evuselConfig;

	$dimensionsPerColumn = $evuselConfig->get( 'imageDimensionsPerColumn' );
	$listNavigationType  = $evuselConfig->get( 'shortcodes.list_view.navigation_for_list' );
	$gridNavigationType  = $evuselConfig->get( 'shortcodes.list_view.navigation_for_grid' );

	$templateType = isset( $_REQUEST['listType'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['listType'] ) ) : 'list';
	$listType     = $templateType === 'grid' ? 'g' : 'l';
	$page         = isset( $_REQUEST['seeAjaxPage'] ) ? intval( $_REQUEST['seeAjaxPage'] ) : 1;

	try {
		$columnAmount = $evuselConfig->get( 'shortcodes.list_view.column_amount' );
		$mainClasses  = 'seetickets-list-events ';
		$mainClasses .= $listType === 'l' ? '' : 'grid-container display-flex grid-cols-' . (int) $columnAmount . ' ';

		// Ensure we're using the same number of events per page as the initial load
		$limit = $evuselConfig->get( 'shortcodes.list_view.per_page' );
		if ( $listType === 'g' ) {
			// For grid view, ensure the limit is a multiple of the column amount
			$limit = max( $columnAmount, $limit - ( $limit % $columnAmount ) );
		}

		$offset = ( $page - 1 ) * $limit;
		$openEventPageToNewTab = $evuselConfig->get( 'open_event_page_to_new_tab' );

		$hideRepeating = $evuselConfig->get( 'show_repeating_events' ) === false;

		$getPosts = new WP_Query();
		$args     = array(
			'posts_per_page' => $limit,
			'offset'         => $offset,
			'post_type'      => 'seetickets-event',
			'post_status'    => array( 'publish' ),
			'meta_query'     => array( 'relation' => 'AND' ),
			'orderby'        => 'meta_value',
			'order'          => 'ASC',
			'meta_key'       => 'event_time',
			'meta_type'      => 'datetime',
			'post_parent'    => 0,
		);

		evusel_add_passed_meta_criteria( $args );

		$events = $getPosts->query( $args );

		if ( empty( $events ) ) {
			$fallback_args = array(
				'posts_per_page' => $limit,
				'offset'         => $offset,
				'post_type'      => 'seetickets-event',
				'post_status'    => array( 'publish' ),
				'meta_query'     => array( 'relation' => 'AND' ),
				'orderby'        => 'meta_value',
				'order'          => 'ASC',
				'meta_key'       => 'sort_date',
				'meta_type'      => 'DATE',
				'post_parent'    => 0,
			);
			evusel_add_passed_meta_criteria( $fallback_args );
			$events = $getPosts->query( $fallback_args );
		}

		if ( empty( $events ) ) {
			$simple_args = array(
				'posts_per_page' => $limit,
				'offset'         => $offset,
				'post_type'      => 'seetickets-event',
				'post_status'    => array( 'publish' ),
				'post_parent'    => 0,
			);
			$events      = $getPosts->query( $simple_args );
		}

		$totalPages = $getPosts->max_num_pages;

		$string  = '<span id="list-view-event"></span>';
		$string .= '<div class="' . esc_attr( $mainClasses ) . '">';

		foreach ( $events as $index => $event ) {
			$eventDateTime = evusel_get_event_display_date_time( $event->ID );
			$eventImage    = evusel_get_event_image( $event->ID );

			$alternate =
				( $index + $offset ) % 2 !== 0 &&
				$evuselConfig->get( 'shortcodes.list_view.use_alternating_view' ) === 'on' &&
				$listType === 'l' ?
					'_alternate' :
					'';

			$ticketLink       = evusel_get_ticket_link( $event );
			$ticketButtonLink = evusel_get_ticket_link( $event, true );

			$eventTitle = get_post_meta( $event->ID, 'event_title', true );

			$btnText   = evusel_get_ticket_status_button_text( $event );
			$ariaLabel = evusel_get_ticket_button_aria_label( false, $eventTitle, $eventDateTime );

			$classes       = evusel_get_ticket_status_button_classes( $event );
			$materialStyle = $evuselConfig->get( 'shortcodes.list_view.material_list_style' );
			if ( $materialStyle !== 'outlined' && $materialStyle !== 'elevated' ) {
				$materialStyle = 'outlined';
			}
			$containerClasses  = 'seetickets-list-event-container mdc-card ';
			$containerClasses .= $listType === 'g' ? 'grid-item ' : '';
			$containerClasses .= $materialStyle === 'outlined' ? 'mdc-card--outlined ' : 'mdc-card--elevated ';

			$gridImageContainerStyle  = $listType === 'l' ?
				'width: 275px; height: 275px; ' :
				'width: ' . $dimensionsPerColumn[ $columnAmount ]['imageWidth'] . 'px; height: ' . $dimensionsPerColumn[ $columnAmount ]['imageWidth'] . 'px; ';
			$gridImageContainerStyle .= $evuselConfig->get( 'event_image_style' ) === 'square' ?
				'object-fit: cover; ' :
				'object-fit: contain; ';

			$socialClasses = $evuselConfig->get( 'social_icon_circles' ) === 'on' ? 'social-circle ' : 'social-icon ';

			$seeticketEventButtonTarget = '';
			if ( $openEventPageToNewTab == 'on' ) {
				$seeticketEventButtonTarget = "target='_blank'";
			}

			$seetiketEventButton = "<a href='" . esc_url( $ticketButtonLink ) . "' " . esc_attr( $seeticketEventButtonTarget ) . " aria-label='" . esc_attr( $ariaLabel ) . "' class='seetickets-buy-btn fs-16 " . esc_attr( $classes ) . "'>" . esc_html( $btnText ) . '</a>';

			$listElementTemplate = str_replace(
				array(
					'{%image%}',
					'{%cardLabels%}',
					'{%buttonClasses%}',
					'{%eventButtonText%}',
					'{%eventContainerClass%}',
					'{%eventContainerStyle%}',
					'{%pluginDirUrl%}',
					'{%facebookShareText%}',
					'{%twitterSharetext%}',
					'{%ticketLink%}',
					'{%socialClasses%}',
					'{%ariaLabel%}',
					'{%facebookIcon%}',
					'{%twitterIcon%}',
					'{%openEventPageToNewTab%}',
				),
				array(
					evusel_anchorize( '<img src="' . esc_url( $eventImage ) . '" style="' . esc_attr( $gridImageContainerStyle ) . '" class="seetickets-list-view-event-image">', $event ),
					evusel_getCardLabelsHtml( $event, $eventTitle, 'list', false, $eventDateTime ),
					esc_attr( $classes ),
					esc_html( $btnText ),
					esc_attr( $containerClasses ),
					'',
					esc_url( EVUSEL_PLUGIN_DIR_URL ),
					esc_url( urldecode( $ticketLink ) ),
					esc_url( urldecode( $ticketLink ) ),
					esc_url( $ticketButtonLink ),
					esc_attr( $socialClasses ),
					esc_attr( $ariaLabel ),
					'<span class="d-inline-block ' . esc_attr( $socialClasses ) . '">' . file_get_contents( EVUSEL_PLUGIN_DIR . '/images/facebook-icon.svg' ) . '</span>',
					'<span class="d-inline-block ' . esc_attr( $socialClasses ) . '">' . file_get_contents( EVUSEL_PLUGIN_DIR . '/images/x-twitter-brands-solid.svg' ) . '</span>',
					$seetiketEventButton,
				),
				file_get_contents( EVUSEL_PLUGIN_DIR . "includes/templates/event_{$templateType}_element$alternate.html" )
			);

			$string .= $listElementTemplate;
		}

		if ( empty( $events ) ) {
			$string .= file_get_contents( EVUSEL_PLUGIN_DIR . 'includes/templates/no_events_found.html' );
		}

		$string .= '</div>';
		$string .= evusel_generate_list_view_pagination( $listType, $gridNavigationType, $listNavigationType, $totalPages, $page, $templateType );

		// Do NOT wrap with <div class="list-view-events"> for AJAX
		header( 'Content-Type: text/html; charset=UTF-8' );
		echo wp_kses_post( $string );
		wp_die();
	} catch ( Exception $e ) {
		header( 'Content-Type: application/json' );
		wp_send_json_error( 'An error occurred: ' . esc_html( $e->getMessage() ) );
		wp_die();
	}
}

/**
 * @param string $listType
 * @param string $gridNavigationType
 * @param string $listNavigationType
 * @param int    $totalPages
 * @param int    $page
 * @param string $templateType
 * @return string
 *
 * @since 0.31.0b
 */
function evusel_generate_list_view_pagination( $listType, $gridNavigationType, $listNavigationType, $totalPages, $page, $templateType ) {
	// Pagination
	if (
		( ( $listType === 'g' && $gridNavigationType === 'pagination' ) || ( $listType === 'l' && $listNavigationType === 'pagination' ) )
		&& $totalPages > 1
	) {
		if ( wp_doing_ajax() ) {
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reading sanitized GET parameter for pagination
			$evusel_lists_in_content_counter = isset( $_GET['currentList'] ) ? intval( $_GET['currentList'] ) : 1;
		} else {
			global $evusel_lists_in_content_counter;

			if ( empty( $evusel_lists_in_content_counter ) ) {
				$evusel_lists_in_content_counter = 1;
			}
		}

		$paginator  = '<div class="display-flex justify-end">';
		$paginator .= '<ul class="seetickets-list-view-pagination" data-list-type="' . esc_attr( $templateType ) . '" data-nth-list-element="' . esc_attr( $evusel_lists_in_content_counter ) . '">';

		$paginationCount  = 7;
		$paginationToDraw = $totalPages >= $paginationCount ? $paginationCount : $totalPages;
		$halfOfPagination = $paginationToDraw / 2;

		if ( $page == 1 ) {
			$pageNumber = 1;
		} elseif ( $page == $totalPages ) {
			$pageNumber = $page - ( $paginationToDraw - 1 );
		} elseif ( $page < $halfOfPagination ) {
			$pageNumber = $halfOfPagination - $page;
			$pageNumber = $pageNumber < 1 ? ceil( $pageNumber ) : $pageNumber;
		} elseif ( $totalPages - $page < $halfOfPagination ) {
			$pageNumber = $page - $halfOfPagination - ( $halfOfPagination - ( $totalPages - $page ) ) + 1;
		} else {
			$pageNumber = $page - $halfOfPagination + 1;
		}

		$pageNumber = floor( $pageNumber );

		for ( $i = 1; $i <= intval( $paginationToDraw ); $i++ ) {
			$displayPageNumber = $pageNumber < 10 ? '<span>' . esc_html( $pageNumber ) . '</span>' : esc_html( $pageNumber );

			if ( $page == $pageNumber ) {
				$paginator .= '<li class="seetickets-list-view-pagination-active">' . $displayPageNumber . '</li>';
			} else {
				$paginator .= '<li><a href="#" data-see-ajax-page="' . esc_attr( $pageNumber ) . '">' . $displayPageNumber . '</a></li>';
			}
			++$pageNumber;
		}

		$paginator .= '</ul></div>';

		return $paginator;
	}

	return '';
}
