<?php
/**
 * HVAC Community Events Dashboard Data Handler - Refactored
 *
 * Optimized version with better caching and query optimization
 *
 * @package    HVAC_Community_Events
 * @subpackage Includes
 * @since      1.1.0
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Class HVAC_Dashboard_Data_Refactored
 */
class HVAC_Dashboard_Data_Refactored {

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

	/**
	 * Cache group for dashboard data
	 *
	 * @var string
	 */
	private $cache_group = 'hvac_dashboard';

	/**
	 * Cache expiration time (5 minutes)
	 *
	 * @var int
	 */
	private $cache_expiration = 300;

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

	/**
	 * Get all dashboard stats in a single cached object
	 *
	 * @return array
	 */
	public function get_all_stats() : array {
		$cache_key = 'stats_' . $this->user_id;
		$stats = wp_cache_get( $cache_key, $this->cache_group );

		if ( false === $stats ) {
			$stats = array(
				'total_events'    => $this->calculate_total_events_count(),
				'upcoming_events' => $this->calculate_upcoming_events_count(),
				'past_events'     => $this->calculate_past_events_count(),
				'total_tickets'   => $this->calculate_total_tickets_sold(),
				'total_revenue'   => $this->calculate_total_revenue(),
				'revenue_target'  => $this->get_annual_revenue_target(),
			);

			wp_cache_set( $cache_key, $stats, $this->cache_group, $this->cache_expiration );
			HVAC_Logger::info( 'Dashboard stats calculated and cached', 'Dashboard', array( 'user_id' => $this->user_id ) );
		}

		return $stats;
	}

	/**
	 * Clear cache for a specific user
	 *
	 * @return void
	 */
	public function clear_cache() {
		$cache_key = 'stats_' . $this->user_id;
		wp_cache_delete( $cache_key, $this->cache_group );
		HVAC_Logger::info( 'Dashboard cache cleared', 'Dashboard', array( 'user_id' => $this->user_id ) );
	}

	/**
	 * Calculate total events count (optimized)
	 *
	 * @return int
	 */
	private function calculate_total_events_count() : int {
		global $wpdb;
		
		// Direct query is more efficient for simple counts
		$count = $wpdb->get_var( $wpdb->prepare(
			"SELECT COUNT(ID) FROM {$wpdb->posts} 
			WHERE post_type = %s 
			AND post_author = %d 
			AND post_status IN ('publish', 'future', 'draft', 'pending', 'private')",
			Tribe__Events__Main::POSTTYPE,
			$this->user_id
		) );

		return (int) $count;
	}

	/**
	 * Calculate upcoming events count
	 *
	 * @return int
	 */
	private function calculate_upcoming_events_count() : int {
		global $wpdb;
		
		$today = current_time( 'mysql' );
		
		// Query using post_author and meta data
		$count = $wpdb->get_var( $wpdb->prepare(
			"SELECT COUNT(DISTINCT p.ID) 
			FROM {$wpdb->posts} p
			INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
			WHERE p.post_type = %s 
			AND p.post_author = %d 
			AND p.post_status IN ('publish', 'future')
			AND pm.meta_key = '_EventStartDate'
			AND pm.meta_value >= %s",
			Tribe__Events__Main::POSTTYPE,
			$this->user_id,
			$today
		) );

		return (int) $count;
	}

	/**
	 * Calculate past events count
	 *
	 * @return int
	 */
	private function calculate_past_events_count() : int {
		global $wpdb;
		
		$today = current_time( 'mysql' );
		
		$count = $wpdb->get_var( $wpdb->prepare(
			"SELECT COUNT(DISTINCT p.ID) 
			FROM {$wpdb->posts} p
			INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
			WHERE p.post_type = %s 
			AND p.post_author = %d 
			AND p.post_status IN ('publish', 'private')
			AND pm.meta_key = '_EventEndDate'
			AND pm.meta_value < %s",
			Tribe__Events__Main::POSTTYPE,
			$this->user_id,
			$today
		) );

		return (int) $count;
	}

