<?php

namespace App\Tests\Doctor;

use App\Doctor\Entity\Doctor;
use App\Specialty\Entity\Specialty;
use App\Specialty\Repository\SpecialtyRepository;
use App\Tests\ApiTestCase;

/**
 * Specialties are a tree. Whenever a child specialty is attached to a doctor,
 * every ancestor up to the root must be attached too — clients (the IRIMC
 * crawler, the admin panel) only ever send the leaf id.
 */
class DoctorSpecialtyParentsTest extends ApiTestCase
{
    private function makeSpecialty(string $name, ?Specialty $parent = null): Specialty
    {
        $specialty = new Specialty($name, 'sp-' . bin2hex(random_bytes(6)), $parent);
        $this->em->persist($specialty);
        $this->em->flush();

        return $specialty;
    }

    private function repo(): SpecialtyRepository
    {
        return $this->em->getRepository(Specialty::class);
    }

    public function testExpandWithAncestorsWalksTheWholeChain(): void
    {
        $root   = $this->makeSpecialty('داخلی');
        $child  = $this->makeSpecialty('گوارش و کبد', $root);
        $grand  = $this->makeSpecialty('آندوسکوپی', $child);

        $expected = [$root->getId(), $child->getId(), $grand->getId()];
        sort($expected);

        $this->assertSame($expected, $this->repo()->expandWithAncestors([$grand->getId()]));
    }

    public function testExpandWithAncestorsDeduplicatesAndDropsUnknownIds(): void
    {
        $root  = $this->makeSpecialty('داخلی');
        $child = $this->makeSpecialty('گوارش و کبد', $root);

        $expected = [$root->getId(), $child->getId()];
        sort($expected);

        $this->assertSame(
            $expected,
            $this->repo()->expandWithAncestors([$child->getId(), $root->getId(), $child->getId(), 99_999_999])
        );
    }

    public function testExpandWithAncestorsReturnsEmptyForNoInput(): void
    {
        $this->assertSame([], $this->repo()->expandWithAncestors([]));
        $this->assertSame([], $this->repo()->expandWithAncestors([99_999_999]));
    }

    public function testImportAttachesParentSpecialty(): void
    {
        $admin = $this->createUser(['ROLE_USER', 'ROLE_ADMIN']);
        $root  = $this->makeSpecialty('داخلی');
        $child = $this->makeSpecialty('گوارش و کبد', $root);

        $data = $this->authJson('POST', '/api/v1/admin/doctors/import', $admin, [
            'name'                => 'دکتر تست تخصص',
            'medical_system_code' => 'T' . random_int(100_000, 999_999) . random_int(100, 999),
            'specialties'         => [$child->getId()],
        ]);

        $this->assertSame(201, $this->responseCode());

        $doctor = $this->em->getRepository(Doctor::class)->findOneBy(['uuid' => $data['data']['uuid']]);
        $attached = array_map(static fn (Specialty $s) => $s->getId(), $doctor->getSpecialties()->toArray());
        sort($attached);

        $expected = [$root->getId(), $child->getId()];
        sort($expected);

        $this->assertSame($expected, $attached);
    }
}
