<?php
/**
 * HVAC Community Events Dashboard Data Handler
 *
 * Retrieves and calculates data needed for the Trainer Dashboard.
 *
 * @package    HVAC Community Events
 * @subpackage Includes
 * @author     Roo
 * @version    1.0.0
 */

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

/**
 * Class HVAC_Dashboard_Data
 *
 * Handles fetching and processing data for the trainer dashboard.
 */
class HVAC_Dashboard_Data {

	/**
	 * The ID of the trainer user.
	 *
	 * @var int
	 */
	private int $user_id;

	/**
	 * Constructor.
	 *
	 * @param int $user_id The ID of the trainer user.
	 */
	public function __construct( int $user_id ) {
		$this->user_id = $user_id;
	}

	/**
	 * Get the total number of events created by the trainer.
	 *
	 * @return int
	 */
	public function get_total_events_count() : int {
		$args = array(
			'post_type'      => Tribe__Events__Main::POSTTYPE,
			'author'         => $this->user_id, // Query by post author, not organizer
			'post_status'    => array( 'publish', 'future', 'draft', 'pending', 'private' ),
			'posts_per_page' => -1,
			'fields'         => 'ids', // Only need the count
		);
		$query = new WP_Query( $args );
		return (int) $query->found_posts;
	}

	/**
	 * Get the number of upcoming events for the trainer.
	 *
	 * @return int
	 */
	public function get_upcoming_events_count() : int {
	 $today = date( 'Y-m-d H:i:s' );
	 $args  = array(
	 	'post_type'      => Tribe__Events__Main::POSTTYPE,
	 	// 'author'         => $this->user_id, // Query by organizer instead
	 	'post_status'    => array( 'publish', 'future' ), // Only published or scheduled future events
	 	'posts_per_page' => -1,
	 	'fields'         => 'ids', // Only need the count
	 	'meta_query'     => array(
	 		'relation' => 'AND', // Combine organizer and date query
	 		array(
	 			'key'     => '_EventOrganizerID',
	 			'value'   => $this->user_id,
	 			'compare' => '=',
	 			'type'    => 'NUMERIC', // Specify numeric comparison
	 		),
	 		array(
	 			'key'     => '_EventStartDate',
	 			'value'   => $today,
	 			'compare' => '>=',
	 			'type'    => 'DATETIME',
	 		),
	 	),
	 	'orderby'        => 'event_date',
	 	'order'          => 'ASC',
	 );
	 $query = new WP_Query( $args );
	 return (int) $query->found_posts;
	}

	/**
	 * Get the number of past events for the trainer.
	 *
	 * @return int
	 */
	public function get_past_events_count() : int {
	 $today = date( 'Y-m-d H:i:s' );
	 $args  = array(
	 	'post_type'      => Tribe__Events__Main::POSTTYPE,
	 	// 'author'         => $this->user_id, // Query by organizer instead
	 	'post_status'    => array( 'publish', 'private' ), // Count published or private past events
	 	'posts_per_page' => -1,
	 	'fields'         => 'ids', // Only need the count
	 	'meta_query'     => array(
	 		'relation' => 'AND', // Combine organizer and date query
	 		array(
	 			'key'     => '_EventOrganizerID',
	 			'value'   => $this->user_id,
	 			'compare' => '=',
	 			'type'    => 'NUMERIC', // Specify numeric comparison
	 		),
	 		array(
	 			'key'     => '_EventEndDate', // Use end date to determine if it's truly past
	 			'value'   => $today,
	 			'compare' => '<',
	 			'type'    => 'DATETIME',
	 		),
	 	),
	 );
	 $query = new WP_Query( $args );
	 return (int) $query->found_posts;
	}

	/**
	 * Get the total number of tickets sold across all the trainer's events.
	 *
	 * @return int
	 */
	public function get_total_tickets_sold() : int {
	 $total_tickets = 0;
	 $args = array(
	 	'post_type'      => Tribe__Events__Main::POSTTYPE,
	 	// 'author'         => $this->user_id, // Query by organizer instead
	 	'post_status'    => array( 'publish', 'future', 'draft', 'pending', 'private' ), // Include all statuses for historical data
	 	'posts_per_page' => -1,
	 	'fields'         => 'ids', // Only need the IDs
	 	'meta_key'       => '_EventOrganizerID',
	 	'meta_value'     => $this->user_id,
	 	'meta_compare'   => '=', // Explicitly set compare
	 	'meta_type'      => 'NUMERIC', // Specify numeric comparison
	 );
	 $event_ids = get_posts( $args );

	 if ( ! empty( $event_ids ) ) {
	 	foreach ( $event_ids as $event_id ) {
	 		// Check both meta keys that might store sold count
	 		$sold = get_post_meta( $event_id, '_tribe_tickets_sold', true );
	 		if (!is_numeric($sold)) {
	 			// Try alternative meta key used in the test script
	 			$sold = get_post_meta( $event_id, '_tribe_ticket_sold_count', true );
	 		}
	 		
	 		if ( is_numeric( $sold ) ) {
	 			$total_tickets += (int) $sold;
	 		} else {
	 			// If no sold count metadata found, count attendees directly
	 			$attendees_count = $this->count_event_attendees($event_id);
	 			if ($attendees_count > 0) {
	 				$total_tickets += $attendees_count;
	 				// Update the meta for future reference
	 				update_post_meta($event_id, '_tribe_tickets_sold', $attendees_count);
	 			}
	 		}
	 	}
	 }

	 return $total_tickets;
	}

	/**
	 * Get the total revenue generated across all the trainer's events.
	 *
	 * @return float
	 */
	public function get_total_revenue() : float {
	 $total_revenue = 0.0;
	 $args = array(
	 	'post_type'      => Tribe__Events__Main::POSTTYPE,
	 	// 'author'         => $this->user_id, // Query by organizer instead
	 	'post_status'    => array( 'publish', 'future', 'draft', 'pending', 'private' ), // Include all statuses for historical data
	 	'posts_per_page' => -1,
	 	'fields'         => 'ids', // Only need the IDs
	 	'meta_key'       => '_EventOrganizerID',
	 	'meta_value'     => $this->user_id,
	 );
	 $event_ids = get_posts( $args );

	 if ( ! empty( $event_ids ) ) {
	 	foreach ( $event_ids as $event_id ) {
	 		// Event Tickets Plus often stores total revenue in '_tribe_revenue_total' meta
	 		$revenue = get_post_meta( $event_id, '_tribe_revenue_total', true );
	 		if ( is_numeric( $revenue ) ) {
	 			$total_revenue += (float) $revenue;
	 		} else {
	 			// Calculate revenue from attendees if meta not found
	 			$event_revenue = $this->calculate_event_revenue($event_id);
	 			if ($event_revenue > 0) {
	 				$total_revenue += $event_revenue;
	 				// Update the meta for future reference
	 				update_post_meta($event_id, '_tribe_revenue_total', $event_revenue);
	 			}
	 		}
	 	}
	 }

	 return $total_revenue;
	}

	/**
	 * Get the annual revenue target set by the trainer.
	 *
	 * @return float|null Returns the target as a float, or null if not set.
	 */
	public function get_annual_revenue_target() : ?float {
		$target = get_user_meta( $this->user_id, 'annual_revenue_target', true );
		return ! empty( $target ) && is_numeric( $target ) ? (float) $target : null;
	}

	/**
	 * Get the data needed for the events table on the dashboard.
	 *
	 * @param string $filter_status The status to filter events by ('all', 'publish', 'future', 'draft', 'pending', 'private'). Defaults to 'all'.
	 * @return array An array of event data arrays/objects, each containing keys like: id, status, name, link, date, organizer, capacity, sold, revenue.
	 */
	public function get_events_table_data( string $filter_status = 'all' ) : array {
	 $events_data = [];
	 $valid_statuses = array( 'publish', 'future', 'draft', 'pending', 'private' );
	 $post_status = ( 'all' === $filter_status || ! in_array( $filter_status, $valid_statuses, true ) )
	 				? $valid_statuses
	 				: array( $filter_status );

	 $args = array(
	 	'post_type'      => Tribe__Events__Main::POSTTYPE,
	 	'author'         => $this->user_id, // Query by post author
	 	'post_status'    => $post_status,
	 	'posts_per_page' => -1,
	 	'orderby'        => 'meta_value', // Order by start date
	 	'meta_key'       => '_EventStartDate', // Specify the meta key for ordering
	 	'order'          => 'DESC',       // Show most recent first
	 );

	 $query = new WP_Query( $args );

	 if ( $query->have_posts() ) {
	 	while ( $query->have_posts() ) {
	 		$query->the_post();
	 		$event_id = get_the_ID();

	 		// Get Capacity - Sum capacity of all tickets for this event
	 		$total_capacity = 0;
	 		if ( function_exists( 'tribe_get_tickets' ) ) {
	 			$tickets = tribe_get_tickets( $event_id );
	 			if ( $tickets ) {
	 				foreach ( $tickets as $ticket ) {
	 					$capacity = $ticket->capacity();
	 					// -1 often means unlimited capacity for Tribe Tickets
	 					if ( $capacity === -1 ) {
	 						$total_capacity = -1; // Mark as unlimited
	 						break; // No need to sum further if one is unlimited
	 					}
	 					if ( is_numeric( $capacity ) ) {
	 						$total_capacity += $capacity;
	 					}
	 				}
	 			}
	 		}

	 		// Get sold and revenue counts, checking for both standard and alternative meta fields
	 		$sold = get_post_meta( $event_id, '_tribe_tickets_sold', true );
	 		if (!is_numeric($sold)) {
	 			$sold = get_post_meta( $event_id, '_tribe_ticket_sold_count', true );
	 			
	 			// If still no valid count, calculate from attendees
	 			if (!is_numeric($sold)) {
	 				$sold = $this->count_event_attendees($event_id);
	 				if ($sold > 0) {
	 					update_post_meta($event_id, '_tribe_tickets_sold', $sold);
	 				}
	 			}
	 		}
	 		
	 		$revenue = get_post_meta( $event_id, '_tribe_revenue_total', true );
	 		if (!is_numeric($revenue)) {
	 			$revenue = $this->calculate_event_revenue($event_id);
	 			if ($revenue > 0) {
	 				update_post_meta($event_id, '_tribe_revenue_total', $revenue);
	 			}
	 		}

	 		$events_data[] = array(
	 			'id'        => $event_id,
	 			'status'    => get_post_status( $event_id ),
	 			'name'      => get_the_title(),
	 			// Return raw data instead of calling TEC functions here
	 			'link'      => get_permalink( $event_id ), // Use standard WP permalink
	 			'start_date_ts' => strtotime( get_post_meta( $event_id, '_EventStartDate', true ) ), // Return timestamp
	 			'organizer_id' => (int) get_post_meta( $event_id, '_EventOrganizerID', true ), // Return organizer ID
	 			'capacity'  => ( $total_capacity === -1 ) ? 'Unlimited' : (int) $total_capacity,
	 			'sold'      => is_numeric( $sold ) ? (int) $sold : 0,
	 			'revenue'   => is_numeric( $revenue ) ? (float) $revenue : 0.0,
	 		);
	 	}
	 	wp_reset_postdata(); // Restore original Post Data
	 }

	 return $events_data;
	}

