using DxBlazorApplication2.AS400Kommunikation;
using DxBlazorApplication2.Data.Produktion;
using System.Linq;

namespace DxBlazorApplication2.Services.Produktion
{
    /// <summary>
    ///  Produktionsaufträge
    /// </summary>
    public class PSDLService : IDisposable
    {
        private readonly Dictionary<double, PSDLItem> _psdlItems;
        public delegate void PSDLServiceDelegate(object sender, PSDLServiceEventArgs args);
        public event PSDLServiceDelegate OnItemChanged;
        private AS400Connector _loader;
        private readonly Logger _logger = new Logger();
        private Task _autoAdd;
        private AS400Connector Loader
        {
            get
            {
                // Erster Aufruf
                if (_loader == null)
                {
                    _loader = new AS400Connector("7550");
                }
                // Reconnect
                else if (!_loader.Connected)
                {
                    _loader = new AS400Connector("7550");
                    _loader.Clear("10");
                    _loader.SetString("A0OPTI", "9"); // Automatikjob starten
                    _loader.WriteSatz();
                }
                return _loader;
            }
        }

        public PSDLService()
        {
            _logger.Log("PSDLService()");
            _psdlItems = new Dictionary<double, PSDLItem>();
            Loader.Clear("10");
            Loader.SetString("A0OPTI", "1"); // Alle Aufträge des Tages einlesen
            Loader.WriteSatz();
            while (Loader.ReadLine() == "11")
                _psdlItems.Add(Loader.GetDouble("A1PANR"), new PSDLItem(Loader));

            _autoAdd = Task.Factory.StartNew(() =>
            {
                _logger.Log($"PSDLService(Task): Loader.Connected={Loader.Connected}");
                Loader.Clear("10");
                Loader.SetString("A0OPTI", "9"); // Automatikjob starten
                Loader.WriteSatz();
                while (true)
                {
                    try
                    {
                        string test = Loader.ReadLine();
                        double PANR = Loader.GetDouble("A1PANR");
                        if (_psdlItems.ContainsKey(PANR))
                            _psdlItems[PANR].Load(Loader);
                        else
                            _psdlItems[PANR] = new PSDLItem(Loader);
                        if (this.OnItemChanged != null)
                            this.OnItemChanged(this, new PSDLServiceEventArgs(_psdlItems[PANR]));
                    }
                    catch (Exception ex)
                    {
                        _logger.Log($"PSDLService(Task): Exception={ex.Message}");
                        break;
                    }
                }
                _logger.Log($"PSDLService(Task): Ende");
            });
        }

        public void Dispose()
        {
            _logger.Log($"PSDLService.Dispose()");
            if (_loader != null)
            {
                _logger.Log($"PSDLService.Dispose(): Loader.Connected={_loader.Connected}");
                if (_loader.Connected)
                    _loader.Close();
                _loader.Dispose();
                _loader = null;
            }
            if (_autoAdd != null)
            {
                _logger.Log($"PSDLService.Dispose(): AutoAdd.Status={_autoAdd.Status}");
                if(!_autoAdd.IsCompleted)
                    if(!_autoAdd.Wait(10000))
                        _logger.Log($"PSDLService.Dispose(): AutoAdd nicht Completed!");
            }
        }

        public IEnumerable<PSDLItem> GetItems()
        {
            return _psdlItems.Values;
        }
    }

    public class PSDLServiceEventArgs : EventArgs
    {
        public PSDLItem DataItem { get; }
        public PSDLServiceEventArgs(PSDLItem item)
        {
            this.DataItem = item;
        }
    }
}
