using Extrudex.Domain.Enums;
using Extrudex.Domain.Interfaces;
using QRCoder;

namespace Extrudex.Infrastructure.Services;

/// <summary>
/// Generates high-contrast QR codes encoding deep links to Extrudex resources.
/// Optimized for small label printing with dark modules on white background.
/// Uses QRCoder library with ECC-level High for robust scanning on tiny labels.
/// </summary>
public class QrCodeService : IQrCodeService
{
    private const string BaseUrl = "https://extrudex.app";

    /// <inheritdoc />
    public byte[] GeneratePng(QrResourceType resourceType, Guid id, int pixelsPerModule = 20)
    {
        var url = GetResourceUrl(resourceType, id);

        using var qrGenerator = new QRCodeGenerator();
        var qrCodeData = qrGenerator.CreateQrCode(
            url,
            QRCodeGenerator.ECCLevel.H); // High error correction — critical for small labels

        using var qrCode = new PngByteQRCode(qrCodeData);
        return qrCode.GetGraphic(
            pixelsPerModule,
            darkColorRgba: new byte[] { 0, 0, 0, 255 },       // Pure black — maximum contrast
            lightColorRgba: new byte[] { 255, 255, 255, 255 }, // Pure white background
            drawQuietZones: true);                               // Quiet zones improve scan reliability
    }

    /// <inheritdoc />
    public string GenerateSvg(QrResourceType resourceType, Guid id)
    {
        var url = GetResourceUrl(resourceType, id);

        using var qrGenerator = new QRCodeGenerator();
        var qrCodeData = qrGenerator.CreateQrCode(
            url,
            QRCodeGenerator.ECCLevel.H);

        using var svgQrCode = new SvgQRCode(qrCodeData);
        return svgQrCode.GetGraphic(
            pixelsPerModule: 20,
            darkColorHex: "#000000",    // Pure black — maximum contrast
            lightColorHex: "#FFFFFF",   // Pure white background
            drawQuietZones: true,
            sizingMode: SvgQRCode.SizingMode.WidthHeightAttribute);
    }

    /// <inheritdoc />
    public string GetResourceUrl(QrResourceType resourceType, Guid id)
    {
        var path = resourceType switch
        {
            QrResourceType.Spool => $"/spools/{id}",
            QrResourceType.Printer => $"/printers/{id}",
            QrResourceType.Location => $"/locations/{id}",
            _ => throw new ArgumentOutOfRangeException(nameof(resourceType),
                resourceType, $"Unsupported QR resource type: {resourceType}")
        };

        return $"{BaseUrl}{path}";
    }
}