<?php
/**
 * Unit Tests for HVAC Trainer Status
 *
 * @package HVAC_Community_Events
 * @subpackage Tests
 */

class Test_HVAC_Trainer_Status extends WP_UnitTestCase {
    
    /**
     * Test user ID
     */
    private $test_user_id;
    
    /**
     * Setup before each test
     */
    public function setUp() {
        parent::setUp();
        
        // Create a test user with trainer role
        $this->test_user_id = $this->factory->user->create( array(
            'role' => 'hvac_trainer',
            'user_login' => 'test_trainer',
            'user_email' => 'test@example.com',
            'display_name' => 'Test Trainer',
        ) );
    }
    
    /**
     * Teardown after each test
     */
    public function tearDown() {
        parent::tearDown();
        
        // Clean up test user
        if ( $this->test_user_id ) {
            wp_delete_user( $this->test_user_id );
        }
    }
    
    /**
     * Test status constants are defined
     */
    public function test_status_constants() {
        $this->assertEquals( 'pending', HVAC_Trainer_Status::STATUS_PENDING );
        $this->assertEquals( 'approved', HVAC_Trainer_Status::STATUS_APPROVED );
        $this->assertEquals( 'active', HVAC_Trainer_Status::STATUS_ACTIVE );
        $this->assertEquals( 'inactive', HVAC_Trainer_Status::STATUS_INACTIVE );
        $this->assertEquals( 'disabled', HVAC_Trainer_Status::STATUS_DISABLED );
    }
    
    /**
     * Test get all statuses
     */
    public function test_get_all_statuses() {
        $statuses = HVAC_Trainer_Status::get_all_statuses();
        
        $this->assertIsArray( $statuses );
        $this->assertArrayHasKey( 'pending', $statuses );
        $this->assertArrayHasKey( 'approved', $statuses );
        $this->assertArrayHasKey( 'active', $statuses );
        $this->assertArrayHasKey( 'inactive', $statuses );
        $this->assertArrayHasKey( 'disabled', $statuses );
    }
    
    /**
     * Test default trainer status
     */
    public function test_default_trainer_status() {
        // New user without status should default to pending
        $status = HVAC_Trainer_Status::get_trainer_status( $this->test_user_id );
        $this->assertEquals( HVAC_Trainer_Status::STATUS_PENDING, $status );
    }
    
    /**
     * Test setting trainer status
     */
    public function test_set_trainer_status() {
        // Test setting to approved
        $result = HVAC_Trainer_Status::set_trainer_status( $this->test_user_id, HVAC_Trainer_Status::STATUS_APPROVED );
        $this->assertTrue( $result );
        
        $status = HVAC_Trainer_Status::get_trainer_status( $this->test_user_id );
        $this->assertEquals( HVAC_Trainer_Status::STATUS_APPROVED, $status );
        
        // Test setting to disabled
        $result = HVAC_Trainer_Status::set_trainer_status( $this->test_user_id, HVAC_Trainer_Status::STATUS_DISABLED );
        $this->assertTrue( $result );
        
        $status = HVAC_Trainer_Status::get_trainer_status( $this->test_user_id );
        $this->assertEquals( HVAC_Trainer_Status::STATUS_DISABLED, $status );
    }
    
    /**
     * Test invalid status
     */
    public function test_invalid_status() {
        $result = HVAC_Trainer_Status::set_trainer_status( $this->test_user_id, 'invalid_status' );
        $this->assertFalse( $result );
    }
    
    /**
     * Test approval date is set
     */
    public function test_approval_date_set() {
        // Set to approved
        HVAC_Trainer_Status::set_trainer_status( $this->test_user_id, HVAC_Trainer_Status::STATUS_APPROVED );
        
        $approval_date = get_user_meta( $this->test_user_id, 'approval_date', true );
        $this->assertNotEmpty( $approval_date );
    }
    
    /**
     * Test active/inactive status based on event date
     */
    public function test_active_inactive_status() {
        // First approve the user
        HVAC_Trainer_Status::set_trainer_status( $this->test_user_id, HVAC_Trainer_Status::STATUS_APPROVED );
        
        // Create a recent event (should make user active)
        $recent_event_id = $this->factory->post->create( array(
            'post_type' => 'tribe_events',
            'post_author' => $this->test_user_id,
            'post_status' => 'publish',
        ) );
        
        // Set event date to 30 days ago
        update_post_meta( $recent_event_id, '_EventStartDate', date( 'Y-m-d H:i:s', strtotime( '-30 days' ) ) );
        
        $status = HVAC_Trainer_Status::get_trainer_status( $this->test_user_id );
        $this->assertEquals( HVAC_Trainer_Status::STATUS_ACTIVE, $status );
        
        // Update event date to 200 days ago (should make user inactive)
        update_post_meta( $recent_event_id, '_EventStartDate', date( 'Y-m-d H:i:s', strtotime( '-200 days' ) ) );
        
        $status = HVAC_Trainer_Status::get_trainer_status( $this->test_user_id );
        $this->assertEquals( HVAC_Trainer_Status::STATUS_INACTIVE, $status );
        
        // Clean up
        wp_delete_post( $recent_event_id, true );
    }
    
    /**
     * Test can access trainer pages
     */
    public function test_can_access_trainer_pages() {
        // Pending users cannot access
        HVAC_Trainer_Status::set_trainer_status( $this->test_user_id, HVAC_Trainer_Status::STATUS_PENDING );
        $this->assertFalse( HVAC_Trainer_Status::can_access_trainer_pages( $this->test_user_id ) );
        
        // Disabled users cannot access
        HVAC_Trainer_Status::set_trainer_status( $this->test_user_id, HVAC_Trainer_Status::STATUS_DISABLED );
        $this->assertFalse( HVAC_Trainer_Status::can_access_trainer_pages( $this->test_user_id ) );
        
        // Active users can access
        HVAC_Trainer_Status::set_trainer_status( $this->test_user_id, HVAC_Trainer_Status::STATUS_ACTIVE );
        $this->assertTrue( HVAC_Trainer_Status::can_access_trainer_pages( $this->test_user_id ) );
        
        // Inactive users can access
        HVAC_Trainer_Status::set_trainer_status( $this->test_user_id, HVAC_Trainer_Status::STATUS_INACTIVE );
        $this->assertTrue( HVAC_Trainer_Status::can_access_trainer_pages( $this->test_user_id ) );
    }
    
    /**
     * Test get trainers by status
     */
    public function test_get_trainers_by_status() {
        // Create additional test users
        $pending_user = $this->factory->user->create( array( 'role' => 'hvac_trainer' ) );
        $approved_user = $this->factory->user->create( array( 'role' => 'hvac_trainer' ) );
        $disabled_user = $this->factory->user->create( array( 'role' => 'hvac_trainer' ) );
        
        // Set statuses
        HVAC_Trainer_Status::set_trainer_status( $pending_user, HVAC_Trainer_Status::STATUS_PENDING );
        HVAC_Trainer_Status::set_trainer_status( $approved_user, HVAC_Trainer_Status::STATUS_APPROVED );
        HVAC_Trainer_Status::set_trainer_status( $disabled_user, HVAC_Trainer_Status::STATUS_DISABLED );
        
        // Get pending trainers
        $pending_trainers = HVAC_Trainer_Status::get_trainers_by_status( HVAC_Trainer_Status::STATUS_PENDING );
        $pending_ids = wp_list_pluck( $pending_trainers, 'ID' );
        $this->assertContains( $pending_user, $pending_ids );
        
        // Get disabled trainers
        $disabled_trainers = HVAC_Trainer_Status::get_trainers_by_status( HVAC_Trainer_Status::STATUS_DISABLED );
        $disabled_ids = wp_list_pluck( $disabled_trainers, 'ID' );
        $this->assertContains( $disabled_user, $disabled_ids );
        
        // Clean up
        wp_delete_user( $pending_user );
        wp_delete_user( $approved_user );
        wp_delete_user( $disabled_user );
    }
    
    /**
     * Test bulk update status
     */
    public function test_bulk_update_status() {
        // Create test users
        $user1 = $this->factory->user->create( array( 'role' => 'hvac_trainer' ) );
        $user2 = $this->factory->user->create( array( 'role' => 'hvac_trainer' ) );
        $user3 = $this->factory->user->create( array( 'role' => 'hvac_trainer' ) );
        
        $user_ids = array( $user1, $user2, $user3 );
        
        // Bulk update to approved
        $results = HVAC_Trainer_Status::bulk_update_status( $user_ids, HVAC_Trainer_Status::STATUS_APPROVED );
        
        $this->assertEquals( 3, $results['success'] );
        $this->assertEquals( 0, $results['failed'] );
        
        // Verify all users are approved
        foreach ( $user_ids as $user_id ) {
            $status = HVAC_Trainer_Status::get_trainer_status( $user_id );
            $this->assertEquals( HVAC_Trainer_Status::STATUS_APPROVED, $status );
        }
        
        // Clean up
        foreach ( $user_ids as $user_id ) {
            wp_delete_user( $user_id );
        }
    }
    
    /**
     * Test registration date
     */
    public function test_get_registration_date() {
        $date = HVAC_Trainer_Status::get_registration_date( $this->test_user_id );
        $this->assertNotEmpty( $date );
        $this->assertRegExp( '/^\d{4}-\d{2}-\d{2}$/', $date ); // Check format YYYY-MM-DD
    }
    
    /**
     * Test trainer event count
     */
    public function test_get_trainer_event_count() {
        // Initially should be 0
        $count = HVAC_Trainer_Status::get_trainer_event_count( $this->test_user_id );
        $this->assertEquals( 0, $count );
        
        // Create events
        $event1 = $this->factory->post->create( array(
            'post_type' => 'tribe_events',
            'post_author' => $this->test_user_id,
            'post_status' => 'publish',
        ) );
        
        $event2 = $this->factory->post->create( array(
            'post_type' => 'tribe_events',
            'post_author' => $this->test_user_id,
            'post_status' => 'draft',
        ) );
        
        $count = HVAC_Trainer_Status::get_trainer_event_count( $this->test_user_id );
        $this->assertEquals( 2, $count );
        
        // Clean up
        wp_delete_post( $event1, true );
        wp_delete_post( $event2, true );
    }
    
    /**
     * Test status change action hook
     */
    public function test_status_change_hook() {
        $hook_called = false;
        $old_status_captured = '';
        $new_status_captured = '';
        
        // Add test action
        add_action( 'hvac_trainer_status_changed', function( $user_id, $new_status, $old_status ) use ( &$hook_called, &$old_status_captured, &$new_status_captured ) {
            $hook_called = true;
            $old_status_captured = $old_status;
            $new_status_captured = $new_status;
        }, 10, 3 );
        
        // Set initial status
        HVAC_Trainer_Status::set_trainer_status( $this->test_user_id, HVAC_Trainer_Status::STATUS_PENDING );
        
        // Change status
        HVAC_Trainer_Status::set_trainer_status( $this->test_user_id, HVAC_Trainer_Status::STATUS_APPROVED );
        
        $this->assertTrue( $hook_called );
        $this->assertEquals( HVAC_Trainer_Status::STATUS_PENDING, $old_status_captured );
        $this->assertEquals( HVAC_Trainer_Status::STATUS_APPROVED, $new_status_captured );
    }
}