<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\AdminBundle\Twig;

use Ferienpass\AdminBundle\Controller\Fragment\ListActionsController;
use Knp\Menu\ItemInterface;
use Knp\Menu\Twig\Helper;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Twig\Attribute\AsTwigFunction;

class MenuExtension
{
    public function __construct(
        private readonly Helper $helper,
        private readonly UrlGeneratorInterface $urlGenerator,
    ) {
    }

    #[AsTwigFunction('list_actions')]
    public function get($item, array $path = [], array $options = []): ItemInterface
    {
        return $this->helper->get('admin_list_actions', $path, ['item' => $item] + $options);
    }

    /**
     * Where a row's dropdown fetches its entries from, or null when the row
     * cannot be addressed by type and id — those keep the eager menu.
     *
     * Building a menu walks the workflow and the voters, so a list that did it
     * per row spent most of its time producing markup behind a click.
     */
    #[AsTwigFunction('list_actions_src')]
    public function src($item, array $options = []): ?string
    {
        if (!\is_object($item)) {
            return null;
        }

        $slug = ListActionsController::slugFor($item);
        if (null === $slug || !method_exists($item, 'getId') || null === $id = $item->getId()) {
            return null;
        }

        return $this->urlGenerator->generate('admin_list_actions', array_filter([
            'type' => $slug,
            'id' => $id,
            'view' => $options['view'] ?? null,
            'edition' => $options['edition'] ?? null,
        ], static fn ($v) => null !== $v && '' !== $v));
    }

    /**
     * The frame id a row's dropdown and its fragment agree on.
     */
    #[AsTwigFunction('list_actions_frame')]
    public function frame($item): ?string
    {
        if (!\is_object($item)) {
            return null;
        }

        $slug = ListActionsController::slugFor($item);
        if (null === $slug || !method_exists($item, 'getId') || null === $id = $item->getId()) {
            return null;
        }

        return \sprintf('list-actions-%s-%d', $slug, $id);
    }
}
