using ZXing;
using ZXing.Common;

namespace MaBibli.Client.Scan;

/// <summary>
/// Décodage d'un code-barres EAN-13 / EAN-8 à partir d'un buffer de pixels RGBA.
///
/// Décision actée dans CLAUDE.md : le décodage reste **entièrement en C#** (ZXing.Net),
/// le JavaScript ne sert qu'à fournir les pixels de la caméra. Cette classe ne dépend
/// donc ni du navigateur, ni de Blazor : elle est réutilisable telle quelle hors WASM
/// (app native, décodage d'une photo côté serveur, scan en masse).
/// </summary>
public static class IsbnScanner
{
    // ZXing.Net n'est pas thread-safe sur ce lecteur, mais le WASM est mono-thread
    // et la boucle de scan est séquentielle : une instance partagée suffit et évite
    // de reconstruire les hints à chaque frame.
    private static readonly MultiFormatReader Reader = new()
    {
        Hints = new Dictionary<DecodeHintType, object>
        {
            [DecodeHintType.POSSIBLE_FORMATS] = new List<BarcodeFormat>
            {
                BarcodeFormat.EAN_13, BarcodeFormat.EAN_8,
            },
            [DecodeHintType.TRY_HARDER] = true,
        },
    };

    /// <summary>
    /// Tente de décoder un code-barres. Renvoie le texte brut du code, ou <c>null</c>
    /// si la frame n'en contient aucun de lisible — cas très majoritaire en usage réel.
    /// </summary>
    /// <param name="rgba">Buffer brut issu de <c>ctx.getImageData(...).data</c> (4 octets par pixel).</param>
    public static string? TryDecode(byte[] rgba, int largeur, int hauteur)
    {
        ArgumentNullException.ThrowIfNull(rgba);

        if (largeur <= 0 || hauteur <= 0 || rgba.Length < largeur * hauteur * 4)
        {
            return null;
        }

        // RGBLuminanceSource consomme directement le buffer du canvas :
        // aucune bibliothèque d'image nécessaire (ni SkiaSharp, ni ImageSharp).
        var source = new RGBLuminanceSource(
            rgba, largeur, hauteur, RGBLuminanceSource.BitmapFormat.RGBA32);

        // La version .NET de ZXing renvoie null sur échec (pas d'exception).
        return Reader.decode(new BinaryBitmap(new HybridBinarizer(source)))?.Text;
    }
}
