<?php

namespace App\Domains\Unterschrift\Actions\RenderPreview;

use Imagick;
use ImagickPixel;
use RuntimeException;

class RenderPreviewCommand
{
    /** Aufloesung fuer die Vorschaubilder (klein halten, Platzierung erfolgt relativ). */
    private const PREVIEW_DPI = 96;

    /** Maximale Seitenzahl, die verarbeitet wird. */
    public const MAX_PAGES = 30;

    public function __construct(private readonly RenderPreviewRequest $request) {}

    public function execute(): RenderPreviewResponse
    {
        $doc = new Imagick();
        $doc->setResolution(self::PREVIEW_DPI, self::PREVIEW_DPI);

        try {
            $doc->readImage($this->request->pdfPath);
        } catch (\ImagickException $e) {
            throw new RuntimeException('Das PDF konnte nicht gelesen werden.', 0, $e);
        }

        $pageCount = $doc->getNumberImages();

        if ($pageCount < 1) {
            throw new RuntimeException('Das PDF enthält keine Seiten.');
        }

        if ($pageCount > self::MAX_PAGES) {
            throw new RuntimeException('Das PDF hat zu viele Seiten (max. ' . self::MAX_PAGES . ').');
        }

        $pages = [];

        for ($i = 0; $i < $pageCount; $i++) {
            $doc->setIteratorIndex($i);
            $doc->setImageBackgroundColor(new ImagickPixel('white'));

            if ($doc->getImageAlphaChannel()) {
                $doc->setImageAlphaChannel(Imagick::ALPHACHANNEL_REMOVE);
            }

            $doc->setImageFormat('png');

            $pages[] = [
                'dataUri' => 'data:image/png;base64,' . base64_encode($doc->getImageBlob()),
                'width'   => $doc->getImageWidth(),
                'height'  => $doc->getImageHeight(),
            ];
        }

        $doc->clear();

        return new RenderPreviewResponse(pages: $pages, pageCount: $pageCount);
    }
}
