<?php


namespace AutoAdmin\Bundle\Content\EventListener;


use AutoAdmin\Bundle\Content\Configuration\ConfigManager;
use AutoAdmin\Bundle\Content\Entity\Content;
use AutoAdmin\Bundle\Content\Event\ContentMatchEvent;
use AutoAdmin\Bundle\Content\Repository\DefaultTranslatableContentRepository;
use Doctrine\Persistence\ManagerRegistry;
use Exception;
use Psr\Log\LoggerInterface;
use ReflectionClass;

class ContentMatcherListener
{
    protected ConfigManager $config;
    private ManagerRegistry $doctrine;
    private LoggerInterface $logger;

    public function __construct(ConfigManager $config, ManagerRegistry $doctrine, LoggerInterface $logger)
    {
        $this->config = $config;
        $this->doctrine = $doctrine;
        $this->logger = $logger;
    }

    public function onContentMatch(ContentMatchEvent $event): void
    {
        $contentContext = $event->getContentContext();
        $request = $event->getRequest();

        $route = $request->get('_route');
        if (!$this->isSupportedRoute($route)) {
            return;
        }

        $contentClass = $this->config->getContentClassForRoute($route);
        $slugAndAction = $this->config->getRouteSlugAndAction($route);
        if ($contentClass === null) {
            $this->logger->warning('Could not match $mainContent on url "' . $request->getUri() . '" and route "' . $route . '"');
        } elseif ($slugAndAction) {
            $contentRefl = new ReflectionClass($contentClass);
            if ($contentRefl->isSubclassOf(Content::class)) {
                try {
                    /** @var DefaultTranslatableContentRepository $repository */
                    $repository = $this->doctrine->getRepository($contentClass);
                    if ($route === 'page_index') {
                        $mainContent = $repository->contentFindOneBy(['_.homepage' => true]);
                        if (empty($mainContent)) {
                            throw new Exception('You must define one page as "homepage".');
                        }
                        $contentContext->setMainContent($mainContent);
                    } else {
                        $findParameters = [];
                        $routeConfig = $this->config->getRoute($route);
                        if ($routeConfig && !empty($routeConfig['autofill_parameters'])) {
                            foreach ($routeConfig['autofill_parameters'] as $param => $path) {
                                $prefix = stripos('_tr.', $path) !== false ? '_.' : '_tr.';
                                $findParameters[$prefix . $param] = $request->get($param);
                            }
                            $mainContent = $repository->contentFindOneBy($findParameters);
                            if ($mainContent) {
                                $contentContext->setMainContent($mainContent);
                            }
                        }

                    }
                } catch (Exception $e) {
                    error_log($e->getMessage());
                }
            }
        }
    }

    protected function isSupportedRoute($route): bool
    {
        if ($route === 'page_index') {
            return true;
        }

        $hasRoute = $this->config->hasRoute($route);
        if ($hasRoute
            && ($routeConfig = $this->config->getRoute($route))
            && !empty($routeConfig['autofill_parameters'])
        ) {
            return true;
        }

        return false;
    }
}
