<?php

declare(strict_types=1);

namespace App\Domain\QrCode\ValueObject;

readonly class QrCodeMatrix
{
    public function __construct(
        private array $matrix
    ) {
    }

    public function getMatrix(): array
    {
        return $this->matrix;
    }

    public function getSize(): int
    {
        return count($this->matrix);
    }

    public function getModule(int $row, int $col): bool
    {
        return $this->matrix[$row][$col] ?? false;
    }

    public function toSvg(int $moduleSize = 4, int $margin = 4, string $foreground = '#000000', string $background = '#FFFFFF'): string
    {
        // Stellen Sie sicher, dass der Margin mindestens 4 Module beträgt (Quiet Zone)
        $margin = max(4, $margin);

        $size = $this->getSize();
        $totalSize = ($size + 2 * $margin) * $moduleSize;

        $svg = sprintf(
            '<svg width="%d" height="%d" viewBox="0 0 %d %d" xmlns="http://www.w3.org/2000/svg">',
            $totalSize, $totalSize, $totalSize, $totalSize
        );

        $svg .= sprintf('<rect width="100%%" height="100%%" fill="%s"/>', $background);

        for ($row = 0; $row < $size; $row++) {
            for ($col = 0; $col < $size; $col++) {
                if ($this->getModule($row, $col)) {
                    $x = ($col + $margin) * $moduleSize;
                    $y = ($row + $margin) * $moduleSize;
                    $svg .= sprintf(
                        '<rect x="%d" y="%d" width="%d" height="%d" fill="%s"/>',
                        $x, $y, $moduleSize, $moduleSize, $foreground
                    );
                }
            }
        }

        $svg .= '</svg>';

        return $svg;
    }

    public function toPng(int $moduleSize = 4, int $margin = 4): string
    {
        // Stellen Sie sicher, dass der Margin mindestens 4 Module beträgt (Quiet Zone)
        $margin = max(4, $margin);

        $size = $this->getSize();
        $totalSize = ($size + 2 * $margin) * $moduleSize;

        $image = imagecreate($totalSize, $totalSize);
        $white = imagecolorallocate($image, 255, 255, 255);
        $black = imagecolorallocate($image, 0, 0, 0);

        imagefill($image, 0, 0, $white);

        for ($row = 0; $row < $size; $row++) {
            for ($col = 0; $col < $size; $col++) {
                if ($this->getModule($row, $col)) {
                    $x1 = ($col + $margin) * $moduleSize;
                    $y1 = ($row + $margin) * $moduleSize;
                    $x2 = $x1 + $moduleSize - 1;
                    $y2 = $y1 + $moduleSize - 1;

                    imagefilledrectangle($image, $x1, $y1, $x2, $y2, $black);
                }
            }
        }

        ob_start();
        imagepng($image);
        $pngData = ob_get_contents();
        ob_end_clean();

        imagedestroy($image);

        return $pngData;
    }

    public function toAscii(): string
    {
        $size = $this->getSize();
        $result = '';

        for ($row = 0; $row < $size; $row++) {
            for ($col = 0; $col < $size; $col++) {
                $result .= $this->getModule($row, $col) ? '██' : '  ';
            }
            $result .= "\n";
        }

        return $result;
    }
}
