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

/*
 * This file is part of the "toubiz-events-neos" package.
 *
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
 */

use DateTime;
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\Flow\Annotations as Flow;
use Neos\Neos\Domain\Service\ContentContext;
use Newland\Toubiz\Events\Neos\Service\EventUrlService;
use Newland\Toubiz\Sync\Neos\Domain\Model\Event;
use Newland\Toubiz\Sync\Neos\Domain\Model\EventDate;

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

    /**
     * @var EventUrlService
     * @Flow\Inject()
     */
    protected $eventUrlService;

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

    protected function generateUrl(?Event $event, EventDate $date = null, Node $currentNode = null): string
    {
        if ($event === null) {
            return '';
        }

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

        if ($currentNode) {
            return (string) $this->eventUrlService->generateUrlByCurrentNode($event, $currentNode, $date);
        }

        return (string) $this->eventUrlService->generateUrl($event, $this->controllerContext, null, $date);
    }

    protected function isInBackend(): bool
    {
        if (static::$inBackendOverride !== null) {
            return static::$inBackendOverride;
        }
        $request = $this->controllerContext->getRequest();

        if (!($request instanceof ActionRequest)) {
            return false;
        }

        /** @var NodeInterface|null $node */
        $node = $request->getInternalArgument('__node');
        if (!$node) {
            return false;
        }

        $context = $node->getContext();
        if (!($context instanceof ContentContext)) {
            return false;
        }

        return $context->isInBackend();
    }

    protected function getCurrentNodeFromContext(): ?Node
    {
        $mainRequest = $this->controllerContext->getRequest()->getMainRequest();

        if ($mainRequest instanceof ActionRequest === false) {
            return null;
        }
        $nodeName = $mainRequest->getArgument('node');

        $node = (new NodeConverter())->convertFrom($nodeName, '');

        if ($node instanceof Node === false) {
            return null;
        }

        return $node;
    }

    /** @var bool|null */
    protected static $inBackendOverride = null;
    public static function pretendToBeInBackendForTest(?bool $inBackend): void
    {
        static::$inBackendOverride = $inBackend;
    }
}
