<?php

namespace Ig\IgReservations\Controller;

use Internetgalerie\IgDatapoolFe\Controller\ActionController;
use Ig\IgReservations\Domain\Repository\EventRepository;
use Ig\IgReservations\Domain\Repository\ReservationRepository;
use Ig\IgReservations\Domain\Repository\CalendarRepository;
use Ig\IgReservations\Domain\Repository\CategoryRepository;
use Ig\IgReservations\Domain\Repository\BookingTypeRepository;
use Ig\IgReservations\Domain\Repository\ReservationTypeRepository;
use Ig\IgReservations\Domain\Repository\StatusRepository;
use Ig\IgReservations\Domain\Repository\LocationRepository;
use Ig\IgReservations\Domain\Repository\FeUserRepository;
use TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter;
use Internetgalerie\IgDatapoolFe\Property\TypeConverter\HtmlConverter;
use Ig\IgReservations\Domain\Model\Timeslot;
use Ig\IgReservations\Domain\Model\Calendar;
use DateTime;
use Internetgalerie\IgDynval\Validation\Validator\DynamicValidator;
use TYPO3\CMS\Extbase\Annotation\IgnoreValidation;
use TYPO3\CMS\Extbase\Annotation\Validate;
use Ig\IgReservations\Domain\Model\Event;
use Ig\IgReservations\Domain\Model\Reservation;
use Ig\IgReservations\Domain\Repository\PurposeRepository;
use Ig\IgReservations\Service\MailService;
use Ig\IgReservations\Service\UserService;
use Internetgalerie\IgDynval\Controller\DynamicValidationActionController;
use Psr\Http\Message\ResponseInterface;
use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
use TYPO3\CMS\Fluid\View\StandaloneView;

/**
 * ReservationController
 */
class ReservationController extends ActionController
{
    use DynamicValidationActionController;

    /**
     * eventRepository
     *
     * @var EventRepository
     */
    protected $eventRepository = null;

    /**
     * reservationRepository
     *
     * @var ReservationRepository
     */
    protected $reservationRepository = null;

    /**
     * calendarRepository
     *
     * @var CalendarRepository
     */
    protected $calendarRepository = null;

    /**
     * categoryRepository
     *
     * @var CategoryRepository
     */
    protected $categoryRepository = null;

    /**
     * bookingTypeRepository
     *
     * @var BookingTypeRepository
     */
    protected $bookingTypeRepository = null;

    /**
     * reservationTypeRepository
     *
     * @var ReservationTypeRepository
     */
    protected $reservationTypeRepository = null;

    /**
     * statusRepository
     *
     * @var StatusRepository
     */
    protected $statusRepository = null;

    /**
     * locationRepository
     *
     * @var LocationRepository
     */
    protected $locationRepository = null;

    /**
     * feUserRepository
     *
     * @var FeUserRepository
     */
    protected $feUserRepository = null;

    protected PurposeRepository $purposeRepository;

    /**
     * MailService
     *
     * @var MailService
     */
    protected $mailService = null;

    /**
     * @var \Ig\IgReservations\Domain\Service\UserService
     */
    protected UserService $userService;

    
    public function injectEventRepository(EventRepository $eventRepository): void
    {
        $this->eventRepository = $eventRepository;
    }

    
    public function injectReservationRepository(
        ReservationRepository $reservationRepository
    ): void {
        $this->reservationRepository = $reservationRepository;
    }

    
    public function injectCalendarRepository(
        CalendarRepository $calendarRepository
    ): void {
        $this->calendarRepository = $calendarRepository;
    }

    
    public function injectCategoryRepository(
        CategoryRepository $categoryRepository
    ): void {
        $this->categoryRepository = $categoryRepository;
    }

    
    public function injectBookingTypeRepository(
        BookingTypeRepository $bookingTypeRepository
    ): void {
        $this->bookingTypeRepository = $bookingTypeRepository;
    }

    
    public function injectReservationTypeRepository(
        ReservationTypeRepository $reservationTypeRepository
    ): void {
        $this->reservationTypeRepository = $reservationTypeRepository;
    }

    
    public function injectStatusRepository(
        StatusRepository $statusRepository
    ): void {
        $this->statusRepository = $statusRepository;
    }

    
    public function injectLocationRepository(
        LocationRepository $locationRepository
    ): void {
        $this->locationRepository = $locationRepository;
    }

    
    public function injectFeUserRepository(
        FeUserRepository $feUserRepository
    ): void {
        $this->feUserRepository = $feUserRepository;
    }

    public function injectPurposeRepository(PurposeRepository $purposeRepository): void
    {
        $this->purposeRepository = $purposeRepository;
    }

    public function injectMailService(MailService $mailService): void
    {
        $this->mailService = $mailService;
    }

    public function injectUserService(UserService $userService): void
    {
        $this->userService = $userService;
    }

    public function initializeAction(): void
    {
        parent::initializeAction();
        if (isset($this->arguments['newReservation']) || isset($this->arguments['reservation'])) {
            $reservation = $this->arguments['newReservation'] ?? $this->arguments['reservation'];
            $pmc = $reservation
                ->getPropertyMappingConfiguration();
            $pmc->allowProperties('event');
            $pmc->forProperty('event')
                ->allowAllProperties();
            $pmc->forProperty('event.*')
                ->allowAllProperties();
            $pmc->forProperty('event.files.*')
                ->allowAllProperties();
            $pmc->forProperty('event.files.*.*')
                ->allowAllProperties();

            $pmc->forProperty('event.*')
                ->setTypeConverterOption(
                    DateTimeConverter::class,
                    DateTimeConverter::CONFIGURATION_DATE_FORMAT,
                    'Y-m-d'
                );
            $pmc->forProperty('event.description')
                ->setTypeConverter(
                    GeneralUtility::makeInstance(HtmlConverter::class)
                );
        }

        $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
        $pageRenderer->addCssFile('EXT:ig_reservations/Resources/Public/Lib/select2/select2.css');
        $pageRenderer->addCssFile('EXT:ig_reservations/Resources/Public/Css/ig_reservations.scss');
        $pageRenderer->addJsFooterFile('EXT:ig_reservations/Resources/Public/JavaScript/handlePurposes.js');
        $pageRenderer->addJsFooterFile('EXT:ig_reservations/Resources/Public/Lib/select2/select2.min.js');
        $pageRenderer->addJsFooterFile('EXT:ig_reservations/Resources/Public/Lib/select2/i18n/de.js');
        $pageRenderer->addJsFooterFile('EXT:ig_reservations/Resources/Public/JavaScript/ig_reservations.js');
        $this->mailService->setSettings($this->settings);
        $this->mailService->setRequest($this->request);
    }

    /**
     * action new
     *
     * @param array|null $search
     */
    public function newAction(
        string $date,
        Timeslot $timeslot = null,
        Calendar $calendar = null,
        Event $event = null,
        array $search = []
    ): ResponseInterface {
        $date = new DateTime($date ?: null);
        $date->setTime(12, 0, 0);

        if ($event) {
            $timeslot = $event->getTimeslot();
            $calendar = $event->getCalendar();
        } else {
            $event = $this->eventRepository->findOneByDateAndTimeslotAndCalendar(
                $date,
                $timeslot->getUid(),
                $calendar->getUid()
            );
        }
            
        $feUser = $this->userService->getUser();

        $newReservation = GeneralUtility::makeInstance(Reservation::class);
        if (!$event) {
            $event = GeneralUtility::makeInstance(Event::class);
            $event->setStartDate($date);
            $event->setTimeslot($timeslot);
            $event->setCalendar($calendar);
            $this->eventRepository->add($event);
            GeneralUtility::makeInstance(PersistenceManager::class)->persistAll();
        }

        $newReservation->setEvent($event);
        $newReservation->setFrontendUser($feUser);
        if ($this->request->hasArgument('multi')) {
            $multi = (int) $this->request->getArgument('multi');

            for ($i = 0; $i < $multi; $i++) {
                $this->reservationRepository->secureAdd(clone $newReservation);
            }
        } else {
            $this->reservationRepository->secureAdd($newReservation);
        }
        GeneralUtility::makeInstance(PersistenceManager::class)->persistAll(); // Zum absichern

        //$pluginName = $this->request->getPluginName();


        //$this->redirect('show', 'Calendar', null, ['search' => $search]);
        $this->view->assign(
            'users',
            $this->feUserRepository->findTeammembers($this->settings['usergroupForTeammembers'] ?: 0)
        );
        $this->view->assign('reservationTypes', $this->reservationTypeRepository->findAll());
        $this->view->assign('locations', $this->locationRepository->findAll());
        $this->view->assign('purposes', $this->purposeRepository->findAll());

        return $this->htmlResponse();
    }

    public function addToEventAction(Event $event): ResponseInterface
    {
        $reservation = GeneralUtility::makeInstance(Reservation::class);
        $reservation->setEvent($event);
        $canRepeat = null;
        $calendar = $event->getCalendar();
        $acl = $calendar->getAcl();
        $categories = $this->categoryRepository->findAll();
        $statusses = $this->statusRepository->findAll();
        $eventStartDate = clone $event->getStartDateTime();
        $eventEndDate = clone $event->getEndDateTime();
        $lastStartDateTime = clone $eventStartDate;
        $lastStartDateTime->modify('+1 year');

        $startTimestamp = $eventStartDate->getTimestamp();
        $endTimestamp = $eventEndDate->getTimestamp();

        $startDate = strftime('%Y-%m-%d', $startTimestamp);
        $startTime = strftime('%H:%M:%S', $startTimestamp);
        $endDate = strftime('%Y-%m-%d', $endTimestamp);
        $endTime = strftime('%H:%M:%S', $endTimestamp);

        $possibleEndTimes = $calendar->getPossibleStartAndEndTimes($startDate, $startTime, $endDate, $endTime);

        $this->view->assign('reservation', $reservation);
        $this->view->assign('startDate', $startDate);
        $this->view->assign('startTime', $startTime);
        $this->view->assign('endDate', $endDate);
        $this->view->assign('endTime', $endTime);
        $this->view->assign('canRepeat', $canRepeat);
        $this->view->assign('eventStartDate', $eventStartDate);
        $this->view->assign('eventEndDate', $eventEndDate);
        $this->view->assign('possibleEndTimes', $possibleEndTimes);

        if ($acl && $acl->hasPermission('team')) {
            $this->view->assign('categories', $this->categoryRepository->findAll());
        } else {
            $this->view->assign('categories', $this->categoryRepository->findBy(['public' => 1]));
        }

        $this->view->assign('calendars', $this->calendarRepository->findByNotInUids([$calendar->getUid()]));
        $this->view->assign('defaultStatus', $this->statusRepository->findOneBy(['isDefault' => 1]));
        $this->view->assign('statusses', $statusses);
        $this->view->assign('event', $event);
        $this->view->assign('date', $event->getStartDate());
        $this->view->assign('timeslot', $event->getTimeslot());
        $this->view->assign('calendar', $event->getCalendar());
        $this->view->assign('calendars', $this->calendarRepository->findAll());
        $this->view->assign('categories', $categories);
        $this->view->assign('bookingTypes', $this->bookingTypeRepository->findAll());
        $this->view->assign('reservationTypes', $this->reservationTypeRepository->findAll());
        $this->view->assign('locations', $this->locationRepository->findAll());
        $this->view->assign('purposes', $this->purposeRepository->findAll());
        $this->view->assign(
            'users',
            $this->feUserRepository->findTeammembers($this->settings['usergroupForTeammembers'] ?: 0)
        );
        return $this->htmlResponse();
    }

    /**
     * action create
     *
     * @param array|null $search
     */
    #[\TYPO3\CMS\Extbase\Annotation\Validate(['validator' => DynamicValidator::class, 'param' => 'reservation'])]
    public function createAction(
        Reservation $reservation,
        array $search = []
    ): ResponseInterface {
        $this->reservationRepository->secureAdd($reservation);

        return $this->redirect('show', 'Event', null, [
            'event' => $reservation->getEvent(),
        ]);
    }

    /**
     * action edit
     */
    #[IgnoreValidation([])] // $reservation
    public function editAction(Reservation $reservation): ResponseInterface
    {
        $event = $reservation->getEvent();
        $calendar = $event->getCalendar();
        $categories = $this->categoryRepository->findAll();
        $statusses = $this->statusRepository->findAll();
        $bookingTypes = $this->bookingTypeRepository->findAll();
        if ($this->request->hasArgument('redirect')) {
            $redirect = &$this->request->getArgument('redirect');
        } else {
            $redirect = '';
        }

        $eventStartDate = clone $event->getStartDateTime();
        $eventEndDate = null;
        if ($event->getEndDateTime()) {
            $eventEndDate = clone $event->getEndDateTime();
        }
        $lastStartDateTime = clone $eventStartDate;
        $lastStartDateTime->modify('+1 year');

        $startTimestamp = $eventStartDate->getTimestamp();
        $endTimestamp = $eventEndDate ? $eventEndDate->getTimestamp() : 0;

        $startDate = strftime('%Y-%m-%d', $startTimestamp);
        $startTime = strftime('%H:%M:%S', $startTimestamp);
        $endDate = strftime('%Y-%m-%d', $endTimestamp);
        $endTime = strftime('%H:%M:%S', $endTimestamp);

        /*$dates = [];
        for($d = clone $eventStartDate; $d <= $lastStartDateTime; $d->modify('+1 week')) {
        $dates[] = $d->format('Y-m-d');
        }

        $existingEventCalendarIds = $this->eventRepository->findCalendarIdsInDatesAndStartAndEndTime($dates, $startTime, $endTime);*/

        $canRepeat = true;
        /*if(!empty($existingEventCalendarIds)) {
        $canRepeat = false;
        }*/

        $possibleEndTimes = $calendar->getPossibleStartAndEndTimes($startDate, $startTime, $endDate, $endTime);


        $this->view->assign('startDate', $startDate);
        $this->view->assign('startTime', $startTime);
        $this->view->assign(
            'users',
            $this->feUserRepository->findTeammembers($this->settings['usergroupForTeammembers'] ?: 0)
        );
        $this->view->assign('reservationTypes', $this->reservationTypeRepository->findAll());
        $this->view->assign('locations', $this->locationRepository->findAll());
        $this->view->assign('reservation', $reservation);
        $this->view->assign('statusses', $statusses);
        $this->view->assign('bookingTypes', $bookingTypes);
        $this->view->assign('event', $event);
        $this->view->assign('date', $event->getStartDate());
        $this->view->assign('timeslot', $event->getTimeslot());
        $this->view->assign('calendar', $event->getCalendar());
        $this->view->assign('categories', $categories);
        $this->view->assign('redirect', $redirect);
        $this->view->assign('eventStartDate', $eventStartDate);
        $this->view->assign('eventEndDate', $eventEndDate);
        $this->view->assign('possibleEndTimes', $possibleEndTimes);
        $this->view->assign('purposes', $this->purposeRepository->findAll());

        return $this->htmlResponse();
    }
    /**
     * action update
     */
    #[Validate(['validator' => DynamicValidator::class, 'param' => 'reservation'])]
    public function updateAction(Reservation $reservation): ResponseInterface
    {
        $event = $reservation->getEvent();
        $this->reservationRepository->update($reservation);

        if ($this->request->hasArgument('redirect') && $this->request->getArgument('redirect') == 'callendar') {
            $calendar = $event->getCalendar();
            $startDate = $event->getStartDate()
->format('Y-m-d');
            $search = [
                'date' => $startDate,
            ];
            $this->uriBuilder->reset()
->setTargetPageUid($calendar->getPageUid());
            $uri = $this->uriBuilder->uriFor(
                'show',
                [
                    'search' => $search,
                    'redirect' => $this->request->getArgument('redirect'),
                ],
                'Calendar',
                'IgReservations',
                'PublicCalendar'
            );
            return $this->redirectToUri($uri);
            //$this->redirect('show', 'Calendar', 'PublicCalendar', ['search' => $search, 'redirect' => $this->request->getArgument('redirect')], $calendar->getPageUid());
        }
        return $this->redirect('show', 'Event', null, [
            'event' => $event->getUid(),
            'redirect' => $this->request->getArgument('redirect'),
        ]);
    }

    /**
     * action delete
     *
     * @param array|null $search
     */
    #[\TYPO3\CMS\Extbase\Annotation\IgnoreValidation([])] // $reservation
    public function deleteAction(
        Reservation $reservation,
        array $search = []
    ): ResponseInterface {
        $feUser = $this->userService->getUser();
        $event = $reservation->getEvent();

        $calendar = $event->getCalendar();
        $startDate = $event->getStartDate()
->format('Y-m-d');

        $this->reservationRepository->secureRemove($reservation);

        $event->reset();

        if ($this->settings['removeEventWithNoReservations'] && $event->getReservations()->count() == 0) {
            $this->eventRepository->secureRemove($event);
        }
        if ($this->request->hasArgument('redirect') && $this->request->getArgument('redirect') == 'callendar') {
            $search = [
                'date' => $startDate,
            ];
            $this->uriBuilder->reset()
->setTargetPageUid($calendar->getPageUid());
            $uri = $this->uriBuilder->uriFor(
                'show',
                [
                    'search' => $search,
                    'redirect' => $this->request->getArgument('redirect'),
                ],
                'Calendar',
                'IgReservations',
                'PublicCalendar'
            );
            return $this->redirectToUri($uri);
        //$this->redirect('show', 'Calendar', null, ['search' => $search, 'redirect' => $this->request->getArgument('redirect')], $calendar->getPageUid());
        } elseif ($this->request->hasArgument('redirect')) {
            return $this->redirect('approvalList', 'Event', null, [
                'redirect' => $this->request->getArgument('redirect'),
            ]);
        }
        return $this->redirectToUri(
            $this->uriBuilder->reset()->setTargetPageUid($this->settings['unapprovedListPageUid'])->build()
        );
    }

    /**
     * [cancelRequestAction description]
     * @param Reservation $reservation [description]
     * @return [type]                                              [description]
     */
    public function cancelRequestAction(Reservation $reservation): ResponseInterface
    {
        $user = $this->userService->getUser();
        $event = $reservation->getEvent();

        $calendar = $event->getCalendar();
        $startDate = $event->getStartDate()
->format('Y-m-d');

        if (
            $user
            && $reservation->getFrontendUser()
            && $reservation->getFrontendUser()
->getUid()
            && $reservation->getFrontendUser()
->getUid() == $user->getUid()
            && $event->getStatus()
            && $event->getStatus()
->getUid() != $this->settings['cancelRequestedStatus']
        ) {
            $status = $this->statusRepository->findByUid($this->settings['cancelRequestedStatus']);
            $event->setStatus($status);
            $this->eventRepository->secureUpdate($event);
            $this->mailService->sendMailAfterCancelRequest($calendar, $event, $reservation);
            /*$this->reservationRepository->secureRemove($reservation);

            $event->reset();

            if($event->getReservations()->count() == 0) {
                $this->eventRepository->secureRemove($event);
            }*/
        }

        return $this->redirect('cancelRequestSent', null, null, [
            'reservation' => $reservation->getUid(),
        ]);
    }

    public function cancelRequestSentAction(Reservation $reservation): ResponseInterface
    {
        $this->view->assign('reservation', $reservation);

        return $this->htmlResponse();
    }

    public function approveCancelRequestAction(
        Reservation $reservation
    ): ResponseInterface {
        $event = $reservation->getEvent();
        $calendar = $event->getCalendar();

        if ($this->settings['cancelRequestedStatus'] && $event->getStatus() && $event->getStatus()->getUid() == $this->settings['cancelRequestedStatus']) {
            $this->reservationRepository->secureRemove($reservation);

            $event->reset();

            $statusUid = $this->settings['canceledStatus'] ?: $this->settings['notAvailableStatus'];

            if ($this->settings['removeEventWithNoReservations'] && $event->getReservations()->count() == 0) {
                $this->eventRepository->secureRemove($event);
            } elseif ($statusUid) {
                $status = $this->statusRepository->findByUid($statusUid);
                $event->setStatus($status);
                $this->eventRepository->secureUpdate($event);
            }
            $this->mailService->sendMailAfterApproveCancelRequest($calendar, $event, $reservation);
        }

        return $this->htmlResponse();
    }

    public function unapproveCancelRequestAction(
        Reservation $reservation
    ): ResponseInterface {
        $event = $reservation->getEvent();
        $calendar = $event->getCalendar();

        $statusUid = $this->settings['cancelRejectedStatus'] ?: $this->settings['notAvailableStatus'];

        if ($statusUid && $event->getStatus() && $event->getStatus()->getUid() != $statusUid) {
            $status = $this->statusRepository->findByUid($statusUid);
            $event->setStatus($status);
            $this->eventRepository->secureUpdate($event);
            $this->mailService->sendMailAfterUnapproveCancelRequest($calendar, $event, $reservation);
        }

        return $this->htmlResponse();
    }


    public function listAction(): ResponseInterface
    {
        $user = $this->userService->getUser();
        $reservations = $this->reservationRepository->findBy(['frontendUser' => $user]);
        $this->view->assign('reservations', $reservations);

        return $this->htmlResponse();
    }

    public function newBookingAction(Event $event): ResponseInterface
    {
        $reservations = $event->getReservations();

        if ($reservations->count() == 0) {
            $user = $this->userService->getUser();
            $newReservation = GeneralUtility::makeInstance(Reservation::class);
            $newReservation->setEvent($event);
            $calendar = $event->getCalendar();
            $eventStartDate = $event->getStartDateTime();
            $eventEndDate = $event->getEndDateTime();
            $lastStartDateTime = clone $eventStartDate;
            $lastStartDateTime->modify('+1 year');

            $startTimestamp = $eventStartDate->getTimestamp();
            $endTimestamp = $eventEndDate->getTimestamp();

            $startDate = strftime('%Y-%m-%d', $startTimestamp);
            $startTime = strftime('%H:%M:%S', $startTimestamp);
            $endDate = strftime('%Y-%m-%d', $endTimestamp);
            $endTime = strftime('%H:%M:%S', $endTimestamp);

            $canRepeat = true;
            /*if(!empty($existingEventCalendarIds)) {
            $canRepeat = false;
            }*/

            $possibleEndTimes = $calendar->getPossibleStartAndEndTimes($startDate, $startTime, $endDate, $endTime);

            $this->view->assign('startDate', $startDate);
            $this->view->assign('startTime', $startTime);
            $this->view->assign('endDate', $endDate);
            $this->view->assign('endTime', $endTime);
            $this->view->assign('canRepeat', $canRepeat);

            $date = $eventStartDate->format('Y-m-d');
            $timeslot = null;

            //$this->view->assign('reservation', $reservation);
            if ($calendar->getAcl() && $calendar->getAcl()->hasPermission('team')) {
                $this->view->assign('categories', $this->categoryRepository->findAll());
            } else {
                $this->view->assign('categories', $this->categoryRepository->findBy(['public' => 1]));
            }
            $this->view->assign('statusses', $this->statusRepository->findAll());
            $this->view->assign('defaultStatus', $this->statusRepository->findOneBy(['isDefault' => 1]));
            $this->view->assign('eventStartDate', $eventStartDate);
            $this->view->assign('eventEndDate', $eventEndDate);
            $this->view->assign('possibleEndTimes', $possibleEndTimes);
            $this->view->assign('calendars', $this->calendarRepository->findByNotInUids([$calendar->getUid()]));

            $this->view->assign('reservationTypes', $this->reservationTypeRepository->findAll());
            $this->view->assign('bookingTypes', $this->bookingTypeRepository->findAll());
            $this->view->assign('locations', $this->locationRepository->findAll());
            $this->view->assign('purposes', $this->purposeRepository->findAll());

            $this->view->assign('calendar', $calendar);
            $this->view->assign('event', $event);
            $this->view->assign('newReservation', $newReservation);
            $this->view->assign('user', $user);

            return $this->htmlResponse();
        }
        return $this->redirectToUri(
            $this->uriBuilder->reset()
->uriFor(
    'list',
    [
        'search' => [
            'bookingType' => $event->getBookingType()
->getUid(),
            'location' => $event->getLocation()
            ->getUid(),
        ],
    ],
    'Event',
    'IgReservations',
    'EventList'
)
        );
    }

    public function createBookingAction(Reservation $newReservation): ResponseInterface
    {
        $event = $newReservation->getEvent();
        $calendar = $event->getCalendar();
        $reservations = $event->getReservations();

        if ($reservations->count() == 0) {
            $user = $this->userService->getUser();
            $newReservation->setFrontendUser($user);

            if ($this->settings['notAvailableStatus']) {
                $defaultStatus = $this->statusRepository->findOneBy(['isDefault' => 1]);
                $event->setStatus($defaultStatus);
                $this->eventRepository->secureUpdate($event);
            }
            $this->reservationRepository->secureAdd($newReservation);
            $this->view->assign('event', $event);
            $this->view->assign('reservation', $newReservation);
            $this->mailService->sendMailAfterCreateBookingUser($newReservation);
            $this->mailService->sendMailAfterCreateBookingTeam($newReservation);
            return $this->redirect('thankYouBooking', null, null, [
                'reservation' => $newReservation->getUid(),
            ]);
        }
        return $this->redirect('failedBooking', null, null);
    }

    public function thankYouBookingAction(Reservation $reservation): ResponseInterface
    {
        $this->view->assign('reservation', $reservation);
        return $this->htmlResponse();
    }

    public function failedBookingAction(): ResponseInterface
    {
        return $this->htmlResponse();
    }

    protected function initializeUpdateAction(): void
    {
        if (isset($this->arguments['reservation'])) {
            $reservation = $this->arguments['reservation'];
            foreach (['event.startDate', 'event.endDate'] as $dateField) {
                $reservation->getPropertyMappingConfiguration()
                       ->forProperty($dateField)
                       ->setTypeConverterOption(
                           DateTimeConverter::class,
                           DateTimeConverter::CONFIGURATION_DATE_FORMAT,
                           'Y-m-d'
                       );
            }

            $reservation
                ->getPropertyMappingConfiguration()
                ->forProperty('event.description')
                ->setTypeConverter(
                    GeneralUtility::makeInstance(HtmlConverter::class)
                );
        }
    }

    /**
     * Create a fluid template
     */
    private function createFluidTemplate(string $name): StandaloneView
    {
        $extbaseFrameworkConfiguration = $this->configurationManager->getConfiguration(
            ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK
        );
        $view = GeneralUtility::makeInstance(StandaloneView::class);
        // $view->setControllerContext($this->controllerContext); // TODO: Find Replacement for TYPO3 12
        $view->setLayoutRootPaths($extbaseFrameworkConfiguration['view']['layoutRootPaths']);
        $view->setTemplateRootPaths($extbaseFrameworkConfiguration['view']['templateRootPaths']);
        $view->setPartialRootPaths($extbaseFrameworkConfiguration['view']['partialRootPaths']);
        $view->setTemplate($name);
        return $view;
    }
}
