using System.IO.Ports;
using System.Security.AccessControl;
using System.Text;
using Serilog;
using VisionBuilder.UI.Common;
using VisionBuilder.UI.Common.Processing;

namespace PackstrasseBarcodeReader
{
    public class PackstrasseBarcodeReaderModule : IVisionBuilderModule
    {
        private readonly PackstrasseBarcodeReaderSettings _settings;
        private readonly SingleCameraVM _singleCameraVm;
        private SerialPort _port;


        public PackstrasseBarcodeReaderModule(PackstrasseBarcodeReaderSettings settings, SingleCameraVM singleCameraVm)
        {
            _settings = settings;
            _singleCameraVm = singleCameraVm;
            
        }

        private void _port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Thread.Sleep(100);
            byte[] buffer = new byte[_port.BytesToRead];
            _port.Read(buffer, 0, _port.BytesToRead);
            var data = Encoding.ASCII.GetString(buffer).Trim();
            var vm = _singleCameraVm.GetRecipeSelectionVm();


            string searchString = data;
            if (_settings.BarcodeRecipeMappings.Any(x=>x.Barcode==searchString))
            {
                searchString = _settings.BarcodeRecipeMappings.First(x => x.Barcode == searchString).RecipeName;
            }

            var existingRecipe= vm.Recipes.FirstOrDefault(x => x.RecipeName == searchString);
            if (existingRecipe == null)
            {
                Log.Warning("No matching recipe found for data: {Data}", data);
                return;
            }
            vm.SelectedRecipe = vm.Recipes.FirstOrDefault(r => r.RecipeName == existingRecipe.RecipeName);
            _singleCameraVm.SynchronizationContext!.Post((_) =>
            {
                _singleCameraVm.ProcessRecipeSelectionVm(vm);
            }, null);
        }


        public void InitializeModule()
        {
            try
            {
                _port = new SerialPort(_settings.ComPort, 9600);
                _port.Open();
                _port.DataReceived += _port_DataReceived;
            }
            catch (Exception e)
            {
                Log.Warning(e, "Failed to open com-port");
            }
            
        }
    }
}
