<?php

namespace App\Repository;

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

/**
 * @method Location|null find($id, $lockMode = null, $lockVersion = null)
 * @method Location|null findOneBy(array $criteria, array $orderBy = null)
 * @method Location[]    findAll()
 * @method Location[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 */
class LocationViewRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, LocationView::class);
    }

    public function findBySpecialistId(
        int $specialistId, 
        bool $onlineMode = false, 
        ?int $department = null,
        ?\DateTimeInterface $startDate = null,
        ?\DateTimeInterface $endDate = null
    ): array {
        // Основной запрос
        $qb = $this->createQueryBuilder('l')
            ->select('l.id, l.dcode, l.department, l.onlineMode, l.filial, l.active, l.nearestDate, d.name')
            ->leftJoin('App\Entity\Department', 'd', 'WITH', 'd.did = l.department')
            ->where('l.specialistId = :specialistId')
            ->setParameter('specialistId', $specialistId)
            ->andWhere('l.active = true')
            ->andWhere('l.onlineMode = :onlineMode')
            ->setParameter('onlineMode', $onlineMode);
        
        // Фильтр по отделению (специализации), если указано
        if ($department !== null && $department > 0) {
            $qb->andWhere('l.department = :department')
               ->setParameter('department', $department);
        }
        
        // Фильтр по дате приема (диапазон дат), если указано
        if ($startDate !== null) {
            $qb->andWhere('l.nearestDate >= :startDate')
               ->setParameter('startDate', $startDate);
        }
        
        if ($endDate !== null) {
            $qb->andWhere('l.nearestDate <= :endDate')
               ->setParameter('endDate', $endDate);
        }
        
        // Сортировка по ближайшему приему: сначала ближайшие даты (ASC), NULL значения в конце
        $qb->orderBy('CASE WHEN l.nearestDate IS NULL THEN 1 ELSE 0 END', 'ASC')
           ->addOrderBy('l.nearestDate', 'ASC');
        
        $mainQuery = $qb->getQuery()->getResult();

        if (empty($mainQuery)) {
            return [];
        }

        // Получаем все уникальные filialId из основного запроса
        $filialIds = array_filter(array_unique(array_column($mainQuery, 'filial')));

        if (empty($filialIds)) {
            return $mainQuery;
        }

        // Запрос для получения данных Filial через EntityManager
        $entityManager = $this->getEntityManager();
        $filialQuery = $entityManager->createQueryBuilder()
            ->select('f.fid, f.address, f.company, f.addressName')
            ->from('App\Entity\Filial', 'f')
            ->where('f.fid IN (:filialIds)')
            ->setParameter('filialIds', $filialIds)
            ->getQuery()
            ->getResult();

        // Создаем мапу для быстрого доступа к данным Filial
        $filialMap = [];
        foreach ($filialQuery as $filial) {
            $filialMap[$filial['fid']] = [
                'address' => $filial['address'],
                'company' => $filial['company'],
                'addressName' => $filial['addressName']
            ];
        }

        // Объединяем данные
        foreach ($mainQuery as &$record) {
            $filialId = $record['filial'];
            if ($filialId && isset($filialMap[$filialId])) {
                $record = array_merge($record, $filialMap[$filialId]);
            } else {
                // Добавляем пустые значения если filial не найден
                $record['address'] = null;
                $record['company'] = null;
                $record['addressName'] = null;
            }
        }

        return $mainQuery;
    }
}
