<?php

namespace App\ClinicInvitation\Repository;

use App\Doctor\Entity\Doctor;
use App\ClinicInvitation\Entity\ClinicDoctorInvitation;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

class ClinicDoctorInvitationRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, ClinicDoctorInvitation::class);
    }

    public function findByToken(string $token): ?ClinicDoctorInvitation
    {
        return $this->findOneBy(['token' => $token]);
    }

    public function findPendingByMobileAndClinic(string $mobile, int $clinicId): ?ClinicDoctorInvitation
    {
        return $this->createQueryBuilder('i')
            ->where('i.mobile = :mobile')
            ->andWhere('i.clinic = :clinicId')
            ->andWhere('i.status = :status')
            ->setParameter('mobile', $mobile)
            ->setParameter('clinicId', $clinicId)
            ->setParameter('status', ClinicDoctorInvitation::STATUS_PENDING)
            ->setMaxResults(1)
            ->getQuery()
            ->getOneOrNullResult();
    }

    /** @return ClinicDoctorInvitation[] */
    public function findPendingByDoctor(Doctor $doctor): array
    {
        return $this->createQueryBuilder('i')
            ->where('i.doctor = :doctor')
            ->andWhere('i.status = :status')
            ->setParameter('doctor', $doctor)
            ->setParameter('status', ClinicDoctorInvitation::STATUS_PENDING)
            ->orderBy('i.invitedAt', 'DESC')
            ->getQuery()
            ->getResult();
    }

    /**
     * شناسهٔ پزشکانی که دعوت پذیرفته‌شده در این کلینیک دارند.
     *
     * @return int[]
     */
    public function acceptedDoctorIdsByClinic(int $clinicId): array
    {
        $rows = $this->createQueryBuilder('i')
            ->select('IDENTITY(i.doctor) AS doctorId')
            ->where('i.clinic = :clinicId')
            ->andWhere('i.status = :accepted')
            ->andWhere('i.doctor IS NOT NULL')
            ->setParameter('clinicId', $clinicId)
            ->setParameter('accepted', ClinicDoctorInvitation::STATUS_ACCEPTED)
            ->getQuery()
            ->getScalarResult();

        return array_map(static fn(array $r) => (int) $r['doctorId'], $rows);
    }

    public function save(ClinicDoctorInvitation $invitation): void
    {
        $em = $this->getEntityManager();
        $em->persist($invitation);
        $em->flush();
    }
}
