<?php
declare(strict_types=1);

namespace App\Filter\DoctrineFilter;

use App\Attribute\DateTimeConstraintAware;
use App\Service\Constraint\DateTimeConstraint;
use App\Service\Utils\StringsUtils;
use Doctrine\ORM\Mapping\ClassMetadata;

/**
 * Classe DateTimeFilter qui définie la requête SQL devant être ajoutée aux Entités possédant l'annotation DateTimeConstraintAware
 */
final class DateTimeFilter extends AbstractTimeFilter
{
    private DateTimeConstraint $dateTimeConstraint;

    /**
     * Méthode surchargée de SQLFilter
     * @param ClassMetadata $targetEntity
     * @param string $targetTableAlias
     * @return string
     * @throws \Exception
     */
    public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias): string
    {
        if(!$this->hasParameter('_time_constraint')
            || !boolval(StringsUtils::unquote($this->getParameter('_time_constraint')))
            || !$this->hasParameter('accessId')
        )
            return '';

        $dateTimeConstraintAware = $targetEntity->getReflectionClass()->getAttributes(DateTimeConstraintAware::class)[0] ?? null;
        $startFieldName = $dateTimeConstraintAware?->getArguments()['startDateFieldName'] ?? null;
        $endFieldName = $dateTimeConstraintAware?->getArguments()['endDateFieldName'] ?? null;
        if ($startFieldName === '' || is_null($startFieldName) || $endFieldName === '' || is_null($endFieldName)) {
            return '';
        }

        $accessId = intval(StringsUtils::unquote($this->getParameter('accessId')));
        $constraints = $this->dateTimeConstraint->invoke($accessId);

        $fields = [
            DateTimeConstraint::START_KEY => $startFieldName,
            DateTimeConstraint::END_KEY => $endFieldName
        ];
      
        return $this->constructQuery($constraints, $targetTableAlias, $fields);
    }

    /**
     * Permets d'assurer l'injection de dépendance du service DateTimeConstraint
     * @param DateTimeConstraint $dateTimeConstraint
     */
    public function setDateTimeConstraint(DateTimeConstraint $dateTimeConstraint): void{
        $this->dateTimeConstraint = $dateTimeConstraint;
    }
}