<?php

namespace Tests\Unit\Patient;

use CodeIgniter\Test\CIUnitTestCase;
use App\Models\Patient\PatientModel;

/**
 * PatientModelTest
 * 
 * Unit tests for PatientModel - Testing model configuration only
 * These tests don't require a database connection
 * 
 * For tests that require database, use Feature tests instead
 * 
 * Test Cases:
 * 1. testModelInstantiation - Model can be instantiated
 * 2. testModelHasCorrectTable - Model points to correct table
 * 3. testModelHasCorrectPrimaryKey - Model has correct primary key
 * 4. testModelUsesSoftDeletes - Model uses soft deletes
 * 5. testModelHasCorrectDeletedField - Model has correct deleted field
 * 6. testModelHasCorrectCreatedField - Model has correct created field
 * 7. testModelHasAllowedFields - Model has correct allowed fields
 */
class PatientModelTest extends CIUnitTestCase
{
    protected PatientModel $model;

    protected function setUp(): void
    {
        parent::setUp();
        $this->model = new PatientModel();
    }

    /**
     * Test Case 1: Model can be instantiated
     */
    public function testModelInstantiation()
    {
        $this->assertInstanceOf(PatientModel::class, $this->model);
    }

    /**
     * Test Case 2: Model has correct table name
     */
    public function testModelHasCorrectTable()
    {
        $reflection = new \ReflectionClass($this->model);
        $property = $reflection->getProperty('table');
        $property->setAccessible(true);
        
        $this->assertEquals('patient', $property->getValue($this->model));
    }

    /**
     * Test Case 3: Model has correct primary key
     */
    public function testModelHasCorrectPrimaryKey()
    {
        $reflection = new \ReflectionClass($this->model);
        $property = $reflection->getProperty('primaryKey');
        $property->setAccessible(true);
        
        $this->assertEquals('InternalPID', $property->getValue($this->model));
    }

    /**
     * Test Case 4: Model uses soft deletes
     */
    public function testModelUsesSoftDeletes()
    {
        $reflection = new \ReflectionClass($this->model);
        $property = $reflection->getProperty('useSoftDeletes');
        $property->setAccessible(true);
        
        $this->assertTrue($property->getValue($this->model));
    }

    /**
     * Test Case 5: Model has correct deleted field
     */
    public function testModelHasCorrectDeletedField()
    {
        $reflection = new \ReflectionClass($this->model);
        $property = $reflection->getProperty('deletedField');
        $property->setAccessible(true);
        
        $this->assertEquals('DelDate', $property->getValue($this->model));
    }

    /**
     * Test Case 6: Model has correct created field
     */
    public function testModelHasCorrectCreatedField()
    {
        $reflection = new \ReflectionClass($this->model);
        $property = $reflection->getProperty('createdField');
        $property->setAccessible(true);
        
        $this->assertEquals('CreateDate', $property->getValue($this->model));
    }

    /**
     * Test Case 7: Model allowed fields contain required fields
     */
    public function testModelHasAllowedFields()
    {
        $reflection = new \ReflectionClass($this->model);
        $property = $reflection->getProperty('allowedFields');
        $property->setAccessible(true);
        
        $allowedFields = $property->getValue($this->model);
        
        $this->assertIsArray($allowedFields);
        $this->assertContains('PatientID', $allowedFields);
        $this->assertContains('NameFirst', $allowedFields);
        $this->assertContains('Sex', $allowedFields);
        $this->assertContains('Birthdate', $allowedFields);
        $this->assertContains('EmailAddress1', $allowedFields);
        $this->assertContains('Phone', $allowedFields);
        $this->assertContains('MobilePhone', $allowedFields);
    }

    /**
     * Test Case 8: Model uses timestamps
     */
    public function testModelUsesTimestamps()
    {
        $reflection = new \ReflectionClass($this->model);
        $property = $reflection->getProperty('useTimestamps');
        $property->setAccessible(true);
        
        $this->assertTrue($property->getValue($this->model));
    }

    /**
     * Test Case 9: Model has no updated field (empty string)
     */
    public function testModelHasNoUpdatedField()
    {
        $reflection = new \ReflectionClass($this->model);
        $property = $reflection->getProperty('updatedField');
        $property->setAccessible(true);
        
        $this->assertEquals('', $property->getValue($this->model));
    }

    /**
     * Test Case 10: Model allowed fields count
     */
    public function testModelAllowedFieldsCount()
    {
        $reflection = new \ReflectionClass($this->model);
        $property = $reflection->getProperty('allowedFields');
        $property->setAccessible(true);
        
        $allowedFields = $property->getValue($this->model);
        
        // Should have a reasonable number of fields
        $this->assertGreaterThan(20, count($allowedFields));
    }

    /**
     * Test Case 11: Model allowed fields contain address fields
     */
    public function testModelHasAddressFields()
    {
        $reflection = new \ReflectionClass($this->model);
        $property = $reflection->getProperty('allowedFields');
        $property->setAccessible(true);
        
        $allowedFields = $property->getValue($this->model);
        
        $this->assertContains('Street_1', $allowedFields);
        $this->assertContains('Street_2', $allowedFields);
        $this->assertContains('Street_3', $allowedFields);
        $this->assertContains('City', $allowedFields);
        $this->assertContains('Province', $allowedFields);
        $this->assertContains('ZIP', $allowedFields);
    }

    /**
     * Test Case 12: Model allowed fields contain demographic fields
     */
    public function testModelHasDemographicFields()
    {
        $reflection = new \ReflectionClass($this->model);
        $property = $reflection->getProperty('allowedFields');
        $property->setAccessible(true);
        
        $allowedFields = $property->getValue($this->model);
        
        $this->assertContains('Country', $allowedFields);
        $this->assertContains('Race', $allowedFields);
        $this->assertContains('Religion', $allowedFields);
        $this->assertContains('Ethnic', $allowedFields);
        $this->assertContains('MaritalStatus', $allowedFields);
    }

    /**
     * Test Case 13: Model allowed fields contain death indicator
     */
    public function testModelHasIsDeadField()
    {
        $reflection = new \ReflectionClass($this->model);
        $property = $reflection->getProperty('allowedFields');
        $property->setAccessible(true);
        
        $allowedFields = $property->getValue($this->model);
        
        $this->assertContains('isDead', $allowedFields);
        $this->assertContains('TimeOfDeath', $allowedFields);
    }

    /**
     * Test Case 14: Model has getPatients method
     */
    public function testModelHasGetPatientsMethod()
    {
        $this->assertTrue(method_exists($this->model, 'getPatients'));
    }

    /**
     * Test Case 15: Model has getPatient method
     */
    public function testModelHasGetPatientMethod()
    {
        $this->assertTrue(method_exists($this->model, 'getPatient'));
    }

    /**
     * Test Case 16: Model has createPatient method
     */
    public function testModelHasCreatePatientMethod()
    {
        $this->assertTrue(method_exists($this->model, 'createPatient'));
    }

    /**
     * Test Case 17: Model has updatePatient method
     */
    public function testModelHasUpdatePatientMethod()
    {
        $this->assertTrue(method_exists($this->model, 'updatePatient'));
    }
}