	/**
	 * Calculate total tickets sold (optimized with single query)
	 *
	 * @return int
	 */
	private function calculate_total_tickets_sold() : int {
		global $wpdb;
		
		// Get all event IDs in one query
		$event_ids = $wpdb->get_col( $wpdb->prepare(
			"SELECT ID FROM {$wpdb->posts} 
			WHERE post_type = %s 
			AND post_author = %d 
			AND post_status IN ('publish', 'future', 'draft', 'pending', 'private')",
			Tribe__Events__Main::POSTTYPE,
			$this->user_id
		) );

		if ( empty( $event_ids ) ) {
			return 0;
		}

		// Get sum of tickets sold in one query
		$placeholders = array_fill( 0, count( $event_ids ), '%d' );
		$sql = $wpdb->prepare(
			"SELECT SUM(meta_value) 
			FROM {$wpdb->postmeta} 
			WHERE meta_key = '_tribe_tickets_sold' 
			AND post_id IN (" . implode( ',', $placeholders ) . ")",
			$event_ids
		);

		$total = $wpdb->get_var( $sql );

		return (int) $total;
	}

	/**
	 * Calculate total revenue (optimized)
	 *
	 * @return float
	 */
	private function calculate_total_revenue() : float {
		global $wpdb;
		
		// Get all event IDs in one query
		$event_ids = $wpdb->get_col( $wpdb->prepare(
			"SELECT ID FROM {$wpdb->posts} 
			WHERE post_type = %s 
			AND post_author = %d 
			AND post_status IN ('publish', 'future', 'draft', 'pending', 'private')",
			Tribe__Events__Main::POSTTYPE,
			$this->user_id
		) );

		if ( empty( $event_ids ) ) {
			return 0.0;
		}

		// Get sum of revenue in one query
		$placeholders = array_fill( 0, count( $event_ids ), '%d' );
		$sql = $wpdb->prepare(
			"SELECT SUM(meta_value) 
			FROM {$wpdb->postmeta} 
			WHERE meta_key = '_tribe_revenue_total' 
			AND post_id IN (" . implode( ',', $placeholders ) . ")",
			$event_ids
		);

		$total = $wpdb->get_var( $sql );

		return (float) $total;
	}

	/**
	 * Get annual revenue target
	 *
	 * @return float|null
	 */
	private 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 events table data (optimized)
	 *
	 * @param string $filter_status Status filter
	 * @return array
	 */
	public function get_events_table_data( string $filter_status = 'all' ) : array {
		global $wpdb;

		$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 );

		// Convert to SQL-safe string
		$status_placeholders = array_fill( 0, count( $post_status ), '%s' );
		$status_sql = implode( ',', $status_placeholders );

		// Get all events with their metadata in fewer queries
		$sql = $wpdb->prepare(
			"SELECT p.ID, p.post_title, p.post_status, p.guid,
				MAX(CASE WHEN pm.meta_key = '_EventStartDate' THEN pm.meta_value END) as start_date,
				MAX(CASE WHEN pm.meta_key = '_EventOrganizerID' THEN pm.meta_value END) as organizer_id,
				MAX(CASE WHEN pm.meta_key = '_tribe_tickets_sold' THEN pm.meta_value END) as tickets_sold,
				MAX(CASE WHEN pm.meta_key = '_tribe_revenue_total' THEN pm.meta_value END) as revenue
			FROM {$wpdb->posts} p
			LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
			WHERE p.post_type = %s 
			AND p.post_author = %d 
			AND p.post_status IN ($status_sql)
			GROUP BY p.ID
			ORDER BY start_date DESC",
			array_merge(
				array( Tribe__Events__Main::POSTTYPE, $this->user_id ),
				$post_status
			)
		);

		$events = $wpdb->get_results( $sql );
		$events_data = array();

		foreach ( $events as $event ) {
			// Get ticket capacity
			$capacity = $this->get_event_capacity( $event->ID );

			$events_data[] = array(
				'id'        => $event->ID,
				'status'    => $event->post_status,
				'name'      => $event->post_title,
				'link'      => get_permalink( $event->ID ),
				'start_date_ts' => strtotime( $event->start_date ),
				'organizer_id' => (int) $event->organizer_id,
				'capacity'  => $capacity,
				'sold'      => (int) $event->tickets_sold,
				'revenue'   => (float) $event->revenue,
			);
		}

		return $events_data;
	}

	/**
	 * Get event capacity
	 *
	 * @param int $event_id Event ID
	 * @return string|int
	 */
	private function get_event_capacity( $event_id ) {
		if ( ! function_exists( 'tribe_get_tickets' ) ) {
			return 0;
		}

		$tickets = tribe_get_tickets( $event_id );
		$total_capacity = 0;

		foreach ( $tickets as $ticket ) {
			$capacity = $ticket->capacity();
			if ( $capacity === -1 ) {
				return 'Unlimited';
			}
			if ( is_numeric( $capacity ) ) {
				$total_capacity += $capacity;
			}
		}

		return $total_capacity;
	}
}