<?php
namespace Newland\Toubiz\Poi\Neos\ViewHelpers\Link;

/*
 * 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\Node;
use Neos\ContentRepository\Domain\Model\NodeInterface;
use Neos\ContentRepository\TypeConverter\NodeConverter;
use Neos\Flow\Mvc\ActionRequest;
use Neos\FluidAdaptor\Core\ViewHelper\AbstractTagBasedViewHelper;
use Neos\Neos\Domain\Service\ContentContext;
use Newland\Toubiz\Poi\Neos\Service\ArticleUrlService;
use Newland\Toubiz\Sync\Neos\Domain\Model\Article;
use Neos\Flow\Annotations as Flow;

class ArticleViewHelper extends AbstractTagBasedViewHelper
{
    /**
     * @var string
     */
    protected $tagName = 'a';

    /**
     * @var ArticleUrlService
     * @Flow\Inject()
     */
    protected $articleUrlService;

    public function initializeArguments(): void
    {
        $this->registerUniversalTagAttributes();
        $this->registerTagAttribute('target', 'string', 'Link target (e.g. _blank)');
    }

    public function render(Article $article = null, Node $currentNode = null): string
    {
        if (!$article) {
            return $this->isInBackend() ? 'Error: No article specified.' : '';
        }

        if ($currentNode === null) {
            $currentNode = $this->getCurrentNodeFromContext();
        }

        $url = '';
        if ($currentNode !== null) {
            $url = (string) $this->articleUrlService->generateUrlByCurrentNode($article, $currentNode);
        }

        $this->tag->addAttribute('href', $url);
        $this->tag->setContent($this->renderChildren());
        return $this->tag->render();
    }

    private function isInBackend(): bool
    {
        $request = $this->controllerContext->getRequest();
        if (!($request instanceof ActionRequest)) {
            return false;
        }

        /** @var NodeInterface|null $node */
        $node = $request->getInternalArgument('__node');
        $context = null;
        if ($node instanceof Node) {
            $context = $node->getContext();
        }

        if (!($context instanceof ContentContext)) {
            return false;
        }

        return $context->isInBackend();
    }

    private function getCurrentNodeFromContext(): ?Node
    {
        $mainRequest = $this->controllerContext->getRequest()->getMainRequest();
        if (!($mainRequest instanceof ActionRequest)) {
            return null;
        }

        if (!$mainRequest->hasArgument('node')) {
            return null;
        }

        $node = (new NodeConverter())->convertFrom($mainRequest->getArgument('node'), '');
        if (!($node instanceof Node)) {
            return null;
        }

        return $node;
    }
}
