<?php
namespace Newland\PageFrameProvider\Definition;

use Neos\Flow\Configuration\ConfigurationManager;
use Neos\Flow\Annotations as Flow;
use Newland\PageFrameProvider\Service\PageFrameContextService;

class RoutingConfigurationHelper
{

    /**
     * @var ConfigurationManager
     * @Flow\Inject()
     */
    protected $configurationManager;

    /**
     * @var RouteDefinition[]
     */
    protected $definitions;

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

    /**
     * @var array
     */
    protected $typeConfiguration = [];

    public function setTypeConfiguration(array $typeConfiguration)
    {
        $this->typeConfiguration = $typeConfiguration;
    }

    /**
     * @return RouteDefinition[]
     */
    public function getAllDefinitions(): array
    {
        return $this->ensureDefinitionsExist();
    }

    public function getDefinition(?string $type = null): ?RouteDefinition
    {
        $this->ensureDefinitionsExist();
        return $this->definitions[$type] ?? null;
    }

    public function urlFragmentForType(?string $type = null): ?string
    {
        $definition = $this->getDefinition($type) ?? $this->getDefinition('_fallback');

        if (!$definition) {
            return null;
        }

        $url = $definition->getUriSegment($this->language());
        if (!$url) {
            return null;
        }

        return trim($url, '/');
    }

    public function removeUriSegmentsFromRoutePath(string $routePath): string
    {
        $language = $this->language();
        $matchGroup = implode(
            '|',
            array_map(
                function (RouteDefinition $definition) use ($language) {
                    return preg_quote($definition->getUriSegment($language), '/');
                },
                array_values($this->getAllDefinitions())
            )
        );

        $regex = sprintf('/^\/?(%s)/', $matchGroup);
        return (string) preg_replace($regex, '', $routePath);
    }

    /**
     * @return RouteDefinition[]
     */
    private function ensureDefinitionsExist(): array
    {
        if (!$this->definitions) {
            $this->definitions = array_map(
                function ($element) {
                    return new RouteDefinition($element);
                },
                $this->typeConfiguration
            );
        }

        return $this->definitions;
    }


    /**
     * @return string|null
     */
    private function language()
    {
        return $this->pageFrameContext->getDimensions()['language'][0] ?? null;
    }
}
