<?php


namespace AutoAdmin\Bundle\Content\ContentReference;


use AutoAdmin\Bundle\Content\Configuration\ConfigManager;
use AutoAdmin\Bundle\Content\Entity\ContentReference;
use AutoAdmin\Bundle\Content\Repository\AbstractTranslatableContentRepository;
use AutoAdmin\Bundle\Content\Routing\ContentRouter;
use Doctrine\Persistence\ManagerRegistry;
use RuntimeException;
use Symfony\Component\HttpFoundation\RequestStack;

class ContentReferenceResolver
{
    private ConfigManager $configManager;
    private ManagerRegistry $doctrine;
    private ContentRouter $contentRouter;
    private RequestStack $requestStack;

    public function __construct(
        ConfigManager   $configManager,
        ManagerRegistry $doctrine,
        ContentRouter   $contentRouter,
        RequestStack    $requestStack
    )
    {
        $this->configManager = $configManager;
        $this->doctrine = $doctrine;
        $this->contentRouter = $contentRouter;
        $this->requestStack = $requestStack;
    }

    public function resolveRouteConfig(ContentReference $contentReference, $throwIfNotFound = false): ?string
    {
        $content = $this->resolve($contentReference, $throwIfNotFound);

        return $this->contentRouter->generate($content, $contentReference->getReferencedAction());
    }

    public function resolve(?ContentReference $contentReference, $throwIfNotFound = false)
    {
        if (is_null($contentReference)) {
            if ($throwIfNotFound) {
                throw new RuntimeException('Could not resolve content reference, null given');
            } else {
                return null;
            }
        }

        $classConfig = $this->configManager->getContentConfig($contentReference->getReferencedSlug());
        $contentClass = $classConfig['class'];
        $repository = $this->doctrine->getRepository($contentClass);

        if (!empty($classConfig['translation_class'])) {
            /** @var AbstractTranslatableContentRepository $repository */
            $content = $repository->findOneByIdAndLocale(
                $contentReference->getReferencedIdentifier(),
                $this->requestStack->getCurrentRequest()->getLocale()
            );
        } else {
            $content = $repository->find($contentReference->getReferencedIdentifier());
        }

        if (empty($content)) {
            if ($throwIfNotFound) {
                throw new RuntimeException('Could not resolve content reference #' . $contentReference->getId());
            } else {
                return null;
            }
        }

        return $content;
    }

    public function resolvePath(ContentReference $contentReference, $throwIfNotFound = false): ?string
    {
        $content = $this->resolve($contentReference, $throwIfNotFound);

        return $this->contentRouter->generate($content, $contentReference->getReferencedAction());
    }
}
