<?php declare(strict_types=1);

namespace App\Engine\UpcomingEvent;

final readonly class VisibleRecordsFilters
{

    public const CURRENT_DATE_TIME_PARAMETER_NAME = 'dateTime';
    private const _CURRENT_DATE_TIME_PARAMETER_NAME = ":" . self::CURRENT_DATE_TIME_PARAMETER_NAME;

    public function __construct(
        private \Doctrine\ORM\Query\Expr $expr,
        private string                   $alias,
    ) {
    }

    public static function create(\Doctrine\ORM\Query\Expr $expr, string $alias): VisibleRecordsFilters
    {
        return new self($expr, $alias);
    }

    public function visibleForHomepage(): \Stringable
    {
        return $this->expr->andX(
            $this->visibleForFrontend(),
            $this->visibleAccordingToPublishFrom(),
            $this->visibleAccordingToPublishTo(),
            $this->expr->eq("$this->alias.showOnHp", true),
        );
    }

    private function visibleForFrontend(): \Stringable
    {
        return $this->expr->eq("$this->alias.enabled", true);
    }

    private function visibleAccordingToPublishFrom(): \Stringable
    {
        return $this->expr->orX(
            $this->expr->isNull("$this->alias.publishFrom"),
            $this->expr->lte("$this->alias.publishFrom", self::_CURRENT_DATE_TIME_PARAMETER_NAME),
        );
    }

    private function visibleAccordingToPublishTo(): \Stringable
    {
        return $this->expr->orX(
            $this->expr->isNull("$this->alias.publishTo"),
            $this->expr->gte("$this->alias.publishTo", self::_CURRENT_DATE_TIME_PARAMETER_NAME),
        );
    }

    public function visibleForList(): \Stringable
    {
        return $this->expr->andX(
            $this->visibleForFrontend(),
            $this->visibleAccordingToPublishFrom(),
            $this->visibleAccordingToPublishTo(),
        );
    }

    public function visibleForArchive(): \Stringable
    {
        return $this->expr->andX(
            $this->visibleForFrontend(),
            $this->visibleAccordingToPublishFrom(),
            $this->expr->lt("$this->alias.publishTo", self::_CURRENT_DATE_TIME_PARAMETER_NAME), // Musí být nastaveno a menší než aktuální čas.
            $this->visibleAccordingToArchiveTo(),
        );
    }

    public function visibleForTrainingList(): \Stringable
    {
        return $this->expr->andX(
            $this->visibleForFrontend(),
            $this->visibleAccordingToPublishFrom(),
            $this->visibleAccordingToPublishTo(),
            $this->expr->eq("$this->alias.type", $this->expr->literal(\App\Engine\UpcomingEvent\UpcomingEventType::Training->value)),
        );
    }

    private function visibleAccordingToArchiveTo(): \Stringable
    {
        return $this->expr->orX(
            $this->expr->isNull("$this->alias.archiveTo"),
            $this->expr->gte("$this->alias.archiveTo", self::_CURRENT_DATE_TIME_PARAMETER_NAME),
        );
    }

}