<?php
namespace Newland\Toubiz\Sync\Neos\Domain\Repository;

/*
 * This file is part of the "toubiz-sync-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\QueryBuilder;
use Neos\Flow\Annotations as Flow;
use Newland\Toubiz\Sync\Neos\Command\OrphanFinder;
use Newland\Toubiz\Sync\Neos\Domain\Filter\CategoryFilter;
use Newland\Toubiz\Sync\Neos\Domain\Filter\FilterInterface;
use Newland\Toubiz\Sync\Neos\Domain\Model\Category;
use Newland\Toubiz\Sync\Neos\Translation\TranslatableRepository;

/**
 * Category repository.
 *
 * @Flow\Scope("singleton")
 *
 * @method Category|null findOneByOriginalId(string $originalId)
 * @method Category|null findByIdentifier(string $identifier)
 */
class CategoryRepository extends AbstractRepository implements OrphanFinder
{

    use TranslatableRepository;

    /** @var string */
    protected $alias = 'category';

    public function orphanQuery(): QueryBuilder
    {
        $query = $this->createQueryBuilder('category');

        $query->leftJoin('category.events', 'events');
        $query->leftJoin('category.articles', 'articles');

        $query->andWhere($query->expr()->andX(
            $query->expr()->isNull('events.Persistence_Object_Identifier'),
            $query->expr()->isNull('articles.Persistence_Object_Identifier')
        ));

        return $query;
    }

    /**
     * @param CategoryFilter $filter
     * @param QueryBuilder $query
     * @return QueryBuilder
     */
    protected function applyFilter(FilterInterface $filter, QueryBuilder $query): QueryBuilder
    {
        $this->applyBasicFilter($filter, $query);
        $fromDate = $filter->getFromDate();
        $toDate = $filter->getToDate();

        $mainType = $filter->getArticleMainType();
        if ($mainType !== null) {
            $query->innerJoin('category.articles', 'article');
            $query->andWhere(
                $query->expr()->eq('article.mainType', $mainType)
            );
        }

        if ($fromDate || $toDate) {
            $query->innerJoin('category.events', 'event');
            $query->innerJoin('event.eventDates', 'eventDate');
        }

        if ($fromDate) {
            $query->andWhere('(DATE(eventDate.beginsAt) >= :fromDate OR eventDate.beginsAt IS NULL)')
                ->setParameter('fromDate', $fromDate->format('Y-m-d'));
        }

        if ($toDate) {
            $query->andWhere('(DATE(eventDate.endsAt) <= :toDate OR eventDate.endsAt IS NULL)')
                ->setParameter('toDate', $toDate->format('Y-m-d'));
        }

        return $query;
    }
}
