// Copyright © Selmo Technology GmbH. All Rights Reserved

using SelmoStudio.Hmi.Server.Alarms.Model;
using SelmoStudio.Hmi.Server.Alarms.Model.Dto;

namespace SelmoStudio.Hmi.Server.Alarms.Service
{
    /// <summary>
    /// Test implementation of the Alarm service TODO Replace with a real implementation
    /// </summary>
    public class AlarmService : IAlarmService, IDisposable
    {
        private IList<AlarmDto> _alarmDtos;

        public Action OnUpdate { get; set; }

        public AlarmService()
        {
            GenerateTestAlarms();
        }

        public Task<IList<Alarm>> GetActive()
        {
            return Task.FromResult(GetMappedAlarms(_alarmDtos));
        }

        public Task<Alarm> LastActive => Task.FromResult(MapTestAlarm(_alarmDtos.Last()));

        public Task<Alarm> HeaderAlarm
        {
            get
            {
                if (_alarmDtos.Count > 0)
                {
                    var maxSeverityValue = _alarmDtos.Max(s => s.Severity);
                    var alarmWithHighestPriority = _alarmDtos.Where(a => a.Severity == maxSeverityValue).MaxBy(a => a.Created);

                    if (alarmWithHighestPriority != null)
                    {
                        return Task.FromResult(MapTestAlarm(alarmWithHighestPriority));
                    }
                }

                return Task.FromResult(GetTypeNoneAlarm());
            }
        }

        private Alarm GetTypeNoneAlarm()
        {
            return new Alarm()
            {
                AlarmType = AlarmType.None
            };
        }

        public void Add(Alarm alarm)
        {
            //If alarm already exists doesnt add but update date
            _alarmDtos.Add(Map(alarm));

            OnUpdate?.Invoke();
        }

        public void Remove(Guid id)
        {
            _alarmDtos = _alarmDtos.Where(alarm => !alarm.Id.Guid.Equals(id)).ToList();

            OnUpdate?.Invoke();
        }

        private AlarmDto Map(Alarm from)
        {
            AlarmDto dto = new()
            {
                Id = new(from.Id),
                Title = from.Title,
                Message = from.Message,
                Severity = from.Severity,
                Created = from.Created,
                AlarmType = from.AlarmType
            };

            return dto;
        }

        private void GenerateTestAlarms()
        {
            _alarmDtos = new List<AlarmDto>();
        }

        private IList<Alarm> GetMappedAlarms(IList<AlarmDto> alarmDtos)
        {
            var alarms = new List<Alarm>();

            foreach (var alarmDto in alarmDtos)
            {
                alarms.Add(MapTestAlarm(alarmDto));
            }

            return alarms;
        }

        private Alarm MapTestAlarm(AlarmDto alarmDto)
        {
            return new()
            {
                Id = alarmDto.Id.Guid,
                Severity = alarmDto.Severity,
                Created = alarmDto.Created,
                Title = alarmDto.Title,
                Message = alarmDto.Message,
                AlarmType = AlarmType.Standard
            };
        }

        public void Dispose()
        {
        }
    }
}