<?php

namespace App\Service\SnipParser\Generic;

use InvalidArgumentException;
use League\Pipeline\StageInterface;
use Tempest\Highlight\Highlighter;

readonly class ReplaceBlocksStage implements StageInterface
{
    public function __construct(
        public string $openTag = '<pre><code>',
        public string $closeTag = '</code></pre>',
        public string $delimiter = '```'
    ) {}

    public function __invoke(mixed $payload): string
    {
        if (!is_string($payload)) {
            throw new InvalidArgumentException('The payload must be a string.');
        }

        return $this->replaceCodeBlocks($payload);
    }

    private function replaceCodeBlocks(string $text): string
    {
        $pattern = sprintf('/%s(.+?)%s/s', preg_quote($this->delimiter), preg_quote($this->delimiter));

        $highlighter = new Highlighter()->withGutter();
        return preg_replace_callback($pattern, function ($matches) use ($highlighter) {
            return $this->openTag . $highlighter->parse(trim($matches[1]), 'php') . $this->closeTag;
        }, $text);
    }
}