<?php

function bw_upcoming_courses_request ($request) {

	$category = $request->get_param('category');
	if (empty($category)) $category = false;

	$program_exclude = $request->get_param('program_exclude');
	if (empty($program_exclude) || !is_array($program_exclude)) $program_exclude = false;

	$program_include = $request->get_param('program_include');
	if (empty($program_include) || !is_array($program_include)) $program_include = false;

	$posts_per_page = $request->get_param('posts_per_page');
	if (empty($posts_per_page)) $posts_per_page = 12;

	$paged = $request->get_param('paged');
	if (empty($paged)) $paged = 1;

	$grouping = $request->get_param('grouping');
	if (empty($grouping)) $grouping = false;

	$sort = $request->get_param('sort');
	if (empty($sort) || !is_array($sort)) $sort = array();

	$date = $request->get_param('date');
	if (empty($date)) $date = '_EventStartDate';

	$featured = $request->get_param('featured');
	if (empty($featured)) $featured = false;

	return bw_upcoming_courses($category, $program_exclude, $program_include, $posts_per_page, $paged, $grouping, $sort, $date, $featured);
}

function bw_upcoming_courses ($category, $program_exclude, $program_include, $posts_per_page = 20, $paged = 1, $grouping = false, $sort = array(), $date = '_EventStartDate', $featured = false) {
	global $wpdb;

	if ($grouping === 'content_block') {
		return uppcoming_courses_by_content($category, $program_exclude, $program_include, $posts_per_page, $paged, $sort, $date, $featured);
	} else if ( $grouping === 'city' ) {
		return uppcoming_courses_by_city($category, $program_exclude, $program_include, $posts_per_page, $paged, $sort, $date, $featured);
	} else if ( $grouping === 'agency' ) {
		return uppcoming_courses_by_agency($category, $program_exclude, $program_include, $posts_per_page, $paged, $sort, $date, $featured);
	} else {
		return uppcoming_courses_by_none($category, $program_exclude, $program_include, $posts_per_page, $paged, $sort, $date, $featured);
	}
	return new stdClass();
}

function uppcoming_courses_by_content ($category, $program_exclude, $program_include, $posts_per_page = 20, $paged = 1, $sort = array(), $date = '_EventStartDate', $featured = false) {
	global $wpdb;
	// get list of ids of valid courses
	$query = $wpdb->prepare(
		"SELECT DISTINCT pmc.meta_value
		FROM $wpdb->posts AS p
		INNER JOIN $wpdb->term_relationships AS trc ON (p.ID = trc.object_id)
		INNER JOIN $wpdb->term_relationships AS trp ON (p.ID = trp.object_id)
		INNER JOIN $wpdb->term_taxonomy AS ttc ON (trc.term_taxonomy_id = ttc.term_taxonomy_id)
		INNER JOIN $wpdb->term_taxonomy AS ttp ON (trp.term_taxonomy_id = ttp.term_taxonomy_id)
		INNER JOIN $wpdb->postmeta AS pmd ON pmd.post_id = p.ID
		INNER JOIN $wpdb->postmeta AS pmc ON pmc.post_id = p.ID
		" . ($featured ? "INNER JOIN $wpdb->postmeta AS pmf ON pmf.post_id = p.ID" : '') . "
		WHERE p.post_status = 'publish'
			AND p.post_type = 'tribe_events'
			AND ttc.taxonomy = 'tribe_events_cat'
			AND ttp.taxonomy = 'program'
			" . (empty($category) ? "" : "AND ttc.term_id = (" . intval($category) . ")" ) . "
			" . (empty($program_exclude) || !is_array($program_exclude) ? "" : "AND ttp.term_id NOT IN (" . implode(', ', array_map('intval', $program_exclude)) . ")" ) . "
			" . (empty($program_include) || !is_array($program_include) ? "" : "AND ttp.term_id IN (" . implode(', ', array_map('intval', $program_include)) . ")" ) . "
			" . ($featured ? "AND pmf.meta_key = 'featured' AND pmf.meta_value = '1'" : "") . "
			AND pmc.meta_key = 'content_block'
			AND pmd.meta_key = '_EventStartDate'
			AND pmd.meta_value > %s",
		date('Y-m-d 00:00:00', strtotime('now'))
	);
	$results = $wpdb->get_col($query);

	$course_ids = array();
	foreach ($results as $id => $result) {
		$result = unserialize($result);
		if (!is_array($result) || empty($result)) continue;
		foreach ($result as $id) {
			$course_ids[] = $id;
		}
	}

	$args = array(
		'post_type'      => 'course',
		'posts_per_page' => $posts_per_page,
		'paged'          => $paged,
		'post__in'       => $course_ids,
		'orderby'        => array(
			'title' => 'ASC'
		)
	);

	$data = new stdClass();
	$data->posts = array();
	if (empty($course_ids)) return $data;
	
	$courses = array();

	$results = new WP_Query($args);
	$data->found_posts = $results->found_posts;
	$data->post_count = $results->post_count;
	$data->cumulative_count = $results->post_count + max($paged - 1, 0) * $posts_per_page;
	while ($results->have_posts()) {
		$results->the_post();
		$courses[get_the_ID()] = get_the_title();

	}
	wp_reset_postdata();

	foreach ($courses as $id => $title) {
		$data->posts[] = $post = new stdClass();
		$post->title = $title;
		$post->id = $id;
		$post->events = array();
		$args = array(
			'post_type'      => 'tribe_events',
			'posts_per_page' => -1,
			'meta_query'     => array(
				$date . '_clause' => array(
					'key'     => $date,
					'value'   => date('Y-m-d 00:00:00', strtotime('now')),
					'compare' => '>'
				),
				'content_block_clause' => array(
					'key'     => 'content_block',
					'value'   => $id,
					'compare' => 'LIKE'
				)
			),
			'orderby'        => array()
		);
		foreach ($sort as $s) {
			$args['orderby'][$s['field']] = $s['order'];
			if (preg_match('/^(\w+)_clause$/', $s['field'], $matches) && !isset($args['meta_query'][$s['field']])) {
				$args['meta_query'][$s['field']] = array(
					'key' => $matches[1],
					'compare' => 'EXISTS'
				);
			}
		}
		if ($featured) {
			$args['meta_query']['featured_clause'] = array(
				'key' => 'featured',
				'value' => '1',
				'compare' => '='
			);
		}
		$results = new WP_Query($args);
		while ($results->have_posts()) {
			$results->the_post();
			$event = array();

			// use venue city if possible otherwise get city from meta
			$event['city'] = tribe_get_city(get_the_ID());
			if (empty($event['city'])) $event['city'] = get_field('city', get_the_ID());
			
			$category_terms = wp_get_post_terms(get_the_ID(), 'tribe_events_cat');
			if (is_array($category_terms) && count($category_terms)) $event['category'] = $category_terms[0]->name;

			$event['startDate'] = tribe_get_start_date(get_the_ID(), false, 'M j Y');
			$event['endDate'] = tribe_get_end_date(get_the_ID(), false, 'M j Y');
			$event['link'] = get_permalink(get_the_ID());
			$event['title'] = get_the_title(get_the_ID());
			
			$post->events[] = $event;

		}
		wp_reset_postdata();


	}

	return $data;
}

function uppcoming_courses_by_city ($category, $program_exclude, $program_include, $posts_per_page = 20, $paged = 1, $sort = array(), $date = '_EventStartDate', $featured = false) {
	$args = array(
		'post_type'      => 'tribe_events',
		'posts_per_page' => $posts_per_page,
		'paged'          => $paged,
		'tax_query'      => array(
			'relation' => 'AND'
		),
		'meta_query'     => array(
			'relation' => 'AND',
			$date . '_clause' => array(
				'key'     => $date,
				'value'   => date('Y-m-d 00:00:00', strtotime('now')),
				'compare' => '>'
			),
			'city_clause_1' => array(
				'key'     => 'city',
				'compare' => 'EXISTS'
			),
			'city_clause_2' => array(
				'key'     => 'city',
				'value'   => '',
				'compare' => '!='
			)
		),
		'orderby'        => array(
			'city_clause_1' => 'ASC'
		)
	);
	foreach ($sort as $s) {
		$args['orderby'][$s['field']] = $s['order'];
		if (preg_match('/^(\w+)_clause$/', $s['field'], $matches) && !isset($args['meta_query'][$s['field']])) {
			$args['meta_query'][$s['field']] = array(
				'key' => $matches[1],
				'compare' => 'EXISTS'
			);
		}
	}
	if ($featured) {
		$args['meta_query']['featured_clause'] = array(
			'key' => 'featured',
			'value' => '1',
			'compare' => '='
		);
	}
	if (!empty($category)) {
		$args['tax_query'][] = array(
			'taxonomy' => 'tribe_events_cat',
			'terms'    => $category,
			'field'    => 'term_id'
		);
	}
	if (is_array($program_exclude)) {
		$args['tax_query'][] = array(
			'taxonomy' => 'program',
			'terms'    => $program_exclude,
			'field'    => 'term_id',
			'operator'  => 'NOT IN' 
		);
	}
	if (is_array($program_include)) {
		$args['tax_query'][] = array(
			'taxonomy' => 'program',
			'terms'    => $program_include,
			'field'    => 'term_id',
			'operator'  => 'IN' 
		);
	}

	$data = new stdClass();
	$data->posts = array();
	$cities = array();

	$results = new WP_Query($args);
	$data->args = $args;
	$data->found_posts = $results->found_posts;
	$data->post_count = $results->post_count;
	$data->cumulative_count = $results->post_count + max($paged - 1, 0) * $posts_per_page;
	while ($results->have_posts()) {
		$results->the_post();
		$city = get_field('city', get_the_ID());
		if (empty($city)) continue;
		$event = array();
		$event['city'] = $city;

		$category_terms = wp_get_post_terms(get_the_ID(), 'tribe_events_cat');
		if (is_array($category_terms) && count($category_terms)) $event['category'] = $category_terms[0]->name;

		$event['title'] = get_the_title();
		$event['startDate'] = tribe_get_start_date(get_the_ID(), false, 'M j Y');
		$event['endDate'] = tribe_get_end_date(get_the_ID(), false, 'M j Y');
		$event['link'] = get_permalink(get_the_ID());
		if (!isset($cities[$city])) $cities[$city] = array();
		$cities[$city][] = $event;
	}
	wp_reset_postdata();

	foreach ($cities as $city => $events) {
		$data->posts[] = $post = new stdClass();
		$post->title = $city;
		$post->id = $city;
		$post->events = $events;
	}

	return $data;
}

function uppcoming_courses_by_agency ($category, $program_exclude, $program_include, $posts_per_page = 20, $paged = 1, $sort = array(), $date = '_EventStartDate', $featured = false) {
	$args = array(
		'post_type'      => 'tribe_events',
		'posts_per_page' => $posts_per_page,
		'paged'          => $paged,
		'tax_query'      => array(
			'relation' => 'AND'
		),
		'meta_query'     => array(
			'relation' => 'AND',
			$date . '_clause' => array(
				'key'     => $date,
				'value'   => date('Y-m-d 00:00:00', strtotime('now')),
				'compare' => '>'
			),
			'agency_clause_1' => array(
				'key'     => 'agency',
				'compare' => 'EXISTS'
			),
			'agency_clause_2' => array(
				'key'     => 'agency',
				'value'   => '',
				'compare' => '!='
			)
		),
		'orderby'        => array(
			'agency_clause_1' => 'ASC'
		)
	);
	foreach ($sort as $s) {
		$args['orderby'][$s['field']] = $s['order'];
		if (preg_match('/^(\w+)_clause$/', $s['field'], $matches) && !isset($args['meta_query'][$s['field']])) {
			$args['meta_query'][$s['field']] = array(
				'key' => $matches[1],
				'compare' => 'EXISTS'
			);
		}
	}
	if ($featured) {
		$args['meta_query']['featured_clause'] = array(
			'key' => 'featured',
			'value' => '1',
			'compare' => '='
		);
	}
	if (!empty($category)) {
		$args['tax_query'][] = array(
			'taxonomy' => 'tribe_events_cat',
			'terms'    => $category,
			'field'    => 'term_id'
		);
	}
	if (is_array($program_exclude)) {
		$args['tax_query'][] = array(
			'taxonomy' => 'program',
			'terms'    => $program_exclude,
			'field'    => 'term_id',
			'operator'  => 'NOT IN' 
		);
	}
	if (is_array($program_include)) {
		$args['tax_query'][] = array(
			'taxonomy' => 'program',
			'terms'    => $program_include,
			'field'    => 'term_id',
			'operator'  => 'IN' 
		);
	}

	$data = new stdClass();
	$data->posts = array();
	$cities = array();

	$results = new WP_Query($args);
	$data->args = $args;
	$data->found_posts = $results->found_posts;
	$data->post_count = $results->post_count;
	$data->cumulative_count = $results->post_count + max($paged - 1, 0) * $posts_per_page;
	while ($results->have_posts()) {
		$results->the_post();
		$agency = get_field('agency', get_the_ID());
		if (empty($agency)) continue;
		$event = array();
		$event['agency'] = $agency;

		$category_terms = wp_get_post_terms(get_the_ID(), 'tribe_events_cat');
		if (is_array($category_terms) && count($category_terms)) $event['category'] = $category_terms[0]->name;

		$event['title'] = get_the_title();
		$event['startDate'] = tribe_get_start_date(get_the_ID(), false, 'M j Y');
		$event['endDate'] = tribe_get_end_date(get_the_ID(), false, 'M j Y');
		$event['link'] = get_permalink(get_the_ID());
		if (!isset($cities[$agency])) $cities[$agency] = array();
		$cities[$agency][] = $event;
	}
	wp_reset_postdata();

	foreach ($cities as $agency => $events) {
		$data->posts[] = $post = new stdClass();
		$post->title = $agency;
		$post->id = $agency;
		$post->events = $events;
	}

	return $data;
}

function uppcoming_courses_by_none ($category, $program_exclude, $program_include, $posts_per_page = 20, $paged = 1, $sort = array(), $date = '_EventStartDate', $featured = false) {
	$args = array(
		'post_type'      => 'tribe_events',
		'posts_per_page' => $posts_per_page,
		'paged'          => $paged,
		'tax_query'      => array(
			'relation' => 'AND'
		),
		'meta_query'     => array(
			'relation' => 'AND',
			$date . '_clause' => array(
				'key'     => $date,
				'value'   => date('Y-m-d 00:00:00', strtotime('now')),
				'compare' => '>'
			)
		),
		'orderby'        => array()
	);
	foreach ($sort as $s) {
		$args['orderby'][$s['field']] = $s['order'];
		if (preg_match('/^(\w+)_clause$/', $s['field'], $matches) && !isset($args['meta_query'][$s['field']])) {
			$args['meta_query'][$s['field']] = array(
				'key' => $matches[1],
				'compare' => 'EXISTS'
			);
		}
	}
	if ($featured) {
		$args['meta_query']['featured_clause'] = array(
			'key' => 'featured',
			'value' => '1',
			'compare' => '='
		);
	}
	if (!empty($category)) {
		$args['tax_query'][] = array(
			'taxonomy' => 'tribe_events_cat',
			'terms'    => $category,
			'field'    => 'term_id'
		);
	}
	if (is_array($program_exclude)) {
		$args['tax_query'][] = array(
			'taxonomy' => 'program',
			'terms'    => $program_exclude,
			'field'    => 'term_id',
			'operator'  => 'NOT IN' 
		);
	}
	if (is_array($program_include)) {
		$args['tax_query'][] = array(
			'taxonomy' => 'program',
			'terms'    => $program_include,
			'field'    => 'term_id',
			'operator'  => 'IN' 
		);
	}

	$data = new stdClass();
	$data->posts = array();
	$events = array();

	$results = new WP_Query($args);
	$data->found_posts = $results->found_posts;
	$data->post_count = $results->post_count;
	$data->cumulative_count = $results->post_count + max($paged - 1, 0) * $posts_per_page;
	while ($results->have_posts()) {
		$results->the_post();
		$event = array();
		$event['city'] = get_field('city', get_the_ID());
		
		$category_terms = wp_get_post_terms(get_the_ID(), 'tribe_events_cat');
		if (is_array($category_terms) && count($category_terms)) $event['category'] = $category_terms[0]->name;

		$event['title'] = get_the_title();
		$event['startDate'] = tribe_get_start_date(get_the_ID(), false, 'M j Y');
		$event['endDate'] = tribe_get_end_date(get_the_ID(), false, 'M j Y');
		$event['link'] = get_permalink(get_the_ID());
		$events[] = $event;
	}
	wp_reset_postdata();

	$data->posts[] = array(
		'title' => '',
		'id' => 'none',
		'events' => $events
	);

	return $data;
}
