<?php declare(strict_types=1);

namespace Newland\Toubiz\Events\Neos\PageFrame;

use Newland\NeosCommon\Service\NodeService;
use Newland\PageFrameProvider\Dimensions\AlternativeDimensionProvider;
use Newland\PageFrameProvider\Service\PageFrameContextService;
use Newland\Toubiz\Events\Neos\Service\EventUrlService;
use Newland\Toubiz\Sync\Neos\Domain\Model\Event;
use Newland\Toubiz\Sync\Neos\Domain\Repository\EventRepository;
use Neos\Flow\Annotations as Flow;

class EventDimensionProvider implements AlternativeDimensionProvider
{

    /**
     * @var EventRepository
     * @Flow\Inject()
     */
    protected $eventRepository;

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

    /**
     * @var PageFrameContextService
     * @Flow\Inject()
     */
    protected $pageFrameContext;

    /**
     * @var NodeService
     * @Flow\Inject()
     */
    protected $nodeService;

    public function getAlternativeDimensions(string $dimensionName): array
    {
        $event = $this->getEvent();
        if ($dimensionName !== 'language' || !$event) {
            return [];
        }

        $variants = $this->eventRepository->findLanguageVariants($event);
        return array_filter(array_map([ $this, 'eventUrl' ], $variants));
    }


    private function eventUrl(Event $event): ?string
    {
        $node = $this->nodeService->nodeInLanguage($this->pageFrameContext->getNode(), $event->getLanguage());
        if (!$node) {
            return null;
        }
        return $this->eventUrlService->generateUrlByCurrentNode($event, $node, null, true);
    }

    public function getEvent(): ?Event
    {
        $articleUid = $this->pageFrameContext->getPluginArguments()['event'] ?? null;
        $articleUid = $this->resolveFlowEntityEncoding($articleUid);
        if (!$articleUid) {
            return null;
        }

        return $this->eventRepository->findOneBy([ 'Persistence_Object_Identifier' => $articleUid ]);
    }

    /**
     * Flow entity encoding (if passing models as arguments) uses an array with the `__identity` key for the uuid.
     * @see EntityToIdentityConverter
     *
     * @param string|array|null $articleUid
     * @return string|null
     */
    private function resolveFlowEntityEncoding($articleUid): ?string
    {
        if (\is_string($articleUid) || $articleUid === null) {
            return $articleUid;
        }

        if (\is_array($articleUid) && array_key_exists('__identity', $articleUid)) {
            return $articleUid['__identity'];
        }

        return null;
    }
}
