<?php
/**
 * Extended Unit Tests for HVAC Announcements AJAX Handler
 *
 * @package HVAC_Community_Events
 * @subpackage Tests
 */

class Test_HVAC_Announcements_Ajax_Extended extends WP_UnitTestCase {
    
    /**
     * Test users
     */
    private $master_trainer;
    private $regular_trainer;
    
    /**
     * Ajax handler instance
     */
    private $ajax_handler;
    
    /**
     * Setup before each test
     */
    public function setUp() {
        parent::setUp();
        
        // Create test users
        $this->master_trainer = $this->factory->user->create( array(
            'role' => 'hvac_master_trainer',
            'user_login' => 'master_trainer',
            'user_email' => 'master@example.com',
        ) );
        
        $this->regular_trainer = $this->factory->user->create( array(
            'role' => 'hvac_trainer',
            'user_login' => 'regular_trainer',
            'user_email' => 'trainer@example.com',
        ) );
        
        // Add capabilities
        HVAC_Announcements_Permissions::add_capabilities();
        
        // Get ajax handler instance
        $this->ajax_handler = HVAC_Announcements_Ajax::get_instance();
    }
    
    /**
     * Teardown after each test
     */
    public function tearDown() {
        parent::tearDown();
        
        // Clean up test users
        wp_delete_user( $this->master_trainer );
        wp_delete_user( $this->regular_trainer );
        
        // Remove capabilities
        HVAC_Announcements_Permissions::remove_capabilities();
        
        // Clear any transients
        delete_transient( 'hvac_ajax_rate_' . $this->master_trainer );
        delete_transient( 'hvac_ajax_rate_' . $this->regular_trainer );
    }
    
    /**
     * Test create announcement with all fields
     */
    public function test_create_announcement_complete() {
        wp_set_current_user( $this->master_trainer );
        
        // Prepare test data
        $_POST = array(
            'nonce' => wp_create_nonce( 'hvac_announcements_nonce' ),
            'title' => 'New Test Announcement',
            'content' => '<p>This is the <strong>content</strong> with HTML.</p>',
            'excerpt' => 'This is the excerpt',
            'status' => 'publish',
            'publish_date' => '2024-12-25 10:00:00',
            'categories' => array( 1, 2, 3 ),
            'tags' => 'tag1, tag2, tag3',
            'featured_image_id' => 123,
        );
        
        // Mock the AJAX response capture
        $this->expectOutputRegex( '/.*/' ); // Expect some output
        
        // Test would normally call create_announcement() but it uses wp_send_json_*
        // which exits, so we'll test the data preparation instead
        
        // Test title sanitization
        $sanitized_title = sanitize_text_field( $_POST['title'] );
        $this->assertEquals( 'New Test Announcement', $sanitized_title );
        
        // Test content sanitization
        $sanitized_content = wp_kses_post( $_POST['content'] );
        $this->assertStringContainsString( '<strong>content</strong>', $sanitized_content );
        $this->assertStringNotContainsString( '<script>', $sanitized_content );
        
        // Test date handling
        $gmt_date = get_gmt_from_date( $_POST['publish_date'] );
        $this->assertNotEmpty( $gmt_date );
    }
    
    /**
     * Test create announcement validation
     */
    public function test_create_announcement_validation() {
        wp_set_current_user( $this->master_trainer );
        
        // Test without title
        $_POST = array(
            'nonce' => wp_create_nonce( 'hvac_announcements_nonce' ),
            'title' => '', // Empty title
            'content' => 'Content',
            'status' => 'draft',
        );
        
        // Title validation
        $this->assertEmpty( $_POST['title'] );
        
        // Test invalid status
        $_POST['status'] = 'invalid_status';
        $valid_statuses = array( 'publish', 'draft', 'private', 'pending' );
        $this->assertNotContains( $_POST['status'], $valid_statuses );
    }
    
    /**
     * Test update announcement with partial data
     */
    public function test_update_announcement_partial() {
        wp_set_current_user( $this->master_trainer );
        
        // Create test announcement
        $post_id = wp_insert_post( array(
            'post_type' => HVAC_Announcements_CPT::get_post_type(),
            'post_title' => 'Original Title',
            'post_content' => 'Original Content',
            'post_status' => 'draft',
            'post_author' => $this->master_trainer,
        ) );
        
        // Prepare update data
        $_POST = array(
            'nonce' => wp_create_nonce( 'hvac_announcements_nonce' ),
            'id' => $post_id,
            'title' => 'Updated Title',
            'content' => 'Updated Content',
            'status' => 'publish',
        );
        
        // Test that we can update the post
        $update_data = array(
            'ID' => $post_id,
            'post_title' => sanitize_text_field( $_POST['title'] ),
            'post_content' => wp_kses_post( $_POST['content'] ),
            'post_status' => sanitize_text_field( $_POST['status'] ),
        );
        
        $result = wp_update_post( $update_data );
        $this->assertNotEquals( 0, $result );
        $this->assertFalse( is_wp_error( $result ) );
        
        // Verify update
        $updated_post = get_post( $post_id );
        $this->assertEquals( 'Updated Title', $updated_post->post_title );
        $this->assertEquals( 'Updated Content', $updated_post->post_content );
        $this->assertEquals( 'publish', $updated_post->post_status );
        
        // Clean up
        wp_delete_post( $post_id, true );
    }
    
    /**
     * Test delete announcement
     */
    public function test_delete_announcement() {
        wp_set_current_user( $this->master_trainer );
        
        // Create test announcement
        $post_id = wp_insert_post( array(
            'post_type' => HVAC_Announcements_CPT::get_post_type(),
            'post_title' => 'To Delete',
            'post_status' => 'draft',
            'post_author' => $this->master_trainer,
        ) );
        
        // Test deletion
        $_POST = array(
            'nonce' => wp_create_nonce( 'hvac_announcements_nonce' ),
            'id' => $post_id,
        );
        
        // Check permission
        $this->assertTrue( HVAC_Announcements_Permissions::current_user_can_delete( $post_id ) );
        
        // Delete post
        $result = wp_delete_post( $post_id, true );
        $this->assertNotNull( $result );
        $this->assertFalse( is_wp_error( $result ) );
        
        // Verify deletion
        $deleted_post = get_post( $post_id );
        $this->assertNull( $deleted_post );
    }
    
    /**
     * Test get categories and tags
     */
    public function test_get_categories_and_tags() {
        wp_set_current_user( $this->master_trainer );
        
        // Create test categories
        $cat1 = wp_insert_term( 'Category 1', HVAC_Announcements_CPT::get_category_taxonomy() );
        $cat2 = wp_insert_term( 'Category 2', HVAC_Announcements_CPT::get_category_taxonomy() );
        
        // Create test tags
        $tag1 = wp_insert_term( 'Tag 1', HVAC_Announcements_CPT::get_tag_taxonomy() );
        $tag2 = wp_insert_term( 'Tag 2', HVAC_Announcements_CPT::get_tag_taxonomy() );
        
        // Get categories
        $categories = get_terms( array(
            'taxonomy' => HVAC_Announcements_CPT::get_category_taxonomy(),
            'hide_empty' => false,
        ) );
        
        $this->assertGreaterThanOrEqual( 2, count( $categories ) );
        
        // Get tags
        $tags = get_terms( array(
            'taxonomy' => HVAC_Announcements_CPT::get_tag_taxonomy(),
            'hide_empty' => false,
        ) );
        
        $this->assertGreaterThanOrEqual( 2, count( $tags ) );
        
        // Clean up
        if ( !is_wp_error( $cat1 ) ) {
            wp_delete_term( $cat1['term_id'], HVAC_Announcements_CPT::get_category_taxonomy() );
        }
        if ( !is_wp_error( $cat2 ) ) {
            wp_delete_term( $cat2['term_id'], HVAC_Announcements_CPT::get_category_taxonomy() );
        }
        if ( !is_wp_error( $tag1 ) ) {
            wp_delete_term( $tag1['term_id'], HVAC_Announcements_CPT::get_tag_taxonomy() );
        }
        if ( !is_wp_error( $tag2 ) ) {
            wp_delete_term( $tag2['term_id'], HVAC_Announcements_CPT::get_tag_taxonomy() );
        }
    }
    
    /**
     * Test view announcement
     */
    public function test_view_announcement() {
        wp_set_current_user( $this->regular_trainer );
        
        // Create test announcement
        $post_id = wp_insert_post( array(
            'post_type' => HVAC_Announcements_CPT::get_post_type(),
            'post_title' => 'Viewable Announcement',
            'post_content' => 'Content to view',
            'post_status' => 'publish',
            'post_author' => $this->master_trainer,
        ) );
        
        // Set featured image
        $attachment_id = $this->factory->attachment->create_upload_object( 
            DIR_TESTDATA . '/images/test-image.jpg', 
            $post_id 
        );
        set_post_thumbnail( $post_id, $attachment_id );
        
        // Add categories and tags
        wp_set_post_terms( $post_id, array( 'Cat1', 'Cat2' ), HVAC_Announcements_CPT::get_category_taxonomy() );
        wp_set_post_terms( $post_id, array( 'Tag1', 'Tag2' ), HVAC_Announcements_CPT::get_tag_taxonomy() );
        
        // Test view permission
        $this->assertTrue( HVAC_Announcements_Permissions::current_user_can_read() );
        
        // Get announcement content
        $content = HVAC_Announcements_Display::get_announcement_content( $post_id );
        
        $this->assertStringContainsString( 'Viewable Announcement', $content );
        $this->assertStringContainsString( 'Content to view', $content );
        
        // Clean up
        wp_delete_post( $post_id, true );
        wp_delete_attachment( $attachment_id, true );
    }
    
    /**
     * Test pagination in get_announcements
     */
    public function test_get_announcements_pagination() {
        wp_set_current_user( $this->master_trainer );
        
        // Create multiple announcements
        $announcement_ids = array();
        for ( $i = 1; $i <= 25; $i++ ) {
            $announcement_ids[] = wp_insert_post( array(
                'post_type' => HVAC_Announcements_CPT::get_post_type(),
                'post_title' => 'Announcement ' . $i,
                'post_status' => 'publish',
                'post_author' => $this->master_trainer,
                'post_date' => date( 'Y-m-d H:i:s', strtotime( '-' . $i . ' days' ) ),
            ) );
        }
        
        // Test first page
        $args = array(
            'post_type' => HVAC_Announcements_CPT::get_post_type(),
            'posts_per_page' => 10,
            'paged' => 1,
            'post_status' => 'publish',
            'orderby' => 'date',
            'order' => 'DESC',
        );
        
        $query = new WP_Query( $args );
        $this->assertEquals( 10, $query->post_count );
        $this->assertEquals( 3, $query->max_num_pages );
        $this->assertEquals( 25, $query->found_posts );
        
        // Test second page
        $args['paged'] = 2;
        $query = new WP_Query( $args );
        $this->assertEquals( 10, $query->post_count );
        
        // Test last page
        $args['paged'] = 3;
        $query = new WP_Query( $args );
        $this->assertEquals( 5, $query->post_count );
        
        // Clean up
        foreach ( $announcement_ids as $id ) {
            wp_delete_post( $id, true );
        }
    }
    
    /**
     * Test search functionality
     */
    public function test_get_announcements_search() {
        wp_set_current_user( $this->master_trainer );
        
        // Create announcements with different titles
        $id1 = wp_insert_post( array(
            'post_type' => HVAC_Announcements_CPT::get_post_type(),
            'post_title' => 'Important Update',
            'post_content' => 'Content about updates',
            'post_status' => 'publish',
        ) );
        
        $id2 = wp_insert_post( array(
            'post_type' => HVAC_Announcements_CPT::get_post_type(),
            'post_title' => 'Training Schedule',
            'post_content' => 'Content about training',
            'post_status' => 'publish',
        ) );
        
        $id3 = wp_insert_post( array(
            'post_type' => HVAC_Announcements_CPT::get_post_type(),
            'post_title' => 'New Resources',
            'post_content' => 'Important resources available',
            'post_status' => 'publish',
        ) );
        
        // Search for "Important"
        $args = array(
            'post_type' => HVAC_Announcements_CPT::get_post_type(),
            's' => 'Important',
            'post_status' => 'publish',
        );
        
        $query = new WP_Query( $args );
        $this->assertEquals( 2, $query->found_posts ); // Should find 2 posts
        
        // Search for "Training"
        $args['s'] = 'Training';
        $query = new WP_Query( $args );
        $this->assertEquals( 1, $query->found_posts );
        
        // Clean up
        wp_delete_post( $id1, true );
        wp_delete_post( $id2, true );
        wp_delete_post( $id3, true );
    }
    
    /**
     * Test cache versioning on post status change
     */
    public function test_cache_versioning_on_status_change() {
        // Get initial version
        $version1 = wp_cache_get( 'announcements_cache_version', 'hvac_announcements' );
        if ( false === $version1 ) {
            $version1 = 1;
            wp_cache_set( 'announcements_cache_version', $version1, 'hvac_announcements', 0 );
        }
        
        // Create announcement
        $post_id = wp_insert_post( array(
            'post_type' => HVAC_Announcements_CPT::get_post_type(),
            'post_title' => 'Test Cache',
            'post_status' => 'draft',
        ) );
        
        // Trigger status change
        wp_update_post( array(
            'ID' => $post_id,
            'post_status' => 'publish',
        ) );
        
        // Manually trigger cache clear (normally done by hook)
        $this->ajax_handler->clear_announcements_cache_on_status_change( 
            'publish', 
            'draft', 
            get_post( $post_id ) 
        );
        
        // Check version was incremented
        $version2 = wp_cache_get( 'announcements_cache_version', 'hvac_announcements' );
        $this->assertEquals( $version1 + 1, $version2 );
        
        // Clean up
        wp_delete_post( $post_id, true );
    }
}