<?php declare(strict_types=1);
namespace Newland\Toubiz\Poi\Neos\Filter\Items;

/*
 * This file is part of the "toubiz-poi-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\Mvc\ActionRequest;
use Neos\Neos\Domain\Model\Site;
use Neos\Neos\Domain\Service\ContentContext;
use Newland\NeosFiltering\Items\Root;
use Newland\Toubiz\Poi\Neos\Filter\ArticleClientFilterService;
use Newland\Toubiz\Sync\Neos\Domain\Repository\ArticleRepository;
use Neos\Flow\Annotations as Flow;

class ArticleRoot extends Root
{

    /**
     * @var ArticleRepository
     * @Flow\Inject()
     */
    protected $articleRepository;

    /**
     * @var ArticleClientFilterService
     * @Flow\Inject()
     */
    protected $clientFilterService;

    /**
     * @var int
     */
    protected $articleType;

    public function setArticleType(int $articleType): void
    {
        $this->articleType = $articleType;
    }

    public function initializeForFilteredLists(ActionRequest $request): self
    {
        if ($this->pluginNode !== null) {
            $this->addFormAttributesForAjax(sprintf(
                '/toubiz-poi/filtered-list?node=%s&format=ajax',
                $this->pluginNode->getContextPath()
            ));
        }
        $this->fillStateFromRootRequestArguments($request)
            ->setAction(
                [
                    '@action' => 'show',
                    '@controller' => 'FilteredLists',
                    '@package' => 'Newland.Toubiz.Poi.Neos',
                ],
                $request
            );

        return $this;
    }

    public function getArticleQuery(array $additionalWhere = []): QueryBuilder
    {
        $query = $this->articleRepository->createQueryBuilder('entity');
        $query = $this->applyBaseConditions($query, $additionalWhere);
        return $this->applyToQuery($query);
    }

    public function countArticles(array $additionalWhere = []): int
    {
        $query = $this->articleRepository->createQueryBuilder('entity');
        $query = $this->applyBaseConditions($query, $additionalWhere);
        return $this->getResultCount($query);
    }

    private function applyBaseConditions(QueryBuilder $query, array $additionalWhere = []): QueryBuilder
    {
        if ($this->articleType !== null) {
            $query->andWhere(sprintf('entity.mainType = %d', $this->articleType));
            $site = $this->getSite();
            if ($site !== null) {
                $this->clientFilterService->addClientWhereClause($query, $this->articleType, $site, 'entity');
            }
        }
        foreach ($additionalWhere as $where) {
            $query->andWhere($where);
        }
        return $query;
    }

    private function getSite(): ?Site
    {
        if ($this->pluginNode === null) {
            return null;
        }

        $context = $this->pluginNode->getContext();
        if (!($context instanceof ContentContext)) {
            return null;
        }

        return $context->getCurrentSite();
    }
}
