<?php
namespace Newland\Toubiz\Events\Neos\Filter\Items;

/*
 * This file is part of the "toubiz-evets-neos" package.
 *
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
 */

use Doctrine\ORM\Query\Expr;
use Newland\Contracts\Neos\Filter\Expression;
use Newland\Contracts\Neos\Filter\FilterItem;
use Newland\Contracts\Neos\Filter\QueryBoundFilterItem;
use Newland\NeosFiltering\Traits\FilterItemCommon;
use Newland\NeosFiltering\Traits\HasCombinationSettings;
use Newland\NeosFiltering\Traits\HasInvisibleState;
use Newland\NeosFiltering\Traits\HasQueryString;
use Newland\NeosFiltering\Traits\NeedsDatabaseColumn;
use Newland\Toubiz\Poi\Neos\Filter\Items\AttributeCommon;
use Newland\Toubiz\Sync\Neos\Domain\Model\EventDate;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;

class EventHighlight implements FilterItem, QueryBoundFilterItem
{
    use FilterItemCommon,
        AttributeCommon,
        NeedsDatabaseColumn,
        HasCombinationSettings,
        HasQueryString,
        HasInvisibleState;

    /**
     * Returns a database expression that mirrors the item state.
     * This expression is applied to a database query in order to get the filtered results.
     *
     * Note: The entity that is being filtered for is always aliased as `entity`.
     *
     * @param Expr $expr
     * @return Expression An expression built by the given expression builder.
     */
    public function queryExpression(Expr $expr): Expression
    {
        if (empty($this->state)) {
            return Expression::empty();
        }

        // Subquery always selects the first event date of an event that is in the future.
        $subQuery = $this->entityManager
            ->createQueryBuilder()
            ->from(EventDate::class, 'ed')
            ->select('ed.Persistence_Object_Identifier')
            ->where('IDENTITY(ed.event) = event.Persistence_Object_Identifier')
            ->andWhere(
                $expr->orX(
                    $expr->gte('ed.beginsAt', $expr->literal(date('Y-m-d'))),
                    $expr->isNull('ed.beginsAt')
                )
            )
            ->orderBy('ed.beginsAt')
            ->getDQL();

        return Expression::where(
            $expr->andX(
                $expr->eq($this->databaseColumn, $this->state),
                $expr->eq('entity.Persistence_Object_Identifier', sprintf('FIRST(%s)', $subQuery))
            )
        );
    }

    public function render(RenderingContextInterface $renderingContext)
    {
        $view = $this->initializeView(
            [ 'resource://Newland.Toubiz.Events.Neos/Private/Templates/Filter/Items' ],
            [],
            [ 'resource://Newland.Toubiz.Events.Neos/Private/Partials/Filter/Items' ]
        );

        $view->assignMultiple(
            [
                'stateValues' => $this->state,
            ]
        );

        return $view->render('IsHighlight');
    }
}
