<?php
namespace Newland\Toubiz\Poi\Neos\ViewHelpers\Filter\Controller;

/*
 * 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 Neos\ContentRepository\Domain\Model\Node;
use Neos\ContentRepository\Domain\Model\NodeInterface;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Mvc\View\ViewInterface;
use Neos\FluidAdaptor\Core\Widget\AbstractWidgetController;
use Neos\FluidAdaptor\View\TemplateView;
use Newland\Toubiz\Poi\Neos\Domain\Repository\TopicRepository;
use Newland\Toubiz\Sync\Neos\Domain\Repository\AttributeRepository;
use TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperVariableContainer;

class FieldSetController extends AbstractWidgetController
{
    /**
     * @var TopicRepository
     * @Flow\Inject()
     */
    protected $topicRepository;

    /**
     * @var AttributeRepository
     * @Flow\Inject()
     */
    protected $attributeRepository;

    /**
     * @var array
     */
    protected $viewHelperVariables = [];

    public function passViewHelperVariables(ViewHelperVariableContainer $container, array $viewHelpers)
    {
        foreach ($viewHelpers as $class) {
            $this->viewHelperVariables[$class] = $container->getAll($class) ?: [];
        }
    }

    /**
     * @param TemplateView $view
     */
    public function initializeView(ViewInterface $view)
    {
        $variableContainer = $view->getRenderingContext()->getViewHelperVariableContainer();

        foreach ($this->viewHelperVariables as $class => $variables) {
            $variableContainer->addAll($class, $variables);
        }
    }

    public function indexAction()
    {
        $this->initialize();

        $type = $this->widgetConfiguration['fieldSet']['type'];

        $this->view->assignMultiple(
            [
                'fieldSet' => $this->widgetConfiguration['fieldSet'],
                'type' => $type,
                'random' => md5((string) mt_rand()),
                'nodeIdentifier' => $this->getNodeIdentifier(),
            ]
        );

        switch ($type) {
            case 'categories':
                $this->handleCategories();
                break;
            case 'checkboxes':
                $this->handleCheckboxes();
                break;
            case 'range':
                $this->handleRange();
                break;
            default:
                break;
        }
    }

    private function initialize(): void
    {
        $node = $this->widgetConfiguration['node'] ?? null;
        if ($node instanceof Node) {
            $dimensions = $node->getDimensions();
            $language = $dimensions['language'][0] ?? null;
            $this->topicRepository->setLanguage($language);
        }
    }

    private function handleCategories(): void
    {
        $fieldSet = $this->widgetConfiguration['fieldSet'];

        $properties = (array) $this->widgetConfiguration['node']->getNodeData()->getProperties();
        $fieldSet['searchable'] = true;
        $topics = $this->topicRepository->findCategoryByMainType(
            $properties['articleType'] ?? $fieldSet['mainType']
        );

        $this->view->assignMultiple(
            [
                'type' => 'checkboxes',
                'items' => $topics,
                'fieldSet' => $fieldSet,
            ]
        );
    }

    private function handleCheckboxes(): void
    {
        $this->view->assignMultiple(
            [
                'items' => $this->topicRepository->findByIdentifiers($this->widgetConfiguration['fieldSet']['items']),
            ]
        );
    }

    private function handleRange(): void
    {
        $steps = $this->widgetConfiguration['fieldSet']['steps'] ?? 1;
        $factor = $this->widgetConfiguration['fieldSet']['factor'] ?? 1;
        $min = $this->widgetConfiguration['fieldSet']['min'] ?? null;
        $max = $this->widgetConfiguration['fieldSet']['max'] ?? null;

        if (!$min || !$max) {
            list(, $name) = explode(':', $this->widgetConfiguration['fieldSet']['item']);
            $roundAutoBounds = $this->widgetConfiguration['fieldSet']['roundAutoBounds'] ?? 100;
            $bounds = $this->attributeRepository->getNumberBoundsForName($name, $roundAutoBounds);
            $min = $min ?? $bounds['min'];
            $max = $max ?? $bounds['max'];
        }

        $this->view->assignMultiple(
            [
                'item' => $this->topicRepository->findByIdentifier($this->widgetConfiguration['fieldSet']['item']),
                'min' => $min,
                'max' => $max,
                'steps' => $steps,
                'factor' => $factor,
            ]
        );
    }

    private function getNodeIdentifier(): string
    {
        /** @var NodeInterface $node */
        $node = $this->widgetConfiguration['node'];

        return $node->getIdentifier();
    }
}
