<?php
/**
 * HVAC Community Events - Trainer Status Management
 *
 * Handles trainer account status logic and transitions
 *
 * @package HVAC_Community_Events
 * @since 1.0.0
 */

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

/**
 * Class HVAC_Trainer_Status
 *
 * Manages trainer account statuses and their transitions
 */
class HVAC_Trainer_Status {
    
    /**
     * Status constants
     */
    const STATUS_PENDING = 'pending';
    const STATUS_APPROVED = 'approved';
    const STATUS_ACTIVE = 'active';
    const STATUS_INACTIVE = 'inactive';
    const STATUS_DISABLED = 'disabled';
    
    /**
     * Days before a trainer is considered inactive
     */
    const INACTIVE_DAYS_THRESHOLD = 180;
    
    /**
     * Get all available statuses with labels
     *
     * @return array
     */
    public static function get_all_statuses() {
        return array(
            self::STATUS_PENDING => __( 'Pending', 'hvac-community-events' ),
            self::STATUS_APPROVED => __( 'Approved', 'hvac-community-events' ),
            self::STATUS_ACTIVE => __( 'Active', 'hvac-community-events' ),
            self::STATUS_INACTIVE => __( 'Inactive', 'hvac-community-events' ),
            self::STATUS_DISABLED => __( 'Disabled', 'hvac-community-events' ),
        );
    }
    
    /**
     * Get trainer's current status
     *
     * @param int $user_id User ID
     * @return string Status value
     */
    public static function get_trainer_status( $user_id ) {
        // Get stored status
        $stored_status = get_user_meta( $user_id, 'account_status', true );
        
        // If disabled, return immediately
        if ( $stored_status === self::STATUS_DISABLED ) {
            return self::STATUS_DISABLED;
        }
        
        // If pending, return immediately
        if ( $stored_status === self::STATUS_PENDING ) {
            return self::STATUS_PENDING;
        }
        
        // For approved users, check if they're active or inactive
        if ( $stored_status === self::STATUS_APPROVED || 
             $stored_status === self::STATUS_ACTIVE || 
             $stored_status === self::STATUS_INACTIVE ||
             empty( $stored_status ) ) {
            
            // Check last event date to determine active/inactive
            $last_event_date = self::get_last_event_date( $user_id );
            
            if ( $last_event_date ) {
                $days_since_event = ( time() - strtotime( $last_event_date ) ) / DAY_IN_SECONDS;
                
                if ( $days_since_event <= self::INACTIVE_DAYS_THRESHOLD ) {
                    return self::STATUS_ACTIVE;
                } else {
                    return self::STATUS_INACTIVE;
                }
            } else {
                // No events created yet, but approved
                return ( $stored_status === self::STATUS_APPROVED ) ? self::STATUS_APPROVED : self::STATUS_INACTIVE;
            }
        }
        
        // Default to pending for safety
        return self::STATUS_PENDING;
    }
    
    /**
     * Set trainer status
     *
     * @param int $user_id User ID
     * @param string $status New status
     * @return bool Success
     */
    public static function set_trainer_status( $user_id, $status ) {
        $valid_statuses = array_keys( self::get_all_statuses() );
        
        if ( ! in_array( $status, $valid_statuses, true ) ) {
            return false;
        }
        
        $old_status = get_user_meta( $user_id, 'account_status', true );
        
        // Update the status
        update_user_meta( $user_id, 'account_status', $status );
        
        // If transitioning to approved, set approval date
        if ( $status === self::STATUS_APPROVED && $old_status !== self::STATUS_APPROVED ) {
            update_user_meta( $user_id, 'approval_date', current_time( 'mysql' ) );
        }
        
        // Trigger status change action
        do_action( 'hvac_trainer_status_changed', $user_id, $status, $old_status );
        
        return true;
    }
    
    /**
     * Get the date of the trainer's last event
     *
     * @param int $user_id User ID
     * @return string|false Date string or false if no events
     */
    public static function get_last_event_date( $user_id ) {
        global $wpdb;
        
        // Get the most recent event by this trainer
        $last_event_date = $wpdb->get_var( $wpdb->prepare(
            "SELECT pm.meta_value 
             FROM {$wpdb->posts} p
             INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
             WHERE p.post_author = %d
             AND p.post_type = %s
             AND p.post_status IN ('publish', 'private')
             AND pm.meta_key = '_EventStartDate'
             ORDER BY pm.meta_value DESC
             LIMIT 1",
            $user_id,
            class_exists( 'Tribe__Events__Main' ) ? Tribe__Events__Main::POSTTYPE : 'tribe_events'
        ) );
        
        // Store the last event date for quick access
        if ( $last_event_date ) {
            update_user_meta( $user_id, 'last_event_date', $last_event_date );
        }
        
        return $last_event_date;
    }
    
    /**
     * Check if a trainer can access protected pages
     *
     * @param int $user_id User ID
     * @return bool
     */
    public static function can_access_trainer_pages( $user_id ) {
        $status = self::get_trainer_status( $user_id );
        
        // Only active and inactive trainers can access protected pages
        return in_array( $status, array( self::STATUS_ACTIVE, self::STATUS_INACTIVE ), true );
    }
    
    /**
     * Get trainers by status
     *
     * @param string|array $status Status or array of statuses
     * @param array $args Additional query arguments
     * @return array Array of user objects
     */
    public static function get_trainers_by_status( $status, $args = array() ) {
        $default_args = array(
            'role__in' => array( 'hvac_trainer', 'hvac_master_trainer' ),
            'meta_query' => array(),
        );
        
        $args = wp_parse_args( $args, $default_args );
        
        // Handle dynamic statuses (active/inactive)
        if ( is_string( $status ) && in_array( $status, array( self::STATUS_ACTIVE, self::STATUS_INACTIVE ), true ) ) {
            // For active/inactive, we need to check last event dates
            $users = get_users( $args );
            $filtered_users = array();
            
            foreach ( $users as $user ) {
                if ( self::get_trainer_status( $user->ID ) === $status ) {
                    $filtered_users[] = $user;
                }
            }
            
            return $filtered_users;
        }
        
        // For static statuses (pending, approved, disabled)
        $statuses = (array) $status;
        $args['meta_query'][] = array(
            'key' => 'account_status',
            'value' => $statuses,
            'compare' => 'IN',
        );
        
        return get_users( $args );
    }
    
    /**
     * Get trainer registration date
     *
     * @param int $user_id User ID
     * @return string Formatted date
     */
    public static function get_registration_date( $user_id ) {
        $user = get_userdata( $user_id );
        
        if ( ! $user ) {
            return '';
        }
        
        return date( 'Y-m-d', strtotime( $user->user_registered ) );
    }
    
    /**
     * Get trainer's total revenue
     *
     * @param int $user_id User ID
     * @return float
     */
    public static function get_trainer_revenue( $user_id ) {
        global $wpdb;
        
        // This query matches the one in HVAC_Master_Dashboard_Data
        $revenue = $wpdb->get_var( $wpdb->prepare(
            "SELECT SUM(
                CASE 
                    WHEN pm_price1.meta_value IS NOT NULL THEN CAST(pm_price1.meta_value AS DECIMAL(10,2))
                    WHEN pm_price2.meta_value IS NOT NULL THEN CAST(pm_price2.meta_value AS DECIMAL(10,2))
                    WHEN pm_price3.meta_value IS NOT NULL THEN CAST(pm_price3.meta_value AS DECIMAL(10,2))
                    ELSE 0
                END
            ) 
            FROM {$wpdb->posts} attendees
            INNER JOIN {$wpdb->postmeta} pm_event ON attendees.ID = pm_event.post_id AND pm_event.meta_key = '_tribe_tpp_event'
            INNER JOIN {$wpdb->posts} events ON pm_event.meta_value = events.ID
            LEFT JOIN {$wpdb->postmeta} pm_price1 ON attendees.ID = pm_price1.post_id AND pm_price1.meta_key = '_tribe_tpp_ticket_price'
            LEFT JOIN {$wpdb->postmeta} pm_price2 ON attendees.ID = pm_price2.post_id AND pm_price2.meta_key = '_paid_price'
            LEFT JOIN {$wpdb->postmeta} pm_price3 ON attendees.ID = pm_price3.post_id AND pm_price3.meta_key = '_tribe_tpp_price'
            WHERE attendees.post_type = 'tribe_tpp_attendees'
            AND events.post_author = %d",
            $user_id
        ) );
        
        return (float) ( $revenue ?: 0.00 );
    }
    
    /**
     * Get total events count for a trainer
     *
     * @param int $user_id User ID
     * @return int
     */
    public static function get_trainer_event_count( $user_id ) {
        global $wpdb;
        
        $count = $wpdb->get_var( $wpdb->prepare(
            "SELECT COUNT(*) 
             FROM {$wpdb->posts} 
             WHERE post_author = %d
             AND post_type = %s
             AND post_status IN ('publish', 'future', 'draft', 'pending', 'private')",
            $user_id,
            class_exists( 'Tribe__Events__Main' ) ? Tribe__Events__Main::POSTTYPE : 'tribe_events'
        ) );
        
        return (int) $count;
    }
    
    /**
     * Bulk update trainer statuses
     *
     * @param array $user_ids Array of user IDs
     * @param string $new_status New status to set
     * @return array Results array with success/failure counts
     */
    public static function bulk_update_status( $user_ids, $new_status ) {
        $results = array(
            'success' => 0,
            'failed' => 0,
            'errors' => array(),
        );
        
        foreach ( $user_ids as $user_id ) {
            if ( self::set_trainer_status( $user_id, $new_status ) ) {
                $results['success']++;
            } else {
                $results['failed']++;
                $results['errors'][] = sprintf(
                    __( 'Failed to update status for user ID %d', 'hvac-community-events' ),
                    $user_id
                );
            }
        }
        
        return $results;
    }
}