<?php

namespace AutoAdmin\Bundle\Content\Breadcrumbs\Manager;

use AutoAdmin\Bundle\Content\Breadcrumbs\Generator\BreadcrumbsGeneratorInterface;
use AutoAdmin\Bundle\Content\Breadcrumbs\Generator\DefaultBreadcrumbsGenerator;
use Doctrine\ORM\EntityManagerInterface;
use Traversable;

class BreadcrumbsGeneratorManager implements BreadcrumbsGeneratorManagerInterface
{
    private array $managed;
    private array $refs;


    public function __construct(
        Traversable $builders,
        protected EntityManagerInterface $em,
    ) {
        // builders tagged with "aa_seo.sitemap_builder"
        $this->managed = array_map($this->add(...), iterator_to_array($builders));
    }

    public function generate(?object $subject, bool $appendHomepage = false): ?array
    {
        if (!empty($this->refs[spl_object_id($subject)])) {
            return [];
        }

        $this->refs[spl_object_id($subject)] = $subject;

        $fragments = [];
        if (empty($subject)) {
            return null;
        }

        /** @var BreadcrumbsGeneratorInterface $generator */
        foreach ($this->managed as $generator) {
            if ($generator->supports($subject)) {
                $fragments = [...$fragments, ...$generator->generateFragments($subject, $this)];
                break;
            }
        }

        if ($appendHomepage) {
            $homepage = $this->em->getRepository('\\App\\Entity\\Page')->contentFindOneBy(['_.homepage' => true]);
            if ($homepage && !in_array($homepage, $fragments)) {
                /** @var DefaultBreadcrumbsGenerator $defaultGenerator */
                $filter = fn($m) => $m instanceof DefaultBreadcrumbsGenerator;
                $defaultGenerator = array_values(array_filter($this->managed, $filter))[0] ?: null;

                $fragments = [...$fragments, ...$defaultGenerator->generateFragments($homepage, $this)];
            }
        }

        return $fragments;
    }


    protected function add(BreadcrumbsGeneratorInterface $managed): BreadcrumbsGeneratorInterface
    {
        return $managed;
    }
}
