<?php

namespace App\Tests\Resource;

use App\Auth\Entity\User;
use App\Branch\Entity\Room;
use App\Clinic\Entity\Clinic;
use App\Doctor\Entity\Doctor;
use App\Doctor\Entity\DoctorAddress;
use App\Resource\Entity\ResourceType;
use App\Staff\Entity\ClinicStaff;
use App\Tests\ApiTestCase;

/**
 * فیکسچرهای مشترک دامنهٔ منبع. هر تست به یک محیط با آدرس و یک نوع منبع نیاز دارد،
 * و برای سنجش مرز ۴۰۴ به یک محیط بیگانه.
 */
abstract class ResourceTestCase extends ApiTestCase
{
    /** @return array{0: User, 1: Clinic, 2: DoctorAddress} */
    protected function clinicWithAddress(string $addressName = 'شعبهٔ مرکزی'): array
    {
        $user   = $this->createUser(['ROLE_USER', 'ROLE_CLINIC']);
        $clinic = new Clinic($user);
        $clinic->setName('کلینیک منابع');
        $this->em->persist($clinic);
        $this->em->flush();

        $address = DoctorAddress::forClinic($clinic->getId());
        $address->setName($addressName);
        $this->em->persist($address);
        $this->em->flush();

        return [$user, $clinic, $address];
    }

    /** آدرس دوم همان محیط — برای سنجش قاعدهٔ «همهٔ اعضای استخر در یک شعبه». */
    protected function extraAddress(Clinic $clinic, string $name = 'شعبهٔ دوم'): DoctorAddress
    {
        $address = DoctorAddress::forClinic($clinic->getId());
        $address->setName($name);
        $this->em->persist($address);
        $this->em->flush();

        return $address;
    }

    /** @return array{0: User, 1: Doctor, 2: DoctorAddress} */
    protected function doctorWithAddress(): array
    {
        $user   = $this->createUser(['ROLE_USER', 'ROLE_DOCTOR']);
        $doctor = new Doctor($user, 'دکتر منبع');
        $doctor->setMobileNumber($user->getMobileNumber());
        $this->em->persist($doctor);
        $this->em->flush();

        $address = DoctorAddress::forDoctor($doctor);
        $address->setName('مطب شخصی');
        $this->em->persist($address);
        $this->em->flush();

        return [$user, $doctor, $address];
    }

    protected function resourceType(DoctorAddress $address, string $code = 'device', string $name = 'دستگاه'): ResourceType
    {
        $type = new ResourceType($address->tenantEntityType(), $address->tenantEntityId(), $code, $name);
        $this->em->persist($type);
        $this->em->flush();

        return $type;
    }

    protected function staff(DoctorAddress $address, string $name = 'اپراتور یک'): ClinicStaff
    {
        $staff = new ClinicStaff($address->tenantEntityType(), $address->tenantEntityId(), $name);
        $this->em->persist($staff);
        $this->em->flush();

        return $staff;
    }

    protected function room(DoctorAddress $address, string $name = 'اتاق تزریق', int $capacity = 1): Room
    {
        $room = new Room($address, $name);
        $room->setCapacity($capacity);
        $this->em->persist($room);
        $this->em->flush();

        return $room;
    }

    /** @param array<string, mixed> $body */
    protected function createResource(User $user, DoctorAddress $address, ResourceType $type, array $body = []): array
    {
        return $this->authJson('POST', '/api/v1/resource', $user, $body + [
            'address_uuid' => $address->getUuid(),
            'type_uuid'    => $type->getUuid(),
            'name'         => 'لیزر آلکساندرایت ۱',
        ]);
    }

    protected function createSkill(User $user, string $name = 'لیزر آلکساندرایت'): array
    {
        return $this->authJson('POST', '/api/v1/skills', $user, ['name' => $name]);
    }
}
