<?php
namespace ThemeAtelier\EventfulForElementor\Frontend\Helpers;
use ThemeAtelier\EventfulForElementor\Frontend\Helpers\EventfulForElementorFunctions;

if (! defined('ABSPATH')) exit; // Exit if accessed directly

/**
 * The file of query insides.
 *
 * @package eventful-for-elementor
 * @subpackage public
 *
 * @since 2.2.0
 */

/**
 * The query inside class to process the query.
 *
 * @since 2.2.0
 */
class EventfulForElementorQueryinside
{

	/**
	 * The post ID.
	 *
	 * @var string post ID.
	 */

	/**
	 * Filtered content.
	 *
	 * @param integer $efpe_gl_id Shortcode ID.
	 * @return statement
	 */
	public static function get_filtered_content($view_options, $id, $layout_preset, $event_per_page, $event_limit, $efpe_settings, $on_screen = null)
	{
		$efpe_event_type    	= 'tribe_events';
		$view_post_per_page = isset($view_options['post_per_page']) ? $view_options['post_per_page'] : $event_per_page;
		$event_per_page 		= !empty($event_per_page) ? $event_per_page : $view_post_per_page;

		$event_limit 		= isset($event_limit) ? $event_limit : $view_options['efpe_post_limit'];
		$event_offset     	= isset($efpe_settings['efpe_post_offset']) ? $efpe_settings['efpe_post_offset'] : $view_options['efpe_post_offset'];
		$show_pagination 	= true;
		$event_per_page   	= ($event_per_page > $event_limit) ? $event_limit : $event_per_page;
		$event_per_page   	= (!$show_pagination) ? $event_limit : $event_per_page;

		if ('filter_layout' === $layout_preset) {
			$pagination_type = isset($view_options['filter_pagination_type']) ? $view_options['filter_pagination_type'] : '';
		} else {
			$pagination_type = isset($view_options['post_pagination_type']) ? $view_options['post_pagination_type'] : '';
			if ('on_mobile' === $on_screen) {
				$pagination_type = isset($view_options['post_pagination_type_mobile']) ? $view_options['post_pagination_type_mobile'] : '';
			}
		}

		if ('no_ajax' === $pagination_type) {
			$paged_var = 'paged' . $id;
			$paged     = isset($_GET["$paged_var"]) ? sanitize_text_field(wp_unslash($_GET["$paged_var"])) : 1;
		} else {
			$paged            = (get_query_var('paged')) ? get_query_var('paged') : 1;
			$filter_url_value = isset($_SERVER['QUERY_STRING']) ? sanitize_text_field(wp_unslash($_SERVER['QUERY_STRING'])) : '';
			if (!empty($filter_url_value)) {
				$shortcode_id = isset($_GET['pop']) ? sanitize_text_field(wp_unslash($_GET['pop'])) : '';
				if ($shortcode_id == $id) {
					$efpe_page = isset($_GET['efpe_page']) ? sanitize_text_field(wp_unslash($_GET['efpe_page'])) : '1';
					if (!empty($efpe_page)) {
						$paged = $efpe_page;
					}
				}
			}
		}

		$event_per_page = EventfulForElementorFunctions::efpe_post_per_page($event_limit, $event_per_page, $paged);
		if ($event_per_page < 1) {
			$view_post_per_page = isset($view_options['post_per_page']) ? $view_options['post_per_page'] : $view_post_per_page;
			$event_per_page = isset($efpe_settings['post_per_page']) ? $efpe_settings['post_per_page'] : $view_post_per_page;
		}
		$offset               = (int) $event_per_page * ($paged - 1);
		if ('carousel_layout' === $layout_preset) {
			$event_per_page = ($event_limit > 0) ? $event_limit : 999999;
			$args          = array(
				'post_type'           => $efpe_event_type,
				'suppress_filters'    => false,
				'posts_per_page'      => $event_per_page,
				'offset'              => (int) $event_offset,
			);
		} else {
			$args = array(
				'post_type'           => $efpe_event_type,
				'suppress_filters'    => false,
				'posts_per_page'      => $event_per_page,
				'paged'               => $paged,
				'offset'              => (int) $offset + (int) $event_offset,

			);
		}
		// Include specific posts.
		$efpe_include_only_posts = isset($view_options['efpe_include_only_posts']) ? $view_options['efpe_include_only_posts'] : array();
		$include_posts = isset($efpe_settings['efpe_include_only_posts']) ? $efpe_settings['efpe_include_only_posts'] : $efpe_include_only_posts;
		// Exclude posts.
		$efpe_exclude_too = !empty($view_options['efpe_exclude_too']) ? $view_options['efpe_exclude_too'] : array();
		$exclude_too       = isset($efpe_settings['efpe_exclude_too']) && !empty($efpe_settings['efpe_exclude_too']) ? $efpe_settings['efpe_exclude_too'] : $efpe_exclude_too;

		$current_post_id   = in_array('current', $exclude_too, true) ? array(get_the_ID()) : array();
		$efpe_exclude_post_set = isset($view_options['efpe_exclude_post_set']) ? $view_options['efpe_exclude_post_set'] : array();
		$exclude_posts     = !empty($efpe_settings['efpe_exclude_post_set']) && isset($efpe_settings['efpe_exclude_post_set']) ? $efpe_settings['efpe_exclude_post_set'] : $efpe_exclude_post_set;

		$exclude_posts_int = array();
		if (!empty($exclude_posts)) {
			foreach ($exclude_posts as $exclude_post) {
				$exclude_posts_int[] = intval($exclude_post);
			}
		}
		$exclude_post_list = array_merge($exclude_posts_int, $current_post_id);


		if (!empty($exclude_post_list) && !empty($include_posts)) {
			$include_posts = array_diff($include_posts, $exclude_post_list);
		} elseif (!empty($exclude_post_list)) {
			$args['post__not_in'] = ($exclude_post_list);
		}
		// Include specific posts.
		if (!empty($include_posts)) {
			$args['post__in'] = $include_posts;
			$args['orderby']  = 'ID';
		}

		// Exclude password protected posts.
		$password_protected = in_array('password_protected', $exclude_too, true);
		if ($password_protected) {
			$args['has_password'] = false;
		}
		$args['post_status'] = 'publish';
		$args['orderby'] = '_EventStartDate';
		$args['order'] = 'ASC';

		if (empty($include_posts) && empty($exclude_too)) {
			$efpe_event_type = isset($efpe_settings['efpe_event_type']) ? $efpe_settings['efpe_event_type'] : $view_options['efpe_event_type'];
			$args['meta_key']    = '_EventStartDate';
			$meta_date_compare = '>=';
			if ($efpe_event_type == 'past') {
				$meta_date_compare = '<';
			} elseif ($efpe_event_type == 'all') {
				$meta_date_compare = '';
			}
			$attribute['key']       = '_EventStartDate';
			$attribute['meta_date'] = '';
			$meta_date_date         = '';
			if ($meta_date_compare != '') {
				$meta_date_date         = current_time('Y-m-d H:i:s');
				$attribute['key']       = '_EventStartDate';
				$attribute['meta_date'] = array(
					array(
						'key'     => '_EventEndDate',
						'value'   => $meta_date_date,
						'compare' => $meta_date_compare,
						'type'    => 'DATETIME',
					),
				);
			}
			$ect_args = apply_filters(
				'efpe_event_args_filter',
				array(
					'meta_key'       => $attribute['key'],
					'meta_query'     => $attribute['meta_date'],
				),
				$attribute,
				$meta_date_date,
				$meta_date_compare
			);
			$args                      = array_merge($args, $ect_args);
		} else {
			$args['meta_key']    = '_EventStartDate';
		}

		$meta_query = array();
		/**
		 * 🔹 Hide free events (no price)
		 */
		$hide_free_events = isset($efpe_settings['hide_free_events']) ? $efpe_settings['hide_free_events'] : $view_options['hide_free_events'];
		if (!empty($hide_free_events)) {
			$meta_query[] = array(
				'key'     => '_EventCost',
				'compare' => 'EXISTS',
			);

			$meta_query[] = array(
				'key'     => '_EventCost',
				'value'   => '',
				'compare' => '!=',
			);
		}

		/**
		 * 🔹 Hide events without featured image
		 */
		$hide_event_without_thumbnail = isset($efpe_settings['hide_event_without_thumbnail']) ? $efpe_settings['hide_event_without_thumbnail'] : $view_options['hide_event_without_thumbnail'];
		if (!empty($hide_event_without_thumbnail)) {
			$meta_query[] = array(
				'key'     => '_thumbnail_id',
				'compare' => 'EXISTS',
			);
		}

		// Assign back
		$args['meta_query'] = $meta_query;

		$advanced_filters    = isset($efpe_settings['efpe_advanced_filter']) && !empty($efpe_settings['efpe_advanced_filter']) ? $efpe_settings['efpe_advanced_filter'] : $view_options['efpe_advanced_filter'];
		if ($advanced_filters) {
			foreach ($advanced_filters as $advanced_filter) {

				switch ($advanced_filter) {
					case 'taxonomy':
						$taxonomy_options = isset($view_options['taxonomy_options']) ? $view_options['taxonomy_options'] : array();
						$taxonomy_types = isset($efpe_settings['taxonomy_options']) && !empty($efpe_settings['taxonomy_options']) ? $efpe_settings['taxonomy_options'] : $taxonomy_options;
						if (!$taxonomy_types) {
							break;
						}
						$tax_settings = array();
						foreach ($taxonomy_types as $tax_type) {
							$taxonomy = isset($tax_type['select_taxonomy']) ? $tax_type['select_taxonomy'] : '';
							$all_terms = get_terms($taxonomy);
							$terms = isset($tax_type['efpe_select_terms']) && !empty($tax_type['efpe_select_terms']) ? $tax_type['efpe_select_terms'] : $all_terms;
							$all_button_label = isset($tax_type['ajax_rename_all_text']) ? $tax_type['ajax_rename_all_text'] : '';

							if ($taxonomy) {
								if ($terms) {
									$operator = isset($tax_type['taxonomy_term_operator']) ? $tax_type['taxonomy_term_operator'] : '';

									if ('AND' === $operator && 1 == count($terms)) {
										$operator = 'IN';
									}
									$term_ids = wp_list_pluck($terms, 'term_id');

									$tax_settings[] = array(
										'taxonomy'         => $taxonomy,
										'field'            => 'term_id',
										'terms'            => $all_button_label ? $term_ids : $term_ids[0],
										'operator'         => $operator,
										'include_children' => ('AND' === $operator ? 'false' : 'true'),
									);
								}
							}
						}

						if (count($tax_settings) > 1) {
							$tax_settings['relation'] = isset($efpe_settings['taxonomy_relation']) ? $efpe_settings['taxonomy_relation'] : $view_options['taxonomy_relation'];
						}
						$args = array_merge($args, array('tax_query' => $tax_settings));
						break;
					case 'author':
						$author_include = isset($efpe_settings['select_author']) ? $efpe_settings['select_author'] : $view_options['select_author'];
						$author_exclude = isset($efpe_settings['select_not_author']) ? $efpe_settings['select_not_author'] : $view_options['select_not_author'];
						$wp37           = EventfulForElementorFunctions::wp_version_compare('3.7');
						if ($author_include) {
							$args = array_merge(
								$args,
								$wp37 ? array('author__in' => array_map('intval', $author_include)) : array('author' => intval($author_include[0]))
							);
						}
						if ($author_exclude && $wp37) {
							$args = array_merge(
								$args,
								array('author__not_in' => array_map('intval', $author_exclude))
							);
						}
						break;
					case 'sortby':
						$orderby = isset($view_options['select_sortby']) ? $view_options['select_sortby'] : '_EventStartDate';
						$orderby = isset($efpe_settings['select_sortby']) ? $efpe_settings['select_sortby'] : $orderby;
						$select_filter_order = isset($view_options['select_filter_order']) ? $view_options['select_filter_order'] : 'ASC';
						$order   = isset($efpe_settings['select_filter_order']) ? $efpe_settings['select_filter_order'] : $select_filter_order;

						if ('custom_field' === $orderby) {
						} else {
							if ('rand' === $orderby) {
								if ($paged && get_query_var('paged') === 0 && get_query_var('paged') !== null) {
									set_transient('efpe_rand', wp_rand());
								}
							}
							$order_settings = array(
								'orderby' => ('rand' === $orderby) ? 'rand(' . get_transient('efpe_rand') . ')' : $orderby,
								'order'   => $orderby ? $order : '',
							);
							$args           = array_merge($args, $order_settings);
						}

						break;
					case 'status':
						$efpe_event_status = isset($efpe_settings['select_status']) && !empty($efpe_settings['select_status']) ? $efpe_settings['select_status'] : $view_options['select_status'];
						$args            = array_merge($args, array('post_status' => $efpe_event_status));
						break;
					case 'date':
						self::efpe_filter_by_date($args, $view_options, $efpe_settings);
						break;
					case 'keyword':
						$keyword_value = isset($efpe_settings['efpe_set_post_keyword']) && !empty($efpe_settings['efpe_set_post_keyword']) ? $efpe_settings['efpe_set_post_keyword'] : $view_options['efpe_set_post_keyword'];
						if ($keyword_value) {
							$args = array_merge(
								$args,
								array(
									's' => $keyword_value,
								)
							);
						}
						break;
				}
			}
		}

		$filter_url_value = isset($_SERVER['QUERY_STRING']) ? sanitize_text_field(wp_unslash($_SERVER['QUERY_STRING'])) : '';
		if (!empty($filter_url_value)) {
			$shortcode_id = isset($_GET['pop']) ? sanitize_text_field(wp_unslash($_GET['pop'])) : '';
			if ($shortcode_id == $id) {
				$url_args           = $args;
				$url_args['fields'] = 'ids';
				$relation           = isset($efpe_settings['taxonomies_relation']) ? $efpe_settings['taxonomies_relation'] : 'AND';


				$taxonomies          = get_object_taxonomies($efpe_event_type);
				$tax_settings_by_url = array();
				foreach ($taxonomies as $taxonomy) {
					$filter_url_value = isset($_GET["tx_$taxonomy"]) ? sanitize_text_field(wp_unslash($_GET["tx_$taxonomy"]))  : '';
					if (!empty($filter_url_value)) {
						if (strpos($filter_url_value, ',') !== false) {
							$filter_url_value = explode(',', $filter_url_value);
						}
						$tax_settings_by_url[] = array(
							'taxonomy' => $taxonomy,
							'field'    => 'term_id',
							'terms'    => $filter_url_value,
							'operator' => 'IN',
						);
					}
				}
				if (!empty($tax_settings_by_url)) {

					if (count($tax_settings_by_url) > 1) {
						$tax_settings_by_url['relation'] = $relation;
					}
					if ('OR' === $relation) {
						$url_args['posts_per_page'] = '10000';
					}
					$url_post_ids     = get_posts($url_args);
					$args             = array_merge($args, array('tax_query' => $tax_settings_by_url));
					$args['post__in'] = $url_post_ids;
				}
				$final_author_url_value = isset($_GET['efpe_author_id']) ? sanitize_text_field(wp_unslash($_GET['efpe_author_id'])) : '';
				if (!empty($final_author_url_value)) {
					$args['author__in'] = $final_author_url_value;
				}
				$final_orderby_url_value = isset($_GET['efpe_orderby']) ? sanitize_text_field(wp_unslash($_GET['efpe_orderby'])) : '';
				if (!empty($final_orderby_url_value)) {
					$args['orderby'] = $final_orderby_url_value;
				}
				$final_order_url_value = isset($_GET['efpe_order']) ? sanitize_text_field(wp_unslash($_GET['efpe_order'])) : '';
				if (!empty($final_order_url_value)) {
					$args['order'] = $final_order_url_value;
				}
				$final_search_url_value = isset($_GET['efpe_keyword']) ? sanitize_text_field(wp_unslash($_GET['efpe_keyword'])) : '';
				if (!empty($final_search_url_value)) {
					$args['s'] = $final_search_url_value;
				}
			}
		}
		if ('attachment' == $efpe_event_type) {
			$args['post_status'] = 'inherit';
		}
		return $args;
	}

