<?php

namespace App\Specialty\Repository;

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

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

    /** @return Specialty[] */
    public function findActive(?int $parentId = null): array
    {
        $qb = $this->createQueryBuilder('s')
            ->where('s.status = 1')
            ->orderBy('s.weight', 'ASC')
            ->addOrderBy('s.name', 'ASC');

        if ($parentId !== null) {
            $qb->andWhere('s.parent = :parent')->setParameter('parent', $parentId);
        }

        return $qb->getQuery()->getResult();
    }

    /**
     * Count distinct doctors per specialty, optionally limited to a city.
     * Mirrors the join filters used by the public doctor list (cities/specialties).
     *
     * @return array<int,int> specialtyId => doctorCount
     */
    public function doctorCountsByCity(?int $cityId): array
    {
        $qb = $this->getEntityManager()->createQueryBuilder()
            ->select('s.id AS specialty_id', 'COUNT(DISTINCT d.id) AS cnt')
            ->from(Doctor::class, 'd')
            ->join('d.specialties', 's')
            ->groupBy('s.id');

        if ($cityId !== null) {
            $qb->join('d.cities', 'c')
               ->andWhere('c.id = :city')
               ->setParameter('city', $cityId);
        }

        $map = [];
        foreach ($qb->getQuery()->getArrayResult() as $row) {
            $map[(int) $row['specialty_id']] = (int) $row['cnt'];
        }

        return $map;
    }

    public function findBySlug(string $slug): ?Specialty
    {
        return $this->findOneBy(['slug' => $slug]);
    }

    public function save(Specialty $specialty, bool $flush = true): void
    {
        $this->getEntityManager()->persist($specialty);
        if ($flush) $this->getEntityManager()->flush();
    }

    public function remove(Specialty $specialty, bool $flush = true): void
    {
        $this->getEntityManager()->remove($specialty);
        if ($flush) $this->getEntityManager()->flush();
    }
}
