<?php declare(strict_types=1);

namespace Newland\ToubizWidgetRendering\Controller;

use Neos\Flow\Mvc\Controller\ActionController;
use Newland\NeosCommon\Utility\UrlUtility;
use Newland\ToubizWidgetRendering\Exception\InvalidParameterException;
use Neos\Flow\Annotations as Flow;
use Newland\ToubizWidgetRendering\Service\WidgetPageService;
use Ramsey\Uuid\Uuid;

class RedirectController extends ActionController
{
    /**
     * @var array
     * @Flow\InjectConfiguration(path="redirect")
     */
    protected $configuration;

    /**
     * @var WidgetPageService
     * @Flow\Inject()
     */
    protected $widgetPageService;

    /**
     * @var UrlUtility
     * @Flow\Inject()
     */
    protected $urlUtility;

    public function widgetDetailAction(string $type, string $language, string $uuid): void
    {
        $this->validateUuid($uuid);

        $widgetPageNode = $this->widgetPageService->getWidgetPageNode($language);
        $basePath = $this->uriBuilder
            ->reset()
            ->setCreateAbsoluteUri(true)
            ->uriFor('show', [ 'node' => $widgetPageNode ], 'Frontend\Node', 'Neos.Neos');

        $basePath = $this->urlUtility->appendTrackingParameters(
            $basePath,
            $this->request->getMainRequest()->getArguments()
        );

        $this->redirectToUri(
            sprintf('%s#/%s/%s', $basePath, $this->getType($type), $uuid),
            0,
            301
        );
    }

    public function widgetListAction(string $type, string $language): void
    {
        $widgetPageNode = $this->widgetPageService->getWidgetPageNode($language);
        $basePath = $this->uriBuilder
            ->reset()
            ->setCreateAbsoluteUri(true)
            ->uriFor('show', [ 'node' => $widgetPageNode ], 'Frontend\Node', 'Neos.Neos');

        $encodedParams = $this->request->getMainRequest()->getArgument('params');

        $this->redirectToUri(
            sprintf('%s#/%s?params=%s', $basePath, $this->getType($type), $encodedParams),
            0,
            301
        );
    }

    private function getType(string $parameter): string
    {
        $type = $this->configuration['types'][$parameter] ?? null;

        if ($type === null) {
            throw new InvalidParameterException(sprintf('No type mapping configured for parameter "%s"', $parameter));
        }

        return $type;
    }

    private function validateUuid(string $uuid): void
    {
        if (Uuid::isValid($uuid) === false) {
            throw new InvalidParameterException(sprintf('"%s" is not a valid uuid.', $uuid));
        }
    }
}
