<?php

namespace App\Tests\Appointment;

use App\Auth\Entity\User;
use App\Tests\ApiTestCase;
use App\UserProfile\Entity\UserProfile;

/**
 * GET /api/v1/my/appointment/patient-lookup — patient search by mobile OR
 * national code, used by the booking form before asking for national code / name.
 */
class PatientLookupTest extends ApiTestCase
{
    private function booker(): User
    {
        return $this->createUser(['ROLE_DOCTOR']);
    }

    private function mobile(): string
    {
        return '09' . str_pad((string) random_int(0, 999_999_999), 9, '0', STR_PAD_LEFT);
    }

    private function nationalCode(): string
    {
        return '00' . str_pad((string) random_int(0, 99_999_999), 8, '0', STR_PAD_LEFT);
    }

    public function testFoundWithNationalCode(): void
    {
        $mobile = $this->mobile();
        $nc     = $this->nationalCode();
        $patient = $this->createUser(['ROLE_USER'], $mobile);
        $patient->setRealName('علی محمدی');
        $profile = new UserProfile($patient);
        $profile->setNationalCode($nc);
        $this->em->persist($profile);
        $this->em->flush();

        $res = $this->authJson('GET', '/api/v1/my/appointment/patient-lookup?mobile=' . $mobile, $this->booker());

        self::assertSame(200, $this->responseCode());
        self::assertTrue($res['data']['found']);
        self::assertSame('علی محمدی', $res['data']['name']);
        self::assertSame($nc, $res['data']['national_code']);
    }

    public function testFoundWithoutNationalCode(): void
    {
        $mobile  = $this->mobile();
        $patient = $this->createUser(['ROLE_USER'], $mobile);
        $patient->setRealName('بدون کدملی');
        $this->em->flush();

        $res = $this->authJson('GET', '/api/v1/my/appointment/patient-lookup?mobile=' . $mobile, $this->booker());

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

    public function testNotFound(): void
    {
        $res = $this->authJson('GET', '/api/v1/my/appointment/patient-lookup?mobile=' . $this->mobile(), $this->booker());

        self::assertSame(200, $this->responseCode());
        self::assertFalse($res['data']['found']);
    }

    public function testInvalidMobileIs422(): void
    {
        $this->authJson('GET', '/api/v1/my/appointment/patient-lookup?mobile=123', $this->booker());

        self::assertSame(422, $this->responseCode());
    }

    public function testFoundByNationalCode(): void
    {
        $mobile = $this->mobile();
        $nc     = $this->nationalCode();
        $patient = $this->createUser(['ROLE_USER'], $mobile);
        $patient->setRealName('کدملی جو');
        $profile = new UserProfile($patient);
        $profile->setNationalCode($nc);
        $this->em->persist($profile);
        $this->em->flush();

        $res = $this->authJson('GET', '/api/v1/my/appointment/patient-lookup?national_code=' . $nc, $this->booker());

        self::assertSame(200, $this->responseCode());
        self::assertTrue($res['data']['found']);
        self::assertSame('کدملی جو', $res['data']['name']);
        self::assertSame($mobile, $res['data']['mobile']);
        self::assertSame($nc, $res['data']['national_code']);
    }

    public function testNationalCodeNotFound(): void
    {
        $res = $this->authJson('GET', '/api/v1/my/appointment/patient-lookup?national_code=' . $this->nationalCode(), $this->booker());

        self::assertSame(200, $this->responseCode());
        self::assertFalse($res['data']['found']);
    }

    public function testInvalidNationalCodeIs422(): void
    {
        $this->authJson('GET', '/api/v1/my/appointment/patient-lookup?national_code=123', $this->booker());

        self::assertSame(422, $this->responseCode());
    }

    public function testPlainUserIsForbidden(): void
    {
        $this->authJson('GET', '/api/v1/my/appointment/patient-lookup?mobile=' . $this->mobile(), $this->createUser(['ROLE_USER']));

        self::assertSame(403, $this->responseCode());
    }
}
