<?php


namespace AutoAdmin\Bundle\Content\Breadcrumbs\EventListener;


use AutoAdmin\Bundle\Content\Breadcrumbs\BreadcrumbsService;
use AutoAdmin\Bundle\Content\Breadcrumbs\Manager\BreadcrumbsGeneratorManagerInterface;
use AutoAdmin\Bundle\Content\Breadcrumbs\Model\BreadcrumbsConfigInterface;
use AutoAdmin\Bundle\Content\Breadcrumbs\Model\BreadcrumbsItem;
use AutoAdmin\Bundle\Content\Entity\Page;
use AutoAdmin\Bundle\Content\Event\PostContentMetadataEvent;
use AutoAdmin\Bundle\Content\Routing\ContentRouter;
use AutoAdmin\Bundle\Content\Site\SiteContextHelper;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class BreadcrumbsDataSubscriber implements EventSubscriberInterface
{
    public function __construct(
        private readonly BreadcrumbsService $breadcrumbsService,
        private readonly ContentRouter $contentRouter,
        protected BreadcrumbsGeneratorManagerInterface $breadcrumbsGeneratorManager,
        protected readonly SiteContextHelper $contextHelper
    ) {
    }

    public static function getSubscribedEvents(): array
    {
        return [
            // build early to be able to reuse breadcrumbs for metadata, etc.
            PostContentMetadataEvent::class => ['postContentMetadataEvent',  50],
        ];
    }

    public function postContentMetadataEvent(PostContentMetadataEvent $postContentMetadataEvent): void
    {
        $mainContent = $postContentMetadataEvent->getContentContext()->getMainContent();
        if (empty($mainContent)) {
            return;
        }

        if ($mainContent instanceof BreadcrumbsConfigInterface && $mainContent->isHiddenBreadcrumbs() === true) {
            // we may want to keep the breadcrumbs metadata ? => no, if hidden, no breadcrumbs in meta (PK/MF)
            return;
        }

        $fragments = $this->breadcrumbsGeneratorManager->generate($mainContent, true);

        // ensure type of all fragments
        foreach ($fragments as $fragment) {
            if (!$fragment instanceof BreadcrumbsItem) {
                $pattern = 'Breadcrumbs fragments must be of type "%s", "%s" type encountered (for main content: %s)';
                throw new \LogicException(
                    sprintf($pattern, BreadcrumbsItem::class, gettype($fragment), get_class($mainContent))
                );
            }
        }

        $items = [];
        /** @var BreadcrumbsItem $fragment */
        foreach ($fragments as $fragment) {
            if ($s = $fragment->getSubject()) {
                if ($s instanceof Page && $s->isHomepage()) {
                    if (count($this->contextHelper->getDomain()->getLocales()) > 1) {
                        $fragment->setUrl($this->contextHelper->getLocale()->getCode());
                    } else {
                        $fragment->setUrl('/');
                    }
                }

                $items[] = [
                    'label' => $fragment->getLabel() ?: $s->getCurrentTranslation()->getName(),
                    'url' => $fragment->getUrl() ?: $this->contentRouter->generate($s, 'chain'),
                    'extra' => $fragment->getExtra(),
                ];
            } else {
                $items[] = [
                    'label' => $fragment->getLabel(),
                    'url' => $fragment->getUrl(),
                    'extra' => $fragment->getExtra(),
                ];
            }
        }

        $items = array_reverse($items);

        /** @var BreadcrumbsItem $item */
        foreach ($items as $idx => $item) {
            $last = $idx === (count($items) - 1);

            $linkOnLast = !empty($item['extra']['link_on_last']);
            $url = $linkOnLast ? $item['url'] : ($last ? null : $item['url']);

            $this->breadcrumbsService->add(
                $item['label'],
                $url,
                $item['extra']
            );
        }
    }
}