	/**
	 * Count the number of attendees for an event by querying attendee posts
	 *
	 * @param int $event_id Event ID to count attendees for
	 * @return int Number of attendees found
	 */
	private function count_event_attendees(int $event_id) : int {
		$attendee_count = 0;
		
		// Check if Event Tickets is active
		if (class_exists('Tribe__Tickets__Tickets_Handler') && method_exists(Tribe__Tickets__Tickets_Handler::instance(), 'get_attendees_by_id')) {
			$attendees = Tribe__Tickets__Tickets_Handler::instance()->get_attendees_by_id($event_id);
			if (is_array($attendees)) {
				$attendee_count = count($attendees);
			}
		} else {
			// Fallback to direct query if Event Tickets not available
			$attendees_query = new WP_Query([
				'post_type' => 'tribe_tpp_attendees',
				'posts_per_page' => -1,
				'fields' => 'ids',
				'meta_query' => [
					[
						'key' => '_tribe_tpp_event',
						'value' => $event_id,
						'compare' => '=',
					],
				],
			]);
			$attendee_count = $attendees_query->found_posts;
		}
		
		return $attendee_count;
	}
	
	/**
	 * Calculate total revenue for an event by summing ticket prices
	 *
	 * @param int $event_id Event ID to calculate revenue for
	 * @return float Total revenue calculated
	 */
	private function calculate_event_revenue(int $event_id) : float {
		$total_revenue = 0.0;
		
		// Check if Event Tickets is active
		if (class_exists('Tribe__Tickets__Tickets_Handler') && method_exists(Tribe__Tickets__Tickets_Handler::instance(), 'get_attendees_by_id')) {
			$attendees = Tribe__Tickets__Tickets_Handler::instance()->get_attendees_by_id($event_id);
			
			if (is_array($attendees)) {
				foreach ($attendees as $attendee) {
					// Extract price - structure might vary based on ticket provider
					$price = 0;
					if (isset($attendee['price']) && is_numeric($attendee['price'])) {
						$price = (float)$attendee['price'];
					} elseif (isset($attendee['price_paid']) && is_numeric($attendee['price_paid'])) {
						$price = (float)$attendee['price_paid'];
					}
					
					$total_revenue += $price;
				}
			}
		} else {
			// Fallback to direct calculation if Event Tickets not available
			// First get all tickets for this event to get prices
			$tickets_query = new WP_Query([
				'post_type' => 'tribe_tpp_tickets',
				'posts_per_page' => -1,
				'meta_query' => [
					[
						'key' => '_tribe_tpp_for_event',
						'value' => $event_id,
						'compare' => '=',
					],
				],
			]);
			
			if ($tickets_query->have_posts()) {
				while ($tickets_query->have_posts()) {
					$tickets_query->the_post();
					$ticket_id = get_the_ID();
					$price = get_post_meta($ticket_id, '_price', true);
					$sold = get_post_meta($ticket_id, '_tribe_tpp_sold', true);
					
					if (is_numeric($price) && is_numeric($sold)) {
						$total_revenue += ((float)$price * (int)$sold);
					}
				}
				wp_reset_postdata();
			}
		}
		
		return $total_revenue;
	}
} // End class HVAC_Dashboard_Data