<?php
/**
 * Tests for HVAC_Form_Builder class
 *
 * @package HVAC_Community_Events
 * @subpackage Tests
 */

/**
 * Class HVAC_Form_Builder_Test
 */
class HVAC_Form_Builder_Test extends WP_UnitTestCase {

	/**
	 * Test form builder initialization
	 */
	public function test_form_builder_initialization() {
		$form = new HVAC_Form_Builder( 'test_nonce' );
		$this->assertInstanceOf( 'HVAC_Form_Builder', $form );
	}

	/**
	 * Test adding fields
	 */
	public function test_add_field() {
		$form = new HVAC_Form_Builder( 'test_nonce' );
		
		// Add text field
		$form->add_field( array(
			'type' => 'text',
			'name' => 'test_field',
			'label' => 'Test Field',
			'required' => true,
		) );
		
		// Add email field
		$form->add_field( array(
			'type' => 'email',
			'name' => 'email_field',
			'label' => 'Email Field',
			'validate' => array( 'email' => true ),
		) );
		
		// Test that fields were added (we'd need getter methods to properly test this)
		$this->assertTrue( true );
	}

	/**
	 * Test form rendering
	 */
	public function test_render_form() {
		$form = new HVAC_Form_Builder( 'test_nonce' );
		
		// Add a simple field
		$form->add_field( array(
			'type' => 'text',
			'name' => 'test_field',
			'label' => 'Test Field',
		) );
		
		// Set form attributes
		$form->set_attributes( array(
			'id' => 'test-form',
			'class' => 'test-form-class',
		) );
		
		// Render form
		$output = $form->render();
		
		// Verify output contains expected elements
		$this->assertStringContainsString( '<form', $output );
		$this->assertStringContainsString( 'id="test-form"', $output );
		$this->assertStringContainsString( 'class="test-form-class hvac-form"', $output );
		$this->assertStringContainsString( 'Test Field', $output );
		$this->assertStringContainsString( 'name="test_field"', $output );
		$this->assertStringContainsString( 'wp_nonce', $output );
	}

	/**
	 * Test different field types
	 */
	public function test_field_types() {
		$form = new HVAC_Form_Builder( 'test_nonce' );
		
		// Add various field types
		$form->add_field( array(
			'type' => 'text',
			'name' => 'text_field',
			'label' => 'Text Field',
		) );
		
		$form->add_field( array(
			'type' => 'email',
			'name' => 'email_field',
			'label' => 'Email Field',
		) );
		
		$form->add_field( array(
			'type' => 'textarea',
			'name' => 'textarea_field',
			'label' => 'Textarea Field',
		) );
		
		$form->add_field( array(
			'type' => 'select',
			'name' => 'select_field',
			'label' => 'Select Field',
			'options' => array(
				'option1' => 'Option 1',
				'option2' => 'Option 2',
			),
		) );
		
		$form->add_field( array(
			'type' => 'checkbox',
			'name' => 'checkbox_field',
			'label' => 'Checkbox Field',
		) );
		
		$form->add_field( array(
			'type' => 'radio',
			'name' => 'radio_field',
			'label' => 'Radio Field',
			'options' => array(
				'option1' => 'Option 1',
				'option2' => 'Option 2',
			),
		) );
		
		$form->add_field( array(
			'type' => 'file',
			'name' => 'file_field',
			'label' => 'File Field',
		) );
		
		$output = $form->render();
		
		// Verify all field types are rendered
		$this->assertStringContainsString( 'type="text"', $output );
		$this->assertStringContainsString( 'type="email"', $output );
		$this->assertStringContainsString( '<textarea', $output );
		$this->assertStringContainsString( '<select', $output );
		$this->assertStringContainsString( 'type="checkbox"', $output );
		$this->assertStringContainsString( 'type="radio"', $output );
		$this->assertStringContainsString( 'type="file"', $output );
		$this->assertStringContainsString( 'enctype="multipart/form-data"', $output );
	}

	/**
	 * Test form validation
	 */
	public function test_validation() {
		$form = new HVAC_Form_Builder( 'test_nonce' );
		
		// Add fields with validation rules
		$form->add_field( array(
			'type' => 'text',
			'name' => 'required_field',
			'label' => 'Required Field',
			'required' => true,
		) );
		
		$form->add_field( array(
			'type' => 'email',
			'name' => 'email_field',
			'label' => 'Email Field',
			'required' => true,
			'validate' => array( 'email' => true ),
		) );
		
		$form->add_field( array(
			'type' => 'text',
			'name' => 'min_length_field',
			'label' => 'Min Length Field',
			'validate' => array( 'min_length' => 5 ),
		) );
		
		// Test with empty data
		$errors = $form->validate( array() );
		$this->assertArrayHasKey( 'required_field', $errors );
		$this->assertArrayHasKey( 'email_field', $errors );
		
		// Test with invalid email
		$errors = $form->validate( array(
			'required_field' => 'value',
			'email_field' => 'invalid-email',
		) );
		$this->assertArrayHasKey( 'email_field', $errors );
		
		// Test with short value
		$errors = $form->validate( array(
			'required_field' => 'value',
			'email_field' => 'test@example.com',
			'min_length_field' => 'abc',
		) );
		$this->assertArrayHasKey( 'min_length_field', $errors );
		
		// Test with valid data
		$errors = $form->validate( array(
			'required_field' => 'value',
			'email_field' => 'test@example.com',
			'min_length_field' => 'long enough',
		) );
		$this->assertEmpty( $errors );
	}

	/**
	 * Test form sanitization
	 */
	public function test_sanitization() {
		$form = new HVAC_Form_Builder( 'test_nonce' );
		
		// Add fields with different sanitization types
		$form->add_field( array(
			'type' => 'text',
			'name' => 'text_field',
			'sanitize' => 'text',
		) );
		
		$form->add_field( array(
			'type' => 'email',
			'name' => 'email_field',
			'sanitize' => 'email',
		) );
		
		$form->add_field( array(
			'type' => 'url',
			'name' => 'url_field',
			'sanitize' => 'url',
		) );
		
		$form->add_field( array(
			'type' => 'textarea',
			'name' => 'textarea_field',
			'sanitize' => 'textarea',
		) );
		
		$form->add_field( array(
			'type' => 'number',
			'name' => 'int_field',
			'sanitize' => 'int',
		) );
		
		// Test sanitization
		$raw_data = array(
			'text_field' => '<script>alert("xss")</script>',
			'email_field' => ' TEST@EXAMPLE.COM ',
			'url_field' => 'HTTPS://EXAMPLE.COM',
			'textarea_field' => "Line 1\nLine 2\n<script>alert('xss')</script>",
			'int_field' => '123abc',
		);
		
		$sanitized = $form->sanitize( $raw_data );
		
		$this->assertEquals( 'alert(&quot;xss&quot;)', $sanitized['text_field'] );
		$this->assertEquals( 'test@example.com', $sanitized['email_field'] );
		$this->assertEquals( 'https://EXAMPLE.COM', $sanitized['url_field'] );
		$this->assertStringContainsString( 'Line 1', $sanitized['textarea_field'] );
		$this->assertStringNotContainsString( '<script>', $sanitized['textarea_field'] );
		$this->assertEquals( 123, $sanitized['int_field'] );
	}

	/**
	 * Test form with errors display
	 */
	public function test_form_with_errors() {
		$form = new HVAC_Form_Builder( 'test_nonce' );
		
		// Add field
		$form->add_field( array(
			'type' => 'text',
			'name' => 'test_field',
			'label' => 'Test Field',
			'required' => true,
		) );
		
		// Set errors
		$form->set_errors( array(
			'test_field' => 'This field is required',
		) );
		
		$output = $form->render();
		
		// Verify error is displayed
		$this->assertStringContainsString( 'This field is required', $output );
		$this->assertStringContainsString( 'class="error"', $output );
	}

	/**
	 * Test form with existing data
	 */
	public function test_form_with_data() {
		$form = new HVAC_Form_Builder( 'test_nonce' );
		
		// Add fields
		$form->add_field( array(
			'type' => 'text',
			'name' => 'text_field',
			'label' => 'Text Field',
		) );
		
		$form->add_field( array(
			'type' => 'select',
			'name' => 'select_field',
			'label' => 'Select Field',
			'options' => array(
				'option1' => 'Option 1',
				'option2' => 'Option 2',
			),
		) );
		
		// Set data
		$form->set_data( array(
			'text_field' => 'Existing Value',
			'select_field' => 'option2',
		) );
		
		$output = $form->render();
		
		// Verify values are populated
		$this->assertStringContainsString( 'value="Existing Value"', $output );
		$this->assertStringContainsString( 'value="option2" selected', $output );
	}
}