<?php

namespace App\Service\SnipParser\Markdown;

use App\Repository\SnipRepository;
use App\Service\SnipParser\AbstractParser;
use League\CommonMark\Event\DocumentParsedEvent;
use League\CommonMark\Extension\CommonMark\Node\Inline\Link;
use League\CommonMark\GithubFlavoredMarkdownConverter;
use League\CommonMark\Node\Inline\Text;
use League\CommonMark\Node\Query;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\Routing\RouterInterface;
use Tempest\Highlight\CommonMark\HighlightExtension;
use Tempest\Highlight\Highlighter;

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

    public function safeParseView(string $content): string
    {
        $converter = new GithubFlavoredMarkdownConverter();
        $converter
            ->getEnvironment()
            ->addExtension(new HighlightExtension(
                new Highlighter()->withGutter()
            ))
            ->addEventListener(DocumentParsedEvent::class, $this->documentParsed(...))
        ;
        return $converter->convert($content);
    }

    private function documentParsed(DocumentParsedEvent $event): void
    {
        $document = $event->getDocument();

        $linkNodes = new Query()
            ->where(Query::type(Link::class))
            ->findAll($document)
        ;

        foreach ($linkNodes as $linkNode) {
            $url = $linkNode->getUrl();

            $snip = $this->snipRepo->find($url);
            if ($snip === null) {
                continue;
            }
            $linkNode->setUrl($this->router->generate('snip_single', [
                'snip' => $url,
            ]));
            $textNode = $linkNode->firstChild();
            if (!$textNode) {
                $linkNode->appendChild(new Text($snip));
            }
        }
    }
}