<?php

namespace App\Clinic\Repository;

use App\Clinic\Entity\Clinic;
use App\Clinic\Entity\ClinicDoctorPermission;
use App\Doctor\Entity\Doctor;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

/**
 * @extends ServiceEntityRepository<ClinicDoctorPermission>
 */
class ClinicDoctorPermissionRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, ClinicDoctorPermission::class);
    }

    public function findOneFor(Clinic $clinic, Doctor $doctor): ?ClinicDoctorPermission
    {
        return $this->findOneBy(['clinic' => $clinic, 'doctor' => $doctor]);
    }

    /** @return ClinicDoctorPermission[] */
    public function findByClinic(Clinic $clinic): array
    {
        return $this->findBy(['clinic' => $clinic]);
    }

    /**
     * پزشکانی که پیش از این قابلیت عضو شده‌اند سطر مجوز ندارند؛ در اولین دسترسی
     * با مجوز پیش‌فرض ساخته می‌شود.
     */
    public function getOrCreate(Clinic $clinic, Doctor $doctor): ClinicDoctorPermission
    {
        $perm = $this->findOneFor($clinic, $doctor);
        if ($perm !== null) {
            return $perm;
        }

        $perm = new ClinicDoctorPermission($clinic, $doctor);
        $em   = $this->getEntityManager();
        $em->persist($perm);
        $em->flush();

        return $perm;
    }

    /**
     * مجوزهای یک پزشک در چند کلینیک، کلیددار با شناسهٔ کلینیک — برای پرهیز از N+1
     * هنگام ساخت available_contexts.
     *
     * @param  int[] $clinicIds
     * @return array<int, ClinicDoctorPermission>
     */
    public function mapByClinicForDoctor(Doctor $doctor, array $clinicIds): array
    {
        if ($clinicIds === []) {
            return [];
        }

        $rows = $this->createQueryBuilder('p')
            ->andWhere('p.doctor = :doctor')
            ->andWhere('IDENTITY(p.clinic) IN (:clinics)')
            ->setParameter('doctor', $doctor)
            ->setParameter('clinics', $clinicIds)
            ->getQuery()
            ->getResult();

        $map = [];
        foreach ($rows as $row) {
            $map[$row->getClinic()->getId()] = $row;
        }

        return $map;
    }

    public function deleteFor(Clinic $clinic, Doctor $doctor): void
    {
        $perm = $this->findOneFor($clinic, $doctor);
        if ($perm === null) {
            return;
        }

        $em = $this->getEntityManager();
        $em->remove($perm);
        $em->flush();
    }
}
