/**
 * Descomplicar® Crescimento Digital
 * https://descomplicar.pt
 */

<?php
/**
 * Integration tests for Patient Creation Workflow (User Story 1).
 * 
 * These tests validate complete user stories and MUST FAIL initially (TDD RED phase).
 *
 * @package Care_API\Tests\Integration
 */

/**
 * Patient creation workflow integration tests.
 * 
 * User Story: Doctor creates patient record
 */
class Test_Patient_Creation_Workflow extends Care_API_Test_Case {

	/**
	 * Test complete patient creation workflow.
	 * 
	 * @test
	 */
	public function test_doctor_creates_patient_record_workflow() {
		// This test will fail initially as the workflow isn't implemented
		$this->markTestIncomplete( 'Patient creation workflow not implemented yet - TDD RED phase' );
		
		// ARRANGE: Doctor authentication and clinic setup
		wp_set_current_user( $this->doctor_user );
		$clinic_id = $this->create_test_clinic();
		
		// Map doctor to clinic
		global $wpdb;
		$wpdb->insert(
			$wpdb->prefix . 'kc_doctor_clinic_mappings',
			array(
				'doctor_id'  => $this->doctor_user,
				'clinic_id'  => $clinic_id,
				'created_at' => current_time( 'mysql' ),
			)
		);

		// STEP 1: Doctor creates new patient via API
		$patient_data = array(
			'display_name' => 'João Silva Santos',
			'user_email'   => 'joao.santos@example.com',
			'first_name'   => 'João',
			'last_name'    => 'Santos',
			'clinic_id'    => $clinic_id,
			'phone'        => '+351912345678',
			'address'      => 'Rua das Flores, 123',
			'city'         => 'Lisboa',
			'postal_code'  => '1000-001',
			'birth_date'   => '1985-05-15',
			'gender'       => 'M',
		);

		$response = $this->make_request( '/wp-json/kivicare/v1/patients', 'POST', $patient_data, $this->doctor_user );
		
		// ASSERT: Patient created successfully
		$this->assertRestResponse( $response, 201 );
		$patient = $response->get_data();
		$this->assertEquals( $patient_data['display_name'], $patient['display_name'] );
		$this->assertEquals( $patient_data['user_email'], $patient['user_email'] );
		$patient_id = $patient['id'];

		// STEP 2: Verify patient exists in WordPress users table
		$wp_user = get_user_by( 'id', $patient_id );
		$this->assertInstanceOf( 'WP_User', $wp_user );
		$this->assertEquals( $patient_data['user_email'], $wp_user->user_email );
		$this->assertEquals( $patient_data['display_name'], $wp_user->display_name );
		$this->assertTrue( in_array( 'patient', $wp_user->roles, true ) );

		// STEP 3: Verify patient-clinic mapping was created
		$mapping = $wpdb->get_row( 
			$wpdb->prepare( 
				"SELECT * FROM {$wpdb->prefix}kc_patient_clinic_mappings WHERE patient_id = %d AND clinic_id = %d",
				$patient_id,
				$clinic_id
			)
		);
		$this->assertNotNull( $mapping );
		$this->assertEquals( $patient_id, $mapping->patient_id );
		$this->assertEquals( $clinic_id, $mapping->clinic_id );

		// STEP 4: Verify patient metadata was stored correctly
		$phone = get_user_meta( $patient_id, 'phone', true );
		$address = get_user_meta( $patient_id, 'address', true );
		$birth_date = get_user_meta( $patient_id, 'birth_date', true );
		
		$this->assertEquals( $patient_data['phone'], $phone );
		$this->assertEquals( $patient_data['address'], $address );
		$this->assertEquals( $patient_data['birth_date'], $birth_date );

		// STEP 5: Verify doctor can retrieve patient data
		$get_response = $this->make_request( "/wp-json/kivicare/v1/patients/{$patient_id}", 'GET', array(), $this->doctor_user );
		$this->assertRestResponse( $get_response, 200 );
		
		$retrieved_patient = $get_response->get_data();
		$this->assertEquals( $patient_id, $retrieved_patient['id'] );
		$this->assertEquals( $clinic_id, $retrieved_patient['clinic_id'] );

		// STEP 6: Verify patient appears in clinic's patient list
		$list_response = $this->make_request( '/wp-json/kivicare/v1/patients', 'GET', array( 'clinic_id' => $clinic_id ), $this->doctor_user );
		$this->assertRestResponse( $list_response, 200 );
		
		$patients_list = $list_response->get_data();
		$this->assertIsArray( $patients_list['data'] );
		
		$found_patient = false;
		foreach ( $patients_list['data'] as $list_patient ) {
			if ( $list_patient['id'] === $patient_id ) {
				$found_patient = true;
				break;
			}
		}
		$this->assertTrue( $found_patient, 'Created patient should appear in clinic patient list' );
	}

