<?php

namespace App\Libraries;

use Endroid\QrCode\Encoding\Encoding;
use Endroid\QrCode\ErrorCorrectionLevel;
use Endroid\QrCode\QrCode;
use Endroid\QrCode\RoundBlockSizeMode;
use Endroid\QrCode\Writer\SvgWriter;
use InvalidArgumentException;
use Throwable;

class SimpleQrCode
{
    public function toSvg(string $value, int $scale = 10, int $quietZone = 4): string
    {
        $value = trim($value);

        if ($value === '') {
            throw new InvalidArgumentException('Kode barang tidak dapat dibuat menjadi QR Code.');
        }

        try {
            $size = max(240, $scale * 30);
            $margin = max(32, $quietZone * 8);
            $qrCode = QrCode::create($value)
                ->setEncoding(new Encoding('ISO-8859-1'))
                ->setErrorCorrectionLevel(ErrorCorrectionLevel::Medium)
                ->setSize($size)
                ->setMargin($margin)
                ->setRoundBlockSizeMode(RoundBlockSizeMode::Margin);

            $svg = (new SvgWriter())->write($qrCode, null, null, [
                SvgWriter::WRITER_OPTION_EXCLUDE_XML_DECLARATION => true,
                SvgWriter::WRITER_OPTION_COMPACT => true,
            ])->getString();
        } catch (Throwable $exception) {
            throw new InvalidArgumentException('Kode barang tidak dapat dibuat menjadi QR Code.', 0, $exception);
        }

        return $this->addSvgScanAttributes($svg);
    }

    private function addSvgScanAttributes(string $svg): string
    {
        return preg_replace(
            '/<svg\b(?![^>]*shape-rendering=)/',
            '<svg preserveAspectRatio="xMidYMid meet" shape-rendering="crispEdges"',
            $svg,
            1
        ) ?? $svg;
    }
}
