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

/*
 * 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 Neos\ContentRepository\Domain\Model\NodeInterface;
use Neos\Flow\ObjectManagement\Exception\InvalidObjectException;
use Neos\Flow\Persistence\Generic\Query as NeosQuery;
use Newland\NeosFiltering\Factory\DefaultFilterFactory;
use Newland\Toubiz\Poi\Neos\Filter\Items\ArticleRoot;
use Neos\Flow\Annotations as Flow;
use Newland\Toubiz\Poi\Neos\Filter\Items\AttributeCheckboxList;
use Newland\Toubiz\Poi\Neos\Filter\Items\AttributeRange;
use Newland\Toubiz\Poi\Neos\Filter\Items\PreselectedTags;

class ArticleFilterFactory extends DefaultFilterFactory
{
    protected const SORTING_ALPHABETIC = 'alphabetic';
    protected const SORTING_RANDOM = 'random';

    /**
     * @var array
     * @Flow\InjectConfiguration(path="filter")
     */
    protected $filterSettings;

    public function __construct(NodeInterface $node)
    {
        parent::__construct($node);
        $this->predefinedTypes['attribute_range'] = AttributeRange::class;
        $this->predefinedTypes['attribute_checkbox_list'] = AttributeCheckboxList::class;
        $this->predefinedTypes['preselected_tags'] = PreselectedTags::class;
    }

    protected function getRootClassName(): string
    {
        return ArticleRoot::class;
    }

    public function createFilterForArticleType(
        int $articleType,
        array $overrides,
        string $context = 'frontend'
    ): ArticleRoot {
        $configuration = $this->filterSettings['articleType'][$articleType] ?? null;
        if ($configuration === null) {
            $filter = new ArticleRoot([], $this->node);
            $filter->setArticleType($articleType);
            return $filter;
        }

        $filter = $this->createFilter($configuration, $overrides, $context);
        if (!($filter instanceof ArticleRoot)) {
            throw new InvalidObjectException('Object is expected to be ArticleRoot');
        }

        $filter->setArticleType($articleType);

        switch ($overrides['sorting'] ?? static::SORTING_ALPHABETIC) {
            case static::SORTING_ALPHABETIC:
                $filter->setOrder([ 'order' => NeosQuery::ORDER_ASCENDING, 'orderBy' => 'entity.processedName' ]);
                break;
            case static::SORTING_RANDOM:
                $filter->setOrder([ 'order' => NeosQuery::ORDER_ASCENDING, 'orderBy' => 'entity.randomSorting' ]);
                break;
        }

        return $filter;
    }
}
