<?php
namespace Newland\Toubiz\Poi\Neos\ViewHelpers\Uri\OutdoorActive;

use Neos\ContentRepository\Domain\Model\NodeInterface;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Mvc\ActionRequest;
use Neos\FluidAdaptor\Core\ViewHelper\AbstractViewHelper;
use Neos\FluidAdaptor\View\StandaloneView;
use Newland\Toubiz\Poi\Neos\Service\OutdoorActiveCredentialsService;
use Newland\Toubiz\Sync\Neos\Domain\Model\Article;

abstract class AbstractOutdoorActiveUriViewHelper extends AbstractViewHelper
{
    /**
     * Must return a URL template that may contain one of the following placeholders:
     * - `{article}`: The complete article Object
     * - `{outdoorActive.client}`: Outdoor active project
     * - `{outdoorActive.apiKey}`: Outdoor active api Key
     * @return string
     */
    abstract protected function url(): string;

    /**
     * @var OutdoorActiveCredentialsService
     * @Flow\Inject()
     */
    protected $outdoorActiveCredentialsService;

    public function render(Article $article, NodeInterface $referenceNode = null): string
    {
        $referenceNode = $this->resolveReferenceNode($referenceNode);
        if ($referenceNode === null) {
            throw new \InvalidArgumentException('Could not resolve reference node');
        }

        $credentials = $this->outdoorActiveCredentialsService->getOutdoorActiveConfiguration($referenceNode);
        if ($credentials === null) {
            return '#';
        }

        /** @var StandaloneView $view */
        $view = $this->objectManager->get(StandaloneView::class);
        $view->setTemplateSource($this->url());
        $view->assignMultiple(
            [
                'article' => $article,
                'outdoorActive' => $credentials,
            ]
        );

        return $view->render();
    }

    private function resolveReferenceNode(?NodeInterface $node): ?NodeInterface
    {
        if ($node !== null) {
            return $node;
        }

        $request = $this->controllerContext->getRequest();
        if (!($request instanceof ActionRequest)) {
            return null;
        }

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

        return null;
    }
}
