<?php

namespace Tests\Feature\PatVisit;

use CodeIgniter\Test\FeatureTestTrait;
use CodeIgniter\Test\CIUnitTestCase;
use Tests\Support\Traits\CreatesPatients;

class PatVisitUpdateTest extends CIUnitTestCase
{
    use FeatureTestTrait;
    use CreatesPatients;
    protected $endpoint = 'api/patvisit';

    protected function setUp(): void
    {
        parent::setUp();
    }

    /**
     * Test: Update patient visit successfully
     */
    public function testUpdatePatientVisitSuccess()
    {
        // First create a visit to update
        $createPayload = [
            "InternalPID"=> $this->createTestPatient(),
            "EpisodeID"=> "TEST001",
            "PatVisitADT"=> [
                "ADTCode"=> "A01",
                "LocationID"=> "1"
            ]
        ];

        $createResponse = $this->withBodyFormat('json')->call('post', 'api/patvisit', $createPayload);
        $createResponse->assertStatus(201);
        
        $createJson = json_decode($createResponse->getJSON(), true);
        $internalPVID = $createJson['data']['InternalPVID'];
        $pvid = $createJson['data']['PVID'];

        // Now update it
        $payload = [
            'PVID'         => $pvid,
            'EpisodeID'    => 'EPI001',
            'PatDiag' => [
                'DiagCode' => 'A02',
                'DiagName' => 'Dysentery'
            ],
            'PatVisitADT' => [
                'LocationID' => 12,
                'AdmitDate'  => date('Y-m-d H:i:s')
            ]
        ];

        $response = $this->withBodyFormat('json')->call('patch', $this->endpoint . '/' . $internalPVID, $payload);

        // Pastikan response sukses (200 OK untuk update)
        $response->assertStatus(200);

        // Periksa fragment JSON
        $response->assertJSONFragment([
            'status'  => 'success',
            'message' => 'Data updated successfully',
        ]);

        // Pastikan response mengandung data yang sesuai
        $json = json_decode($response->getJSON(), true);
        $this->assertArrayHasKey('data', $json);
        $this->assertEquals($pvid, $json['data']['PVID']);
    }

    /**
     * Test: Update patient visit with missing ID
     */
    public function testUpdatePatientVisitMissingId()
    {
        // InternalPVID tidak ada
        $payload = [
            'EpisodeID' => 'EPI002',
            'PatDiag'   => ['DiagCode' => 'B01', 'DiagName' => 'Flu']
        ];

        $response = $this->withBodyFormat('json')->call('patch', $this->endpoint . '/0', $payload);
        // Karena ID tidak valid → 400 Bad Request
        $response->assertStatus(400);

        $response->assertJSONFragment([
            'status'  => 'error',
            'message' => 'Invalid or missing ID'
        ]);
    }

    /**
     * Test: Update patient visit with non-existent ID
     */
    public function testUpdatePatientVisitNotFound()
    {
        $payload = [
            'EpisodeID'    => 'EPI001',
            'PatDiag' => [
                'DiagCode' => 'A02',
                'DiagName' => 'Dysentery'
            ]
        ];

        $response = $this->withBodyFormat('json')->call('patch', $this->endpoint . '/999999', $payload);
        $response->assertStatus(404);
        $response->assertJSONFragment([
            'status'  => 'error',
            'message' => 'Visit not found'
        ]);
    }

    /**
     * Test: Update patient visit with invalid ID (non-numeric)
     */
    public function testUpdatePatientVisitInvalidId()
    {
        $payload = [
            'PVID'         => 'DV0001',
            'EpisodeID'    => 'EPI001',
            'PatDiag' => [
                'DiagCode' => 'A02',
                'DiagName' => 'Dysentery'
            ],
            'PatVisitADT' => [
                'LocationID' => 12,
                'AdmitDate'  => date('Y-m-d H:i:s')
            ]
        ];

        $response = $this->withBodyFormat('json')->call('patch', $this->endpoint . '/invalid', $payload);
        $response->assertStatus(400);
        $response->assertJSONFragment([
            'status'  => 'error',
            'message' => 'Invalid or missing ID'
        ]);
    }

    /**
     * Test: Update patient visit with empty payload
     */
    public function testUpdatePatientVisitInvalidInput()
    {
        $payload = [];

        $response = $this->withBodyFormat('json')->call('patch', $this->endpoint . '/0', $payload);
        $response->assertStatus(400);
        $response->assertJSONFragment([
            'status'  => 'error',
            'message' => 'Invalid or missing ID'
        ]);
    }

    public function testPatchWithoutPatDiagKeepsExistingPatDiag(): void
    {
        $createPayload = [
            'InternalPID' => $this->createTestPatient(),
            'EpisodeID' => 'KEEP-DIAG',
            'PatDiag' => [
                'DiagCode' => 'A02',
                'DiagName' => 'Original Diagnosis',
            ],
            'PatVisitADT' => [
                'ADTCode' => 'A01',
                'LocationID' => '1',
            ],
        ];

        $createResponse = $this->withBodyFormat('json')->call('post', 'api/patvisit', $createPayload);
        $createResponse->assertStatus(201);

        $createJson = json_decode($createResponse->getJSON(), true);
        $internalPVID = $createJson['data']['InternalPVID'];
        $pvid = $createJson['data']['PVID'];

        $patchResponse = $this->withBodyFormat('json')->call('patch', $this->endpoint . '/' . $internalPVID, [
            'EpisodeID' => 'KEEP-DIAG-UPDATED',
        ]);
        $patchResponse->assertStatus(200);

        $showResponse = $this->call('get', $this->endpoint . '/' . $pvid);
        $showResponse->assertStatus(200);

        $showJson = json_decode($showResponse->getJSON(), true);
        $this->assertEquals('A02', $showJson['data']['DiagCode'] ?? null);
    }

}