	/**
	 * Test patient creation with duplicate email handling.
	 * 
	 * @test
	 */
	public function test_patient_creation_duplicate_email_handling() {
		// This test will fail initially as duplicate handling isn't implemented
		$this->markTestIncomplete( 'Duplicate email handling not implemented yet - TDD RED phase' );
		
		// ARRANGE: First patient created successfully
		$clinic_id = $this->create_test_clinic();
		$patient_data = array(
			'display_name' => 'João Silva',
			'user_email'   => 'joao@example.com',
			'clinic_id'    => $clinic_id,
		);

		$first_response = $this->make_request( '/wp-json/kivicare/v1/patients', 'POST', $patient_data, $this->doctor_user );
		$this->assertRestResponse( $first_response, 201 );

		// ACT: Try to create second patient with same email
		$duplicate_data = array(
			'display_name' => 'João Santos',
			'user_email'   => 'joao@example.com', // Same email
			'clinic_id'    => $clinic_id,
		);

		$duplicate_response = $this->make_request( '/wp-json/kivicare/v1/patients', 'POST', $duplicate_data, $this->doctor_user );
		
		// ASSERT: Should return appropriate error
		$this->assertRestResponse( $duplicate_response, 409 );
		
		$error_data = $duplicate_response->get_data();
		$this->assertEquals( 'duplicate_email', $error_data['code'] );
	}

	/**
	 * Test patient creation with data validation.
	 * 
	 * @test
	 */
	public function test_patient_creation_data_validation() {
		// This test will fail initially as validation isn't implemented
		$this->markTestIncomplete( 'Patient data validation not implemented yet - TDD RED phase' );
		
		$clinic_id = $this->create_test_clinic();

		// Test required field validation
		$invalid_data_sets = array(
			// Missing name
			array(
				'data'  => array( 'user_email' => 'test@example.com', 'clinic_id' => $clinic_id ),
				'field' => 'display_name',
			),
			// Missing email
			array(
				'data'  => array( 'display_name' => 'Test Patient', 'clinic_id' => $clinic_id ),
				'field' => 'user_email',
			),
			// Invalid email format
			array(
				'data'  => array( 'display_name' => 'Test Patient', 'user_email' => 'invalid-email', 'clinic_id' => $clinic_id ),
				'field' => 'user_email',
			),
			// Missing clinic
			array(
				'data'  => array( 'display_name' => 'Test Patient', 'user_email' => 'test@example.com' ),
				'field' => 'clinic_id',
			),
			// Invalid clinic ID
			array(
				'data'  => array( 'display_name' => 'Test Patient', 'user_email' => 'test@example.com', 'clinic_id' => 99999 ),
				'field' => 'clinic_id',
			),
		);

		foreach ( $invalid_data_sets as $test_case ) {
			$response = $this->make_request( '/wp-json/kivicare/v1/patients', 'POST', $test_case['data'], $this->doctor_user );
			
			$this->assertRestResponse( $response, 400 );
			
			$error_data = $response->get_data();
			$this->assertArrayHasKey( 'data', $error_data );
			$this->assertArrayHasKey( 'params', $error_data['data'] );
			$this->assertArrayHasKey( $test_case['field'], $error_data['data']['params'] );
		}
	}

	/**
	 * Test patient creation permissions by role.
	 * 
	 * @test
	 */
	public function test_patient_creation_permissions() {
		// This test will fail initially as permissions aren't implemented
		$this->markTestIncomplete( 'Patient creation permissions not implemented yet - TDD RED phase' );
		
		$clinic_id = $this->create_test_clinic();
		$patient_data = array(
			'display_name' => 'Test Patient',
			'user_email'   => 'test@example.com',
			'clinic_id'    => $clinic_id,
		);

		// Test different role permissions
		$role_tests = array(
			array( 'user_id' => $this->admin_user, 'expected_status' => 201 ),        // Admin can create
			array( 'user_id' => $this->doctor_user, 'expected_status' => 201 ),       // Doctor can create
			array( 'user_id' => $this->receptionist_user, 'expected_status' => 201 ), // Receptionist can create
			array( 'user_id' => $this->patient_user, 'expected_status' => 403 ),      // Patient cannot create
		);

		foreach ( $role_tests as $i => $test ) {
			// Make email unique for each test
			$test_data = $patient_data;
			$test_data['user_email'] = "test{$i}@example.com";
			
			$response = $this->make_request( '/wp-json/kivicare/v1/patients', 'POST', $test_data, $test['user_id'] );
			$this->assertRestResponse( $response, $test['expected_status'] );
		}
	}

	/**
	 * Test patient creation with clinic isolation.
	 * 
	 * @test
	 */
	public function test_patient_creation_clinic_isolation() {
		// This test will fail initially as clinic isolation isn't implemented
		$this->markTestIncomplete( 'Clinic isolation not implemented yet - TDD RED phase' );
		
		// ARRANGE: Two different clinics and doctors
		$clinic1_id = $this->create_test_clinic();
		$clinic2_id = $this->create_test_clinic();
		
		$doctor2_id = $this->factory->user->create( array( 'role' => 'doctor' ) );
		
		global $wpdb;
		// Map doctors to their respective clinics
		$wpdb->insert( $wpdb->prefix . 'kc_doctor_clinic_mappings', array( 'doctor_id' => $this->doctor_user, 'clinic_id' => $clinic1_id ) );
		$wpdb->insert( $wpdb->prefix . 'kc_doctor_clinic_mappings', array( 'doctor_id' => $doctor2_id, 'clinic_id' => $clinic2_id ) );

		// ACT: Doctor 1 tries to create patient in Doctor 2's clinic
		$patient_data = array(
			'display_name' => 'Cross Clinic Patient',
			'user_email'   => 'cross@example.com',
			'clinic_id'    => $clinic2_id, // Different clinic
		);

		$response = $this->make_request( '/wp-json/kivicare/v1/patients', 'POST', $patient_data, $this->doctor_user );
		
		// ASSERT: Should be forbidden
		$this->assertRestResponse( $response, 403 );
		
		$error_data = $response->get_data();
		$this->assertEquals( 'clinic_access_denied', $error_data['code'] );
	}
}