<?php

namespace Ig\IgReservations\Domain\Repository;

use TYPO3\CMS\Extbase\Persistence\Repository;
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
use PDO;
use DateTime;
use Doctrine\DBAL\ParameterType;
use Ig\IgReservations\Domain\Model\Location;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper;

/***
 *
 * This file is part of the "Reservation Tool" Extension for TYPO3 CMS.
 *
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
 *
 *  (c) 2020 Simon Häsler <sh@internetgalerie.ch>, Internetgalerie AG
 *
 ***/
/**
 * The repository for Statuses
 */
class LocationRepository extends Repository
{
    /**
     * DataMapper
     *
     * @var DataMapper
     */
    protected $dataMapper = null;

    /**
     * @var array
     */
    protected $defaultOrderings = [
        'name' => QueryInterface::ORDER_ASCENDING,
    ];

    
    public function injectDataMapper(DataMapper $dataMapper): void
    {
        $this->dataMapper = $dataMapper;
    }

    /**
     * Find locations based on booking type and return only locations with events
     * @param  integer $bookingTypeUid
     * @return array
     */
    public function findByBookingType($bookingTypeUid = 0)
    {
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
            'tx_igreservations_domain_model_location'
        );
        $queryBuilder
            ->select('l.*')
            ->from('tx_igreservations_domain_model_location', 'l')
            ->leftJoin('l', 'tx_igreservations_domain_model_event', 'e', 'e.location = l.uid');

        if ($bookingTypeUid) {
            $queryBuilder->andWhere(
                $queryBuilder->expr()
->eq('e.booking_type', $queryBuilder->createNamedParameter($bookingTypeUid, ParameterType::INTEGER))
            );
        }

        $now = new DateTime();

        // Only get locations that have an active event bound to them
        $queryBuilder->andWhere(
            $queryBuilder->expr()->or($queryBuilder->expr()->and($queryBuilder->expr()
        ->eq('e.start_date', $queryBuilder->createNamedParameter($now->format('Y-m-d'))), $queryBuilder->expr()
        ->gte('e.start_time', $queryBuilder->createNamedParameter($now->format('H:i:s')))), $queryBuilder->expr()
        ->gt('e.start_date', $queryBuilder->createNamedParameter($now->format('Y-m-d'))))
        );

        $queryBuilder->andWhere(
            'e.uid NOT IN (SELECT event FROM tx_igreservations_domain_model_reservation AS r WHERE hidden = 0)'
        );
        $queryBuilder->andWhere('l.name <> \'\' AND l.name IS NOT NULL');

        $queryBuilder->orderBy('l.name');
        $queryBuilder->groupBy('l.uid');

        $res = $queryBuilder->executeQuery()
->fetchAllAssociative();

        $locations = [];
        if (!empty($res)) {
            $locations = $this->dataMapper->map(Location::class, $res);
        }

        return $locations;
    }
}
