<?php
/**
 * Event search shortcode.
 *
 * @package EventimUSEventListings
 */

defined( 'ABSPATH' ) || exit;

global $evuselConfig;

add_shortcode( $evuselConfig::SHORTCODE_EVENT_SEARCH, 'evusel_event_search_shortcode' );
/**
 * Render event search form shortcode.
 *
 * @param array $atts Shortcode attributes.
 * @return string Shortcode output.
 */
function evusel_event_search_shortcode( $atts ) {
	global $evuselConfig;

	$searchParameter = '';
	if ( isset( $_REQUEST['seetickets-search'] ) && ! empty( $_REQUEST['seetickets-search'] ) ) {
		$nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ) : '';
		if ( ! empty( $nonce ) && wp_verify_nonce( $nonce, $evuselConfig::NONCE_CODE ) ) {
			$searchParameter = sanitize_text_field( wp_unslash( $_REQUEST['seetickets-search'] ) );
		}
	}
	$serverRequestUri = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
	$queryArgs        = wp_parse_url( $serverRequestUri, PHP_URL_QUERY );
	$queryArgsArray   = array();
	if ( ! empty( $queryArgs ) ) {
		parse_str( $queryArgs, $queryArgsArray );
	}

	if ( empty( $searchParameter ) ) {
		unset( $queryArgsArray['sepage'] );
	}

	$nonce  = wp_create_nonce( $evuselConfig::NONCE_CODE );
	$string = '<form class="display-flex">
                    <input type="text" value="' . esc_attr( $searchParameter ) . '" name="seetickets-search" class="mr-1r" placeholder="Search">
                    <input type="hidden" name="nonce" value="' . esc_attr( $nonce ) . '">
                    <button type="submit" class="seetickets-search"><span class="dashicons dashicons-search"></span> <span class="ml-1r">Search</span></button>';

	foreach ( $queryArgsArray as $key => $value ) {
		if ( $key === 'seetickets-search' ) {
			continue;
		}
		$string .= '<input type="hidden" name="' . esc_attr( $key ) . '" value="' . esc_attr( $value ) . '">';
	}

	$string .= '</form>';

	return $string;
}

add_shortcode( $evuselConfig::SHORTCODE_EVENT_SEARCH_RESULTS, 'evusel_event_search_results_shortcode' );
/**
 * Render event search results shortcode.
 *
 * @param array $atts Shortcode attributes.
 * @return string Shortcode output.
 */
function evusel_event_search_results_shortcode( $atts = array() ) {
	global $evuselConfig;

	$string   = '<div id="list-view-events">';
	$listType = $evuselConfig->get( 'shortcodes.list_view.view_type' );
	$page     = isset( $_GET['sepage'] ) ? intval( $_GET['sepage'] ) : 1;
	$limit    = $evuselConfig->get( 'shortcodes.list_view.per_page' );
	$offset   = ( $page - 1 ) * $limit;

	$searchParameter = '';
	if ( isset( $_REQUEST['seetickets-search'] ) && ! empty( $_REQUEST['seetickets-search'] ) ) {
		$nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ) : '';
		if ( ! empty( $nonce ) && wp_verify_nonce( $nonce, $evuselConfig::NONCE_CODE ) ) {
			$searchParameter = sanitize_text_field( wp_unslash( $_REQUEST['seetickets-search'] ) );
		}
	}

	$columnAmount        = $evuselConfig->get( 'shortcodes.list_view.column_amount' );
	$fields              = ! empty( $atts['fields'] ) ? explode( ',', $atts['fields'] ) : array();
	$hideRepeating       = $evuselConfig->get( 'show_repeating_events' ) === false;
	$dimensionsPerColumn = $evuselConfig->get( 'imageDimensionsPerColumn' );

	if ( ! empty( $searchParameter ) ) {

		for ( $i = 0; $i < count( $evuselConfig->get( 'shortcodes.event_search.search_parameters' ) ); $i++ ) {
			$fields[ $i ] = $evuselConfig->get( 'shortcodes.event_search.search_parameters' )[ $i ];
		}

		// If no fields are given, default to search everything.
		if ( empty( $fields ) ) {
			$fields = array( 'location', 'genre', 'supporting_talent', 'headliners', 'event_title' );
		}

		$fields = array_map(
			function ( $key ) {
				return str_replace( 'location', 'venue', $key );
			},
			$fields
		);

		// Build meta query for search.
		$meta_query = array( 'relation' => 'OR' );
		foreach ( $fields as $field ) {
			$meta_query[] = array(
				'key'     => sanitize_key( $field ),
				'value'   => $searchParameter,
				'compare' => 'LIKE',
			);
		}

		// Get matching post IDs using WP_Query.
		$search_args = array(
			'post_type'      => 'seetickets-event',
			'post_status'    => 'publish',
			'posts_per_page' => -1,
			'post_parent'    => 0,
			'fields'         => 'ids',
            // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Required for search functionality
			'meta_query'     => $meta_query,
		);

		$search_query = new WP_Query( $search_args );
		$postIds      = $search_query->posts;

		// Get repeating events if enabled.
		if ( ! $hideRepeating && ! empty( $postIds ) ) {
			$repeating_args   = array(
				'post_type'       => 'seetickets-event',
				'post_status'     => 'publish',
				'posts_per_page'  => -1,
				'post_parent__in' => array_map( 'absint', $postIds ),
				'fields'          => 'ids',
			);
			$repeating_query  = new WP_Query( $repeating_args );
			$repeatingPostIds = $repeating_query->posts;

			if ( ! empty( $repeatingPostIds ) ) {
				$postIds = array_merge( $postIds, $repeatingPostIds );
			}
		}

		// Get events with pagination.
		if ( ! empty( $postIds ) ) {
			$events_args  = array(
				'post_type'      => 'seetickets-event',
				'post_status'    => 'publish',
				'posts_per_page' => absint( $limit ),
				'offset'         => absint( $offset ),
				'post__in'       => array_map( 'absint', $postIds ),
				'orderby'        => 'post__in',
			);
			$events_query = new WP_Query( $events_args );
			$events       = $events_query->posts;
			$totalPosts   = count( $postIds );
			$totalPages   = ceil( $totalPosts / $limit );
		} else {
			$events     = array();
			$totalPosts = 0;
			$totalPages = 0;
		}
	} else {
		$events     = array();
		$totalPages = 0;
	}

	$mainClasses = 'seetickets-list-events ';

	if ( $listType === 'g' ) {
		$mainClasses .= 'grid-container display-flex ';
	}

	$string .= '<div class="' . esc_attr( $mainClasses ) . '">';

	$nthItem = 0;

	foreach ( $events as $index => $event ) {
		$eventId           = is_object( $event ) ? $event->ID : $event;
		$eventSearchedData = array();
		foreach ( $fields as $field ) {
			$eventSearchedData[] = strtolower( get_post_meta( $eventId, $field, true ) );
		}

		if ( ! empty( $searchParameter ) ) {
			$foundMatch = false;
			foreach ( $eventSearchedData as $eventSearchedDataItem ) {
				if ( stripos( $eventSearchedDataItem, $searchParameter ) !== false ) {
					$foundMatch = true;
					break;
				}
			}

			if ( ! $foundMatch ) {
				continue;
			}
		}
		++$nthItem;

		$templateType = $listType === 'l' ? 'list' : 'grid';

		$string .= evusel_get_event_card( $eventId, $templateType, $columnAmount, $dimensionsPerColumn, $nthItem );
	}

	$string .= '</div>';

	if ( ! empty( $searchParameter ) && ! empty( $events ) ) {

		if ( $page < $totalPages ) {

			$serverRequestUri = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
			$queryArgs        = wp_parse_url( $serverRequestUri, PHP_URL_QUERY );
			$queryArgsArray   = array();
			if ( ! empty( $queryArgs ) ) {
				parse_str( $queryArgs, $queryArgsArray );
			}
			$queryString = '';
			if ( ! empty( $queryArgsArray ) ) {
				$queryString .= '&';
				$count        = 0;
				foreach ( $queryArgsArray as $key => $value ) {
					if ( $key === 'sepage' ) {
						continue;
					}
					++$count;
					$queryString .= esc_attr( $key ) . '=' . esc_attr( $value );
					if ( $count < count( $queryArgsArray ) ) {
						$queryString .= '&';
					}
				}
			}

			$paginator  = '';
			$paginator .= '<nav class="see-pagination"><ul>';

			for ( $pageNumber = 1; $pageNumber <= $totalPages; $pageNumber++ ) {

				$displayPageNumber = $pageNumber;
				if ( $pageNumber === $page ) {
					$paginator .= '<li><span>' . esc_html( $displayPageNumber ) . '</span></li>';
				} else {
					$paginator .= '<li><a href="?sepage=' . esc_attr( $pageNumber ) . esc_attr( $queryString ) . '">' . esc_html( $displayPageNumber ) . '</a></li>';
				}
			}

			$paginator .= '</ul></nav>';
			$string    .= $paginator;
		}
	}

	$string .= '</div>';

	return $string;
}

add_action( 'wp_ajax_evusel_get_events_search_results', 'evusel_get_events_search_results' );
add_action( 'wp_ajax_nopriv_evusel_get_events_search_results', 'evusel_get_events_search_results' );
function evusel_get_events_search_results() {
	$nonce = isset( $_GET['nonce'] ) ? sanitize_text_field( wp_unslash( $_GET['nonce'] ) ) : '';
	if ( empty( $nonce ) || ! wp_verify_nonce( $nonce, 'evusel-nonce' ) ) {
		wp_die( esc_html__( 'Security check failed', 'eventim-us-event-listings' ) );
	}

	global $evuselConfig;

	$listType = $evuselConfig->get( 'shortcodes.list_view.view_type' );
	$limit    = $evuselConfig->get( 'shortcodes.list_view.per_page' );

	$seeAjaxPage     = isset( $_REQUEST['seeAjaxPage'] ) ? intval( $_REQUEST['seeAjaxPage'] ) : 1;
	$offset          = ( $seeAjaxPage - 1 ) * $limit;
	$columnAmount    = $evuselConfig->get( 'shortcodes.list_view.column_amount' );
	$searchParameter = isset( $_REQUEST['searchParameter'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['searchParameter'] ) ) : '';
	$hideRepeating   = $evuselConfig->get( 'show_repeating_events' ) === false;

	$dimensionsPerColumn = $evuselConfig->get( 'imageDimensionsPerColumn' );
	$reqFields           = isset( $_REQUEST['fields'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['fields'] ) ) : '';
	$fields              = ! empty( $reqFields ) ? explode( ',', $reqFields ) : array();

	// If no fields are given, default to search everything
	if ( empty( $fields ) ) {
		$fields = array( 'location', 'genre', 'supporting_talent', 'headliners', 'event_title' );
	}

	$fields = array_map(
		function ( $key ) {
			return str_replace( 'location', 'venue', $key );
		},
		$fields
	);

	// Build meta query for search
	$meta_query = array( 'relation' => 'OR' );
	foreach ( $fields as $field ) {
		$meta_query[] = array(
			'key'     => sanitize_key( $field ),
			'value'   => $searchParameter,
			'compare' => 'LIKE',
		);
	}

	// Get matching post IDs using WP_Query
	$search_args = array(
		'post_type'      => 'seetickets-event',
		'post_status'    => 'publish',
		'posts_per_page' => -1,
		'post_parent'    => 0,
		'fields'         => 'ids',
        // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Required for search functionality
		'meta_query'     => $meta_query,
	);

	$search_query = new WP_Query( $search_args );
	$postIds      = $search_query->posts;

	// Get repeating events if enabled
	if ( ! $hideRepeating && ! empty( $postIds ) ) {
		$repeating_args   = array(
			'post_type'       => 'seetickets-event',
			'post_status'     => 'publish',
			'posts_per_page'  => -1,
			'post_parent__in' => array_map( 'absint', $postIds ),
			'fields'          => 'ids',
		);
		$repeating_query  = new WP_Query( $repeating_args );
		$repeatingPostIds = $repeating_query->posts;

		if ( ! empty( $repeatingPostIds ) ) {
			$postIds = array_merge( $postIds, $repeatingPostIds );
		}
	}

	// Get events with pagination
	if ( ! empty( $postIds ) ) {
		$events_args  = array(
			'post_type'      => 'seetickets-event',
			'post_status'    => 'publish',
			'posts_per_page' => absint( $limit ),
			'offset'         => absint( $offset ),
			'post__in'       => array_map( 'absint', $postIds ),
			'orderby'        => 'post__in',
		);
		$events_query = new WP_Query( $events_args );
		$events       = $events_query->posts;
	} else {
		$events = array();
	}

	$listType === 'l' ?
		$string = '<div class="seetickets-list-events">' :
		$string = '<div class="seetickets-list-events grid-container display-flex">';

	$nthItem = 0;

	foreach ( $events as $index => $event ) {
		$eventId           = is_object( $event ) ? $event->ID : $event;
		$eventSearchedData = array();
		foreach ( $fields as $field ) {
			$eventSearchedData[] = strtolower( get_post_meta( $eventId, $field, true ) );
		}

		$foundMatch = false;
		foreach ( $eventSearchedData as $eventSearchedDataItem ) {
			if ( stripos( $eventSearchedDataItem, $searchParameter ) !== false ) {
				$foundMatch = true;
				break;
			}
		}

		if ( ! $foundMatch ) {
			continue;
		}

		++$nthItem;

		$templateType = $listType === 'l' ? 'list' : 'grid';

		$string .= evusel_get_event_card( $eventId, $templateType, $columnAmount, $dimensionsPerColumn, $nthItem );
	}

	$string .= '</div>';

	echo wp_kses_post( $string );

	wp_die();
}
