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

<?php
/**
 * PHPUnit bootstrap file for KiviCare API tests.
 *
 * @package Care_API\Tests
 */

// Define testing environment constants
define( 'KIVICARE_API_TESTS', true );
define( 'WP_USE_THEMES', false );

// Set the timezone to avoid warnings
if ( ! ini_get( 'date.timezone' ) ) {
	date_default_timezone_set( 'UTC' );
}

// Determine WordPress test directory
$_tests_dir = getenv( 'WP_TESTS_DIR' );
if ( ! $_tests_dir ) {
	$_tests_dir = rtrim( sys_get_temp_dir(), '/\\' ) . '/wordpress-tests-lib';
}

// Check if WordPress test suite exists
if ( ! file_exists( $_tests_dir . '/includes/functions.php' ) ) {
	echo "Could not find WordPress test suite at: $_tests_dir\n";
	echo "Please install WordPress test suite first:\n";
	echo "bash bin/install-wp-tests.sh wordpress_test root '' localhost latest\n";
	exit( 1 );
}

// Give access to tests_add_filter() function
require_once $_tests_dir . '/includes/functions.php';

/**
 * Manually load the plugin being tested.
 */
function _manually_load_plugin() {
	// Load KiviCare plugin if available (mock if not)
	$kivicare_plugin_file = WP_PLUGIN_DIR . '/kivicare-clinic-&-patient-management-system/kivicare-clinic-&-patient-management-system.php';
	
	if ( file_exists( $kivicare_plugin_file ) ) {
		require $kivicare_plugin_file;
	} else {
		// Mock KiviCare plugin functionality for testing
		require dirname( __FILE__ ) . '/mocks/mock-kivicare.php';
	}
	
	// Load our plugin
	require dirname( dirname( __FILE__ ) ) . '/src/care-api.php';
	
	// Activate our plugin
	activate_plugin( 'care-api/care-api.php' );
}
tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' );

/**
 * Setup test database tables.
 */
function _setup_test_tables() {
	global $wpdb;
	
	// Create KiviCare test tables
	require dirname( __FILE__ ) . '/setup/test-database.php';
	Care_API_Test_Database::create_tables();
	Care_API_Test_Database::insert_sample_data();
}
tests_add_filter( 'wp_install', '_setup_test_tables' );

// Start up the WP testing environment
require $_tests_dir . '/includes/bootstrap.php';

// Include Yoast PHPUnit Polyfills for compatibility
if ( class_exists( 'Yoast\PHPUnitPolyfills\Autoload' ) ) {
	require_once dirname( dirname( __FILE__ ) ) . '/vendor/yoast/phpunit-polyfills/phpunitpolyfills-autoload.php';
}

/**
 * Base test case class for KiviCare API tests.
 */
class Care_API_Test_Case extends WP_UnitTestCase {
	
	/**
	 * Setup before each test.
	 */
	public function setUp(): void {
		parent::setUp();
		
		// Clear any cached data
		wp_cache_flush();
		
		// Set up REST server
		global $wp_rest_server;
		$this->server = $wp_rest_server = new WP_REST_Server;
		do_action( 'rest_api_init' );
		
		// Create test user with proper roles
		$this->create_test_users();
	}
	
	/**
	 * Teardown after each test.
	 */
	public function tearDown(): void {
		// Clear any cached data
		wp_cache_flush();
		
		// Reset REST server
		global $wp_rest_server;
		$wp_rest_server = null;
		
		parent::tearDown();
	}
	
	/**
	 * Create test users for different roles.
	 */
	protected function create_test_users() {
		// Administrator
		$this->admin_user = $this->factory->user->create( array(
			'user_login' => 'test_admin',
			'user_email' => 'admin@example.com',
			'role'       => 'administrator',
		) );
		
		// Doctor
		$this->doctor_user = $this->factory->user->create( array(
			'user_login' => 'test_doctor',
			'user_email' => 'doctor@example.com',
			'role'       => 'doctor',
		) );
		
		// Patient
		$this->patient_user = $this->factory->user->create( array(
			'user_login' => 'test_patient',
			'user_email' => 'patient@example.com',
			'role'       => 'patient',
		) );
		
		// Receptionist
		$this->receptionist_user = $this->factory->user->create( array(
			'user_login' => 'test_receptionist',
			'user_email' => 'receptionist@example.com',
			'role'       => 'kivicare_receptionist',
		) );
	}
	
	/**
	 * Helper method to make REST API requests.
	 *
	 * @param string $endpoint The API endpoint.
	 * @param string $method   HTTP method.
	 * @param array  $data     Request data.
	 * @param int    $user_id  User ID for authentication.
	 * @return WP_REST_Response
	 */
	protected function make_request( $endpoint, $method = 'GET', $data = array(), $user_id = null ) {
		$request = new WP_REST_Request( $method, $endpoint );
		
		if ( ! empty( $data ) ) {
			$request->set_body_params( $data );
		}
		
		if ( $user_id ) {
			wp_set_current_user( $user_id );
		}
		
		return $this->server->dispatch( $request );
	}
	
	/**
	 * Helper method to create test clinic data.
	 *
	 * @return int Clinic ID.
	 */
	protected function create_test_clinic() {
		global $wpdb;
		
		$clinic_data = array(
			'name'            => 'Test Clinic',
			'email'           => 'test@clinic.com',
			'telephone_no'    => '+351912345678',
			'address'         => 'Test Address',
			'city'            => 'Lisboa',
			'state'           => 'Lisboa',
			'country'         => 'Portugal',
			'postal_code'     => '1000-001',
			'status'          => 1,
			'clinic_admin_id' => $this->admin_user,
			'created_at'      => current_time( 'mysql' ),
		);
		
		$wpdb->insert( $wpdb->prefix . 'kc_clinics', $clinic_data );
		return $wpdb->insert_id;
	}
	
	/**
	 * Helper method to create test appointment.
	 *
	 * @param int $clinic_id  Clinic ID.
	 * @param int $doctor_id  Doctor user ID.
	 * @param int $patient_id Patient user ID.
	 * @return int Appointment ID.
	 */
	protected function create_test_appointment( $clinic_id, $doctor_id, $patient_id ) {
		global $wpdb;
		
		$appointment_data = array(
			'appointment_start_date' => gmdate( 'Y-m-d', strtotime( '+1 day' ) ),
			'appointment_start_time' => '14:30:00',
			'appointment_end_date'   => gmdate( 'Y-m-d', strtotime( '+1 day' ) ),
			'appointment_end_time'   => '15:00:00',
			'clinic_id'              => $clinic_id,
			'doctor_id'              => $doctor_id,
			'patient_id'             => $patient_id,
			'status'                 => 1,
			'visit_type'             => 'consultation',
			'description'            => 'Test appointment',
			'created_at'             => current_time( 'mysql' ),
		);
		
		$wpdb->insert( $wpdb->prefix . 'kc_appointments', $appointment_data );
		return $wpdb->insert_id;
	}
	
	/**
	 * Assert that response has correct REST API format.
	 *
	 * @param WP_REST_Response $response The response object.
	 * @param int              $status   Expected status code.
	 */
	protected function assertRestResponse( $response, $status = 200 ) {
		$this->assertInstanceOf( 'WP_REST_Response', $response );
		$this->assertEquals( $status, $response->get_status() );
		
		if ( $status >= 400 ) {
			$data = $response->get_data();
			$this->assertArrayHasKey( 'code', $data );
			$this->assertArrayHasKey( 'message', $data );
		}
	}
}