// Copyright © Selmo Technology GmbH. All Rights Reserved

using Microsoft.AspNetCore.Components;
using Novus.Connectivity.Common;
using Novus.Connectivity.Service;
using Novus.Shared.Types.Extensions;
using SelmoStudio.Hmi.Server.ProcessValue.Services;
using SelmoStudio.Hmi.Server.SelmoHmi.Plant.Pages;
using SelmoStudio.Hmi.Server.Shared.Service;

namespace SelmoStudio.Hmi.Server.Shared.Pages.SelmoHome
{
    public partial class SelmoHome
    {
        private SelmoHmiValueHandler _selmoHmiValueHandler;

        private PlantOverview Plant { get; set; }

        [Inject]
        private IHmiWatchdog _hmiWatchDog { get; set; }

        [Inject]
        private IProcessValuePollingService _valuePollingService { get; set; }

        [Inject]
        private IRegistrationService _registrationService { get; set; }

        #region Init_Lifecycle

        public SelmoHome()
        {
        }

        protected override async Task OnInitializedAsync()
        {
            await base.OnInitializedAsync();
        }

        protected override async Task OnAfterRenderAsync(bool firstRender)
        {
            if (firstRender)
            {
                _hmiWatchDog.OnCycleSecondElapsed += IntervalElapsed;
                _selmoHmiValueHandler = new(_valuePollingService);
                Plant.ComponentChangeEvent += OnEventTriggered;
            }

            await base.OnAfterRenderAsync(firstRender);
        }

        #endregion Init_Lifecycle

        private void OnEventTriggered(object? sender, SelmoHmi.Shared.Component.ComponentEventArgs e)
        {
            _selmoHmiValueHandler.HandleEvent(e);
        }

        private void IntervalElapsed(object sender, WatchdogEventArgs e)
        {
            Task.Run(async () =>
            {
                if (Plant.IsRendered)
                {
                    var valuesToRegister = Plant.GetValueInfos();

                    var regId = HandleRegistration(valuesToRegister);

                    if (regId.Guid.IsEmpty() || !_valuePollingService.IsReady())
                    {
                        return;
                    }

                    //var valueOperation = await _valuePollingService.GetValues(regId);
                    var valueOperation = await _valuePollingService.GetAllValues();

                    if (valueOperation.Issues.Any())
                    {
                        return;
                    }

                    var processValues = valueOperation.Value.ProcessValues;

                    Plant.Update(processValues);
                }
            });
        }

        #region Registration

        private Dictionary<ProcessValueId, IProcessValueInfo> _registeredProcessValues = new();

        private ValuesConnectionRegistrationId _currentRegistration;

        private ValuesConnectionRegistrationId HandleRegistration(List<IProcessValueInfo> valuesToRegister)
        {
            if (AnyValueToRegister(valuesToRegister))
            {
                _registeredProcessValues = valuesToRegister.ToDictionary(item => item.Id);
                ValuesConnectionRegistration reg = ValuesConnectionRegistration.Create(valuesToRegister.ToArray());

                _valuePollingService.RegisterValues(reg);
                _currentRegistration = reg.Id;
            }
            return _currentRegistration;
        }

        private bool AnyValueToRegister(List<IProcessValueInfo> valuesToRegister)
        {
            foreach (var info in valuesToRegister)
            {
                if (!_registeredProcessValues.ContainsKey(info.Id))
                    return true;
            }

            return false;
        }

        #endregion Registration
    }
}