<?php

namespace App\Tests\Patient;

use App\Auth\Entity\User;
use App\Doctor\Entity\Doctor;
use App\Patient\Entity\PatientRecord;
use App\Tests\ApiTestCase;

/**
 * Integration coverage for PATCH /api/v1/patient/{uuid}:
 * the extended demographic fields persist, and mobile edits validate,
 * enforce uniqueness, and rewrite the patient's login identifier.
 *
 * Gate: a doctor caller falls back to the seeded `free` plan, which grants
 * `patient_records` in db_test — so no explicit subscription is needed.
 */
class PatientUpdateProfileTest extends ApiTestCase
{
    private User $doctorUser;
    private int $doctorId;

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

        $this->doctorUser = $this->createUser(['ROLE_DOCTOR']);
        $doctor = new Doctor($this->doctorUser, 'دکتر تست');
        $this->em->persist($doctor);
        $this->em->flush();
        $this->doctorId = $doctor->getId();
    }

    /** Create a patient User + PatientRecord owned by the test doctor; return the record uuid. */
    private function makeRecord(?string $mobile = null): array
    {
        $patient = $this->createUser(['ROLE_USER'], $mobile);
        $patient->setRealName('ساغر صابری نژاد');
        $this->em->persist($patient);

        $record = new PatientRecord('doctor', $this->doctorId, $patient, 'doctor', $this->doctorId);
        $this->em->persist($record);
        $this->em->flush();

        return [$record->getUuid(), $patient];
    }

    public function testUpdatePersistsExtendedDemographicFields(): void
    {
        [$uuid] = $this->makeRecord();

        $res = $this->authJson('PATCH', "/api/v1/patient/{$uuid}", $this->doctorUser, [
            'fathers_name'    => 'رضا',
            'education'       => 'کارشناسی',
            'field_of_study'  => 'نرم‌افزار',
            'job'             => 'مهندس',
            'province_id'     => 8,
            'city_id'         => 42,
            'postal_code'     => '8913746351',
            'referral_source' => 'اینستاگرام',
            'description'     => 'یادداشت آزمایشی',
        ]);

        self::assertSame(200, $this->responseCode());
        $profile = $res['data']['profile'] ?? [];
        self::assertSame('رضا', $profile['fathers_name']);
        self::assertSame('کارشناسی', $profile['education']);
        self::assertSame('نرم‌افزار', $profile['field_of_study']);
        self::assertSame('مهندس', $profile['job']);
        self::assertSame(8, $profile['province_id']);
        self::assertSame(42, $profile['city_id']);
        self::assertSame('8913746351', $profile['postal_code']);
        self::assertSame('اینستاگرام', $profile['referral_source']);
        self::assertSame('یادداشت آزمایشی', $profile['description']);
    }

    public function testEmptyStringClearsFieldToNull(): void
    {
        [$uuid] = $this->makeRecord();

        $this->authJson('PATCH', "/api/v1/patient/{$uuid}", $this->doctorUser, ['job' => 'مهندس']);
        $res = $this->authJson('PATCH', "/api/v1/patient/{$uuid}", $this->doctorUser, ['job' => '']);

        self::assertSame(200, $this->responseCode());
        self::assertNull($res['data']['profile']['job']);
    }

    public function testMobileEditRewritesLoginIdentifier(): void
    {
        [$uuid, $patient] = $this->makeRecord();
        $newMobile = '09' . str_pad((string) random_int(0, 999_999_999), 9, '0', STR_PAD_LEFT);

        $res = $this->authJson('PATCH', "/api/v1/patient/{$uuid}", $this->doctorUser, ['mobile' => $newMobile]);

        self::assertSame(200, $this->responseCode());
        self::assertSame($newMobile, $res['data']['profile']['mobile']);

        $this->em->refresh($patient);
        self::assertSame($newMobile, $patient->getMobileNumber());
        self::assertSame($newMobile, $patient->getUserIdentifier());
    }

    public function testMobileTakenByAnotherUserReturns409(): void
    {
        $taken = '09' . str_pad((string) random_int(0, 999_999_999), 9, '0', STR_PAD_LEFT);
        $this->createUser(['ROLE_USER'], $taken); // occupy the number

        [$uuid] = $this->makeRecord();
        $res = $this->authJson('PATCH', "/api/v1/patient/{$uuid}", $this->doctorUser, ['mobile' => $taken]);

        self::assertSame(409, $this->responseCode());
        self::assertSame('ERR_PROFILE_002', $res['errors'][0]['code']);
    }

    public function testInvalidMobileReturns422(): void
    {
        [$uuid] = $this->makeRecord();
        $res = $this->authJson('PATCH', "/api/v1/patient/{$uuid}", $this->doctorUser, ['mobile' => '12345']);

        self::assertSame(422, $this->responseCode());
        self::assertSame('ERR_VALIDATION_001', $res['errors'][0]['code']);
    }
}
