<?php


namespace AutoAdmin\Bundle\Menu\Twig;

use AutoAdmin\Bundle\Menu\Provider\MenuProvider;
use Doctrine\ORM\EntityManagerInterface;
use Knp\Menu\ItemInterface;
use Knp\Menu\Twig\Helper;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

class AutoAdminMenuExtension extends AbstractExtension
{
    public function __construct(
        protected Helper $helper,
        protected EntityManagerInterface $em,
        protected MenuProvider $provider,
    ) {
    }

    public function getFunctions(): array
    {
        return [
            new TwigFunction('aa_menu', [$this, 'render'], ['is_safe' => ['html']]),
            new TwigFunction('knp_menu_render', [$this, 'render'], ['is_safe' => ['html']]),
            new TwigFunction('aa_menu_exists', [$this, 'menuExists'], ['is_safe' => ['html']]),
        ];
    }

    public function getFilters(): array
    {
        return [];
    }

    /**
     * Renders a menu with the specified renderer.
     */
    public function render(array|ItemInterface|string $menu, array $options = [], $renderer = null): string
    {
        $menuName = $this->menuToString($menu);

        if (empty($options['currentClass'])) {
            $options['currentClass'] = 'active';
        }

        if (empty($options['quiet_if_not_found'])) {
            $options['quiet_if_not_found'] = true;
        }

        if ($options['quiet_if_not_found'] && !$this->provider->doSlugExist($menuName)) {
            return '<!-- aa:menu:menu-not-found -->';
        }

        return $this->helper->render($menu, $options, $renderer);
    }

    public function menuExists(array|ItemInterface|string $menu): bool
    {
        $menuName = $this->menuToString($menu);

        return $this->provider->doSlugExist($menuName);
    }

    private function menuToString(array|ItemInterface|string $menu): string
    {
        if (is_array($menu)) {
            $menuName = $menu[0] ?? null;
        } elseif ($menu instanceof ItemInterface) {
            $menuName = $menu->getName();
        } else {
            $menuName = $menu;
        }

        return $menuName;
    }
}
