<?php

namespace App\Service\SnipParser\Twig;

use App\Dto\SnipFilterRequest;
use App\Entity\Snip;
use App\Repository\SnipRepository;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\Routing\RouterInterface;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

class SnipTwigExtension extends AbstractExtension
{
    public function __construct(
        #[Autowire(lazy: true)] private readonly RouterInterface $router,
        #[Autowire(lazy: true)] private readonly SnipRepository  $snipRepo,
        #[Autowire(lazy: true)] private readonly Security        $security,
    ) {}

    public function getFunctions(): array
    {
        return [
            new TwigFunction('snipPath', $this->snipPath(...)),
            new TwigFunction('snipLink', $this->snipLink(...), [
                'is_safe' => ['html'],
            ]),
            new TwigFunction('snipsByTag', $this->snipsByTag(...)),
        ];
    }

    private function snipPath(int $id): string
    {
        return $this->router->generate('snip_single', [
            'snip' => $id,
        ]);
    }

    private function snipLink(int $id): string
    {
        $snip = $this->snipRepo->find($id);
        if ($snip === null) {
            throw new \Exception(sprintf('Snip not found with id: %d', $id));
        }
        return sprintf('<a class="btn btn-sm btn-primary" href="%s">%s</a>', $this->snipPath($id), $snip);
    }

    private function snipsByTag(string $tag): array
    {
        // Todo: get 'context' user from the snip it is called from
        $user = $this->security->getUser();
        if ($user === null) {
            return [];
        }
        $request = new SnipFilterRequest(SnipFilterRequest::VISIBILITY_ALL, tag: $tag);
        $snips = $this->snipRepo->findByRequest($user, $request);
        return array_map(fn(Snip $snip) => [
            'id' => $snip->id,
            'name' => $snip->name,
        ], $snips);
    }
}
