<?php

namespace Ig\IgReservations\Domain\Repository;

use TYPO3\CMS\Extbase\Persistence\Repository;
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
use Ig\IgReservations\Domain\Model\Event;
use Ig\IgReservations\Domain\Model\Reservation;
use TYPO3\CMS\Core\Context\Context;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;

/**
 * The repository for Reservations
 */
class ReservationRepository extends Repository
{
    /**
     * @var array
     */
    protected $defaultOrderings = [
        //'frontendUser' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING,
        'name' => QueryInterface::ORDER_ASCENDING,
        'event.startDate' => QueryInterface::ORDER_ASCENDING,
        'event.startTime' => QueryInterface::ORDER_ASCENDING,
    ];
    /*
      public function findByEventAndFeUser($event, $feUser)
      {
      $query = $this->createQuery();

      $query->matching(
      $query->logicalAnd(
      $query->equals('event', $event),
      $query->equals('feUser', $feUser)
      )
      );

      return $query->execute()->getFirst();
      }
    */
    public function secureAdd(Reservation $reservation): bool
    {
        $context = GeneralUtility::makeInstance(Context::class);
        $feUserGroups = $context->getPropertyFromAspect('frontend.user', 'groupIds');
        $event = $reservation->getEvent();
        $calendar = $event->getCalendar();
        $calendarAcl = $calendar->getAcl();

        // events are wirh startDate - endDate
        if ($calendar->getIsDateTimeMode()) {
            // event is free
            //findByStartDateTimeEndDateTimeAndCalendar
            $this->add($reservation);
        } else {
            // events are wirh timeslots

            $numberReservationPerTimeslot = $calendarAcl->getNumberReservationPerTimeslot();
            //        var_dump($numberReservationPerTimeslot, count($event->getUserReservation()));die('ende');
            $event->reset();
            if ($calendar->getMaxReservations() <= (is_countable($event->getReservations()) ? count(
                $event->getReservations()
            ) : 0)) {
                return false;
            }
            if ($numberReservationPerTimeslot > 0 && $numberReservationPerTimeslot <= (is_countable(
                $event->getUserReservation()
            ) ? count(
                $event->getUserReservation()
            ) : 0)) {
                return false;
            }
            // Only Admin can set another user
            $feUserUid = $context->getPropertyFromAspect('frontend.user', 'id');
            if (!$calendarAcl->getIsAdmin() && $reservation->getFrontendUser() && $feUserUid != $reservation->getFrontendUser()->getUid()) {
                return false;
            }
            $this->add($reservation);
        }
        GeneralUtility::makeInstance(PersistenceManager::class)->persistAll(); // Zum absichern

        return true;
    }
    public function secureUpdate(Reservation $reservation): bool
    {
        $this->update($reservation);
        GeneralUtility::makeInstance(PersistenceManager::class)->persistAll(); // Zum absichern
        return true;
    }
    public function secureRemove(Reservation $reservation = null): bool
    {
        if ($reservation == null) {
            return false;
        }
        $context = GeneralUtility::makeInstance(Context::class);
        $feUserGroups = $context->getPropertyFromAspect('frontend.user', 'groupIds');
        $feUserUid = $context->getPropertyFromAspect('frontend.user', 'id');
        $event = $reservation->getEvent();
        $calendar = $event->getCalendar();
        $calendarAcl = $calendar->getAcl();
        if (!$calendarAcl->getIsAdmin() && $reservation->getFrontendUser() && $feUserUid != $reservation->getFrontendUser()->getUid()) {
            return false;
        }
        $this->remove($reservation);
        GeneralUtility::makeInstance(PersistenceManager::class)->persistAll(); // Zum absichern
        return true;
    }

    public function findForReminder(Event $event)
    {
        $query = $this->createQuery();
        $query->getQuerySettings()->setRespectStoragePage(false);

        $query->matching($query->equals('event', $event));
        return $query->execute();
    }
}
