<?php

namespace App\Repository;

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

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

    public function findASlot($date_ref, $space, $period): ?Slot
    {
        $qb = $this->createQueryBuilder('s')
            ->where('s.startOn = :date_ref')
            ->andWhere('s.space = :space')
            ->andWhere('s.period = :period')
            ->setParameter('date_ref', $date_ref)
            ->setParameter('period', $period)
            ->setParameter('space', $space)
            ->getQuery();
        return $qb->getOneOrNullResult();
    }

    public function findNext($slot): ?Slot
    {
        $qb = $this->createQueryBuilder('s')
            ->where('s.startOn = :endThis')
            ->andWhere('s.period = :periodThis')
            ->andWhere('s.space = :spaceThis')
            ->setParameter('endThis', $slot->getEndOn())
            ->setParameter('periodThis', $slot->getPeriod())
            ->setParameter('spaceThis', $slot->getSpace())
            ->getQuery();
        
        return $qb->getOneOrNullResult();
    }

    public function findPrevious($slot): ?Slot
    {
        $qb = $this->createQueryBuilder('s')
            ->where('s.endOn = :startThis')
            ->andWhere('s.period = :periodThis')
            ->andWhere('s.space = :spaceThis')
            ->setParameter('startThis', $slot->getStartOn())
            ->setParameter('periodThis', $slot->getPeriod())
            ->setParameter('spaceThis', $slot->getSpace())
            ->getQuery();
        
        return $qb->getOneOrNullResult();
    }

    public function findNextsAvailables(Slot $slot): array 
    {
        $results = [];

        $nextSlot = $this->findNext($slot);

        while ($nextSlot && is_null($nextSlot->getParty()) && !$nextSlot->isUnavailable()) {
            $results[] = $nextSlot;
            $nextSlot = $this->findNext($nextSlot);
        }

        return $results;
    }

    public function findById(int $id): ?Slot
    {
        $qb = $this->createQueryBuilder('s')
            ->where('s.id = :id')
            ->setParameter('id', $id)
            ->getQuery();
        
        return $qb->getOneOrNullResult();
    }


    //    /**
    //     * @return Slot[] Returns an array of Slot objects
    //     */
    //    public function findByExampleField($value): array
    //    {
    //        return $this->createQueryBuilder('s')
    //            ->andWhere('s.exampleField = :val')
    //            ->setParameter('val', $value)
    //            ->orderBy('s.id', 'ASC')
    //            ->setMaxResults(10)
    //            ->getQuery()
    //            ->getResult()
    //        ;
    //    }

    //    public function findOneBySomeField($value): ?Slot
    //    {
    //        return $this->createQueryBuilder('s')
    //            ->andWhere('s.exampleField = :val')
    //            ->setParameter('val', $value)
    //            ->getQuery()
    //            ->getOneOrNullResult()
    //        ;
    //    }
}
