<?php

declare(strict_types=1);

namespace App\Services;

use SimpleSoftwareIO\QrCode\Generator;

/**
 * QrCodeService — Service for QR Code payload formatting and generation.
 *
 * Scoped only to QR rendering. No database access or business logic.
 * Integrates with simplesoftwareio/simple-qrcode library.
 *
 * @package Inveetaire
 */
class QrCodeService
{
    /**
     * Generate an offline vector SVG layout resembling a QR code pattern containing the token text.
     * This acts as a graceful fallback if the generator fails.
     *
     * @param string $payload
     * @return string SVG content.
     */
    private static function getOfflineFallbackSvg(string $payload): string
    {
        return '<svg xmlns="http://www.w3.org/2000/svg" width="250" height="250" viewBox="0 0 250 250">
            <rect width="250" height="250" fill="#f8fafc" stroke="#e2e8f0" stroke-width="2"/>
            
            <!-- Standard QR Code finder patterns -->
            <rect x="20" y="20" width="50" height="50" fill="none" stroke="#0f172a" stroke-width="8"/>
            <rect x="35" y="35" width="20" height="20" fill="#0f172a"/>

            <rect x="180" y="20" width="50" height="50" fill="none" stroke="#0f172a" stroke-width="8"/>
            <rect x="195" y="35" width="20" height="20" fill="#0f172a"/>

            <rect x="20" y="180" width="50" height="50" fill="none" stroke="#0f172a" stroke-width="8"/>
            <rect x="35" y="195" width="20" height="20" fill="#0f172a"/>

            <!-- Simulated QR code pixels -->
            <rect x="90" y="30" width="20" height="10" fill="#334155"/>
            <rect x="130" y="20" width="10" height="30" fill="#334155"/>
            <rect x="90" y="70" width="40" height="10" fill="#334155"/>
            <rect x="150" y="60" width="20" height="20" fill="#334155"/>
            
            <rect x="30" y="90" width="10" height="40" fill="#334155"/>
            <rect x="60" y="110" width="30" height="10" fill="#334155"/>
            <rect x="100" y="100" width="50" height="20" fill="#0f172a"/>
            <rect x="160" y="90" width="20" height="40" fill="#334155"/>
            <rect x="200" y="100" width="30" height="10" fill="#334155"/>

            <rect x="30" y="150" width="30" height="10" fill="#334155"/>
            <rect x="90" y="140" width="20" height="30" fill="#334155"/>
            <rect x="130" y="150" width="40" height="20" fill="#334155"/>
            <rect x="190" y="130" width="10" height="50" fill="#334155"/>

            <rect x="90" y="200" width="50" height="10" fill="#334155"/>
            <rect x="160" y="190" width="10" height="30" fill="#334155"/>
            <rect x="180" y="210" width="40" height="20" fill="#334155"/>

            <!-- Center text indicator -->
            <rect x="60" y="125" width="130" height="32" rx="4" fill="#ffffff" stroke="#cbd5e1" stroke-width="1"/>
            <text x="125" y="145" font-family="system-ui, -apple-system, sans-serif" font-size="12" font-weight="bold" fill="#0f172a" text-anchor="middle">' . htmlspecialchars($payload) . '</text>
        </svg>';
    }

    /**
     * Generate Guest SVG.
     *
     * @param string $guestCode
     * @param int $size
     * @return string Raw SVG
     */
    public static function generateGuestSvg(string $guestCode, int $size = 300): string
    {
        $payload = trim($guestCode);
        try {
            $qrcode = new Generator();
            // Default generates SVG
            return (string) $qrcode->size($size)->errorCorrection('H')->margin(2)->generate($payload);
        } catch (\Throwable $e) {
            error_log("QrCodeService SVG Error: " . $e->getMessage());
            $svg = self::getOfflineFallbackSvg($payload);
            return str_replace('width="250" height="250"', 'width="' . $size . '" height="' . $size . '"', $svg);
        }
    }

    /**
     * Generate Guest PNG.
     * Note: Requires ext-imagick or ext-gd to be available.
     *
     * @param string $guestCode
     * @param int $size
     * @return string Raw PNG bytes
     */
    public static function generateGuestPng(string $guestCode, int $size = 1000): string
    {
        $payload = trim($guestCode);
        try {
            $qrcode = new Generator();
            return (string) $qrcode->format('png')->size($size)->errorCorrection('H')->margin(2)->generate($payload);
        } catch (\Throwable $e) {
            error_log("QrCodeService PNG Error: " . $e->getMessage());
            // If PNG generation fails (e.g., missing imagick/gd), return the SVG fallback as a string.
            // Downstream handlers should detect or fallback gracefully. We can return an empty string or the SVG fallback.
            $svg = self::getOfflineFallbackSvg($payload);
            return str_replace('width="250" height="250"', 'width="' . $size . '" height="' . $size . '"', $svg);
        }
    }
}