	/**
	 * Filter posts with date.
	 *
	 * @param array $args The arguments of the query.
	 * @param array $view_options The Array of the Metabox fields.
	 * @return void
	 */
	public static function efpe_filter_by_date(&$args, $view_options, $efpe_settings)
	{
		$advanced_filters = isset($efpe_settings['efpe_advanced_filter']) && !empty($efpe_settings['efpe_advanced_filter']) ? $efpe_settings['efpe_advanced_filter'] : $view_options['efpe_advanced_filter'];

		if (in_array('date', $advanced_filters, true)) {
			$_date_type_to_filter = isset($efpe_settings['select_date']) && !empty($efpe_settings['select_date']) ? $efpe_settings['select_date'] : $view_options['select_date'];
			$now                  = new \DateTime('now');
			$today                = $now->format('j'); // A numeric representation of a month without 0.
			$this_month           = $now->format('n'); // A numeric representation of a month without 0.
			$this_year            = $now->format('Y');
			$date_query           = array();
			if ($_date_type_to_filter) {
				switch ($_date_type_to_filter) {
					case 'yesterday':
						$yesterday = gmdate('Y-m-d', strtotime('yesterday'));
						$date      = date_parse($yesterday);

						$date_query = array(
							'year'  => $date['year'],
							'month' => $date['month'],
							'day'   => $date['day'],
						);
						break;

					case 'today_only':
						$date_query = array(
							'year'  => $this_year,
							'month' => $this_month,
							'day'   => $today,
						);
						break;

					case 'today_onwards':
						$yesterday  = gmdate('Y-m-d', strtotime('yesterday'));
						$date_query = array(
							'after' => $yesterday,
						);
						break;

					case 'this_week':
						$date_query = array(
							'year' => $this_year,
							'week' => $now->format('W'),
						);
						break;

					case 'this_month':
						$date_query = array(
							'year'  => $this_year,
							'month' => $this_month,
						);
						break;

					case 'this_year':
						$date_query = array(
							'year' => $this_year,
						);
						break;

					case 'week_ago':
					case 'month_ago':
					case 'year_ago':
						$date_query = array(
							'column' => 'post_date',
							'after'  => sprintf('1 %s ago', str_replace('_ago', '', $_date_type_to_filter)),
						);
						break;

					case 'specific_date':
						$_specific_date = isset($efpe_settings['select_post_specific_date']) && !empty($efpe_settings['select_post_specific_date']) ? $efpe_settings['select_post_specific_date'] : $view_options['select_post_specific_date'];
						$specific_date  = date_parse($_specific_date);
						$date_query     = array(
							'year'  => $specific_date['year'],
							'month' => $specific_date['month'],
							'day'   => $specific_date['day'],
						);
						break;

					case 'specific_month':
						$post_published_in_month = isset($efpe_settings['select_specific_month']) && !empty($efpe_settings['select_specific_month']) ? $efpe_settings['select_specific_month'] : $view_options['select_specific_month'];
						$date_query              = array(
							'month' => $post_published_in_month,
						);
						break;

					case 'specific_year':
						$post_published_in_year = isset($efpe_settings['select_post_specific_year']) && !empty($efpe_settings['select_post_specific_year']) ? $efpe_settings['select_post_specific_year'] : $view_options['select_post_specific_year'];

						$date_query = array(
							'year' => $post_published_in_year,
						);
						break;

					case 'specific_period':
						$_date_from = isset($efpe_settings['select_post_date_from']) ? $efpe_settings['select_post_date_from'] : $view_options['select_post_date_from'];
						$_date_to = isset($efpe_settings['select_post_date_to']) ? $efpe_settings['select_post_date_to'] : $view_options['select_post_date_to'];

						$_date_from    = isset($_date_from) ? $_date_from : $today;
						$_date_to      = isset($_date_to) ? $_date_to : $today;
						$date_from     = date_parse($_date_from);
						$date_to       = date_parse($_date_to);
						if ($date_from && $date_to) {
							$date_query = array(
								'after'     => array(
									'year'  => $date_from['year'],
									'month' => $date_from['month'],
									'day'   => $date_from['day'],
								),
								'before'    => array(
									'year'  => $date_to['year'],
									'month' => $date_to['month'],
									'day'   => $date_to['day'],
								),
								'inclusive' => true,
							);
						}
						break;
				}
				if ($date_query) {
					$args['date_query'] = array($date_query);
				}
			}
		}
	}
}
