using CommunityToolkit.Mvvm.Messaging;
using Microsoft.Maui.Devices.Sensors;
using SteUp.Shared.Core.BarcodeReader.Contracts;
using SteUp.Shared.Core.BarcodeReader.Dto;
using SteUp.Shared.Core.BarcodeReader.Enum;
using SteUp.Shared.Core.Messages.Scanner;

namespace SteUp.Shared.Core.BarcodeReader;

public class BarcodeManager(
    IBarcodeReaderService scanner,
    IMessenger messenger) : IBarcodeManager
{
    public void Init()
    {
        if (!scanner.IsRightAdapter())
        {
            Console.WriteLine("Dispositivo non compatibile con lo scanner Honeywell.");
            return;
        }

        scanner.Register(
            onScanSuccessful: dto =>
            {
                var stringValue = dto.StringValue;

                if (IsEanPeso(dto))
                    stringValue = DecodeEanPeso(stringValue);

                messenger.Send(new NewScannerMessage(stringValue));
            },
            onScanFailed: ex => { messenger.Send(new ErrorScannerMessage(ex.Message)); }
        );

        scanner.Init(() => { scanner.ChangeSettings([("TRIGGER_SCAN_MODE", "ONE_SHOT")]); });
    }

    private static bool IsEanPeso(BarcodeScanDto barcodeScan) =>
        (IsEtichetta128(barcodeScan) || IsEan13(barcodeScan)) && barcodeScan.StringValue is { Length: 13 } &&
        barcodeScan.StringValue.StartsWith('2');

    private static bool IsEtichetta128(BarcodeScanDto barcodeScan) =>
        barcodeScan.Type is BarcodeType.CODE128 or BarcodeType.EAN128;

    private static bool IsEan13(BarcodeScanDto barcodeScan) =>
        barcodeScan.Type == BarcodeType.EAN13;

    private static string DecodeEanPeso(string? barcode)
    {
        return barcode is not { Length: 13 } ? throw new Exception("Errore durante il parse del barcode (" + barcode + ")") : barcode.Substring(1, 6);
    }
}