// Copyright © Selmo Technology GmbH. All Rights Reserved

using Novus.Connectivity.Common;
using Novus.Connectivity.Service;
using SelmoStudio.Hmi.Common.SelmoProject.ProcessValue;
using SelmoStudio.Hmi.Server.SelmoHmi.Cmz.Model.Ids;
using SelmoStudio.Hmi.Server.SelmoHmi.Model.Dtos;
using SelmoStudio.Hmi.Server.SelmoHmi.Model.Ids;
using SelmoStudio.Hmi.Server.SelmoHmi.Model.ProjectItems;
using SelmoStudio.Hmi.Server.SelmoHmi.Parameter.Model.Ids;
using SelmoStudio.Hmi.Server.SelmoHmi.Plant.Model;
using SelmoStudio.Hmi.Server.SelmoHmi.Plant.Model.Ids;
using SelmoStudio.Hmi.Server.SelmoHmi.Sequence.Model;
using SelmoStudio.Hmi.Server.SelmoHmi.Sequence.Model.Dto;
using SelmoStudio.Hmi.Server.SelmoHmi.Sequence.Model.Ids;
using SelmoStudio.Hmi.Server.SelmoHmi.Shared.Model;
using SelmoStudio.Hmi.Server.SelmoHmi.Shared.TestImpl;

namespace SelmoStudio.Hmi.Server.ProcessValue.Services
{
    public class ProcessValueInfoService : IProcessValueInfoService
    {
        public ProcessValueInfoService()
        {
        }

        public void Init(ProcessValuesPlant plantInfo)
        {
            PlantProcessInfo = plantInfo;
        }

        public ProcessValuesPlant PlantProcessInfo { get; set; }

        public ValuesConnectionRegistration CreateCmzRegistration(SelmoHmiProject project)
        {
            List<IProcessValueInfo> infos = new();
            project.Plants.ForEach(plant =>
            {
                infos.AddRange(GetPlantCmzs(plant));
                plant.HardwareZones.ForEach(hardwareZone =>
                {
                    infos.AddRange(GetHardwareZoneCmzs(hardwareZone));
                    hardwareZone.Sequences.ForEach(sequence =>
                    {
                        infos.AddRange(GetSequenceCmzs(sequence));
                    });
                });
            });
            return ValuesConnectionRegistration.Create(infos.ToArray());
        }

        private IEnumerable<IProcessValueInfo> GetPlantCmzs(ProjectItemCollectionPlant plant)
        {
            List<IProcessValueInfo> infos = new();
            plant.CmzCollection.ForEach(cmzColl =>
            {
                cmzColl.Cmzs.ForEach(cmz =>
                {
                    var processValueInfo = GetProcessValueInfo(cmz.Id, plant.PlantInfo.Id);

                    if (processValueInfo != null)
                    {
                        infos.Add(processValueInfo);
                    }
                });
            });
            return infos;
        }

        private IEnumerable<IProcessValueInfo> GetHardwareZoneCmzs(ProjectItemCollectionHwInfo hw)
        {
            List<IProcessValueInfo> infos = new();
            hw.CmzCollection.ForEach(cmzColl =>
            {
                cmzColl.Cmzs.ForEach(cmz =>
                {
                    var processValueInfo = GetProcessValueInfo(cmz.Id, hw.HardwareZoneInfo.Id);

                    if (processValueInfo != null)
                    {
                        infos.Add(processValueInfo);
                    }
                });
            });
            return infos;
        }

        private IEnumerable<IProcessValueInfo> GetSequenceCmzs(ProjectItemCollectionSequence sequence)
        {
            List<IProcessValueInfo> infos = new();
            sequence.CmzCollection.Cmzs.ForEach(cmz =>
            {
                var processValueInfo = GetProcessValueInfo(cmz.Id, sequence.SequenceInfo.Id);

                if (processValueInfo != null)
                {
                    infos.Add(processValueInfo);
                }
            });
            return infos;
        }

        public ValuesConnectionRegistration CreateParameterRegistration(List<ParameterId> paramIds, SequenceId seqId)
        {
            List<IProcessValueInfo> infos = new();
            foreach (var id in paramIds)
            {
                var processValueInfo = GetProcessValueInfo(id, seqId);

                if (processValueInfo != null)
                {
                    infos.Add(processValueInfo);
                }
            }

            return ValuesConnectionRegistration.Create(infos.ToArray());
        }

        public ValuesConnectionRegistration CreateParameterRegistration(List<ParameterId> paramIds, HardwareZoneId hwId)
        {
            List<IProcessValueInfo> infos = new();
            foreach (var id in paramIds)
            {
                var processValueInfo = GetProcessValueInfo(id, hwId);

                if (processValueInfo != null)
                {
                    infos.Add(processValueInfo);
                }
            }

            return ValuesConnectionRegistration.Create(infos.ToArray());
        }

        public ValuesConnectionRegistration CreateParameterRegistration(List<ParameterId> paramIds)
        {
            List<IProcessValueInfo> infos = new();
            foreach (var id in paramIds)
            {
                var processValueInfo = GetProcessValueInfo(id);

                if (processValueInfo != null)
                {
                    infos.Add(processValueInfo);
                }
            }

            return ValuesConnectionRegistration.Create(infos.ToArray());
        }

        public Dictionary<ParameterId, ProcessValueId> GetParameterLookupTable(List<ParameterId> paramIds, SequenceId seqId)
        {
            Dictionary<ParameterId, ProcessValueId> lookupTable = new();
            foreach (var id in paramIds)
            {
                var processValueInfo = GetProcessValueInfo(id, seqId);

                if (processValueInfo != null)
                {
                    lookupTable[id] = processValueInfo.Id;
                }
            }

            return lookupTable;
        }

        public Dictionary<ParameterId, ProcessValueId> GetParameterLookupTable(List<ParameterId> paramIds, HardwareZoneId hwId)
        {
            Dictionary<ParameterId, ProcessValueId> lookupTable = new();
            foreach (var id in paramIds)
            {
                var processValueInfo = GetProcessValueInfo(id, hwId);

                if (processValueInfo != null)
                {
                    lookupTable[id] = processValueInfo.Id;
                }
            }

            return lookupTable;
        }

        public Dictionary<ParameterId, ProcessValueId> GetParameterLookupTable(List<ParameterId> paramIds)
        {
            Dictionary<ParameterId, ProcessValueId> lookupTable = new();
            foreach (var id in paramIds)
            {
                var processValueInfo = GetProcessValueInfo(id);

                if (processValueInfo != null)
                {
                    lookupTable[id] = processValueInfo.Id;
                }
            }

            return lookupTable;
        }

        public ValuesConnectionRegistration CreateZoneHMIButtonRegistration(List<ZoneId> ids, SequenceId seqId)
        {
            List<IProcessValueInfo> infos = new();
            foreach (var id in ids)
            {
                var processValueInfo = GetProcessValueInfo(id, seqId);

                if (processValueInfo != null)
                {
                    infos.Add(processValueInfo.ZoneManualButtonVariable);
                    infos.Add(processValueInfo.ZoneInputActiveState);
                    infos.Add(processValueInfo.ZoneOutputActiveState);
                }
            }

            return ValuesConnectionRegistration.Create(infos.ToArray());
        }

        public ValuesConnectionRegistration CreateSequenceRegistrationWithoutStepCounter(SequenceId id)
        {
            List<IProcessValueInfo> infos = new();

            var seqInfo = GetProcessValueInfo(id);
            if (seqInfo != null)
            {
                infos.Add(seqInfo.TriggerStepNextValid);
                infos.Add(seqInfo.TriggerStepReset);
                infos.Add(seqInfo.TriggerStepSingle);
                infos.Add(seqInfo.TriggerSingleStepOn);
                infos.Add(seqInfo.TriggerStepDecrement);
                infos.Add(seqInfo.TriggerStepIncrement);
                infos.Add(seqInfo.Status.GhostModeInput);
            }

            return ValuesConnectionRegistration.Create(infos.ToArray());
        }

        public ValuesConnectionRegistration CreateSequenceRegistrationStepCounterAndZones(SequenceId id)
        {
            List<IProcessValueInfo> infos = new();

            var seqInfo = GetProcessValueInfo(id);
            if (seqInfo != null)
            {
                infos.Add(seqInfo.Status.StepCount);

                foreach (var waitingFor in seqInfo.StandardWaitingFor)
                {
                    infos.Add(waitingFor.Value);
                }

                foreach (var waitingFor in seqInfo.ZoneInfos)
                {
                    infos.Add(waitingFor.Value.WaitingActive);
                    infos.Add(waitingFor.Value.WaitingForPair);
                }

                foreach (var outputZones in seqInfo.OutputZones)
                {
                    infos.Add(outputZones.Value);
                }
            }

            return ValuesConnectionRegistration.Create(infos.ToArray());
        }

        public ValuesConnectionRegistration CreateStepMonitoringRegistration(SequenceId id)
        {
            List<IProcessValueInfo> infos = new();

            var seqInfo = GetProcessValueInfo(id);
            if (seqInfo != null)
            {
                infos.Add(seqInfo.Status.TeachMode);
                foreach (var step in seqInfo.MonitoringSteps.Values)
                {
                    infos.Add(step.TimeAvg);
                    infos.Add(step.TimeMin);
                    infos.Add(step.ActualTime);
                    infos.Add(step.TimeMax);
                    infos.Add(step.TimeLast);
                    infos.Add(step.TimeoutAdd);
                    infos.Add(step.TimeoutSet);
                    infos.Add(step.TimeoutCount);
                    infos.Add(step.TimeoutDisabled);
                }
            }

            return ValuesConnectionRegistration.Create(infos.ToArray());
        }

        public ValuesConnectionRegistration CreateHwZoneRegistration(HardwareZoneId id, List<HardwareZoneInfoDto> zoneInfos)
        {
            List<IProcessValueInfo> infos = new();

            var hwInfo = GetProcessValueInfo(id);
            if (hwInfo != null)
            {
                infos.Add(hwInfo.SafetyGateLamp);
                infos.Add(hwInfo.EocReachedLamp);
                infos.Add(hwInfo.AutomaticLamp);
                infos.Add(hwInfo.AllSequencesReady);
                infos.Add(hwInfo.AnySequencesReady);
                infos.Add(hwInfo.AutomaticMode);
                infos.Add(hwInfo.ManualMode);
                infos.Add(hwInfo.HardwareZoneAutomaticRelease);
                infos.Add(hwInfo.EmergencyStopLamp);
                infos.Add(hwInfo.EocMode);
                infos.Add(hwInfo.EocModeIsOn);
                infos.Add(hwInfo.EocModeIsOff);
                infos.Add(hwInfo.AnySeqEocReached);
                infos.Add(hwInfo.AnySeqGhostMode);
                infos.Add(hwInfo.AnySeqSingleStep);
                infos.Add(hwInfo.AnySeqTimeout);
                infos.Add(hwInfo.AllSequencesAutomaticRelease);
                infos.Add(hwInfo.AnySeqInterlockFault);
                infos.Add(hwInfo.AnySeqCmzFault);
            }

            foreach (var zoneInfo in zoneInfos)
            {
                if (!zoneInfo.Id.Guid.Equals(id.Guid))
                {
                    hwInfo = GetProcessValueInfo(zoneInfo.Id);
                    infos.Add(hwInfo.AnySeqEocReached);
                    infos.Add(hwInfo.AnySeqGhostMode);
                    infos.Add(hwInfo.AnySeqSingleStep);
                    infos.Add(hwInfo.AnySeqTimeout);
                    infos.Add(hwInfo.ManualMode);
                }
            }
            return ValuesConnectionRegistration.Create(infos.ToArray());
        }

        public ValuesConnectionRegistration CreatePlantRegistration()
        {
            List<IProcessValueInfo> infos = new()
            {
                PlantProcessInfo.GlobalReset,
                PlantProcessInfo.GlobalAutomaticRelease,
                PlantProcessInfo.GlobalSequenceStepReset,
                PlantProcessInfo.LampTest
            };

            return ValuesConnectionRegistration.Create(infos.ToArray());
        }

        public ProcessValuesZoneInfo GetProcessValueInfo(ZoneId id, SequenceId seqId)
        {
            var seqInfo = GetProcessValueInfo(seqId);
            return seqInfo?.ZoneInfos.FirstOrDefault(z => z.Key.Guid.Equals(id.Guid)).Value;
        }

        public IProcessValueInfo GetProcessValueInfo(CmzId id, SequenceId seqId)
        {
            var seqInfo = GetProcessValueInfo(seqId);
            if (seqInfo == null)
                return null;

            var foundProcessValueInfo = seqInfo.Cmzs.FirstOrDefault(t => t.Key.Guid.Equals(id.Guid));
            if (foundProcessValueInfo.Value == null)
                return null;
            return foundProcessValueInfo.Value;
        }

        public IProcessValueInfo GetProcessValueInfo(CmzId id, HardwareZoneId hwId)
        {
            var hwInfo = GetProcessValueInfo(hwId);
            if (hwInfo == null)
                return null;

            var foundProcessValueInfo = hwInfo.Tcmzs.FirstOrDefault(t => t.Key.Guid.Equals(id.Guid));
            if (foundProcessValueInfo.Value == null)
                return null;
            return foundProcessValueInfo.Value;
        }

        public IProcessValueInfo GetProcessValueInfo(CmzId id, PlantId plantId)
        {
            var foundProcessValueInfo = PlantProcessInfo.Tcmzs.FirstOrDefault(t => t.Key.Guid.Equals(id.Guid));
            if (foundProcessValueInfo.Value == null)
                return null;
            return foundProcessValueInfo.Value;
        }

        private IProcessValueInfo? GetProcessValueInfo(ParameterId id, SequenceId seqId)
        {
            var seqInfo = GetProcessValueInfo(seqId);
            return seqInfo?.Parameters.First(p => p.Key.Guid.Equals(id.Guid)).Value;
        }

        private IProcessValueInfo? GetProcessValueInfo(ParameterId id, HardwareZoneId hwId)
        {
            var hwInfo = GetProcessValueInfo(hwId);
            return hwInfo?.Parameters.First(p => p.Key.Guid.Equals(id.Guid)).Value;
        }

        private IProcessValueInfo GetProcessValueInfo(ParameterId id)
        {
            return PlantProcessInfo.Parameters.FirstOrDefault(p => p.Key.Guid.Equals(id.Guid)).Value;
        }

        public ProcessValuesHardwareZone GetProcessValueInfo(HardwareZoneId id)
        {
            if (PlantProcessInfo.HardwareZones != null)
            {
                foreach (var hw in PlantProcessInfo.HardwareZones)
                {
                    if (hw.Key.Guid.Equals(id.Guid))
                    {
                        return hw.Value;
                    }
                }
            }
            return null;
        }

        public ProcessValuesSequence GetProcessValueInfo(SequenceId id)
        {
            foreach (var hw in PlantProcessInfo.HardwareZones)
            {
                if (hw.Value.Sequences != null)
                {
                    foreach (var seq in hw.Value.Sequences)
                    {
                        if (seq.Key.Guid.Equals(id.Guid))
                        {
                            return seq.Value;
                        }
                    }
                }
            }
            return null;
        }

        public ProcessValuesPlant GetProcessValueInfo()
        {
            return PlantProcessInfo;
        }

        public Dictionary<CmzId, ProcessValueId> CreateCmzLookUpTable(SelmoHmiProject project)
        {
            Dictionary<CmzId, ProcessValueId> lookupTable = new();

            project.Plants.ForEach(plant =>
            {
                lookupTable = AddPlantCmzsToLookupTable(lookupTable, plant);
                plant.HardwareZones.ForEach(hardwareZone =>
                {
                    lookupTable = AddHardwareZoneCmzsToLookupTable(lookupTable, hardwareZone);
                    hardwareZone.Sequences.ForEach(sequence =>
                    {
                        sequence.CmzCollection.Cmzs.ForEach(cmz =>
                        {
                            lookupTable = AddSequenceCmzsToLookupTable(lookupTable, sequence);
                        });
                    });
                });
            });

            return lookupTable;
        }

        private Dictionary<CmzId, ProcessValueId> AddPlantCmzsToLookupTable(Dictionary<CmzId, ProcessValueId> lookupTable,
            ProjectItemCollectionPlant plant)
        {
            plant.CmzCollection.ForEach(cmzColl =>
            {
                cmzColl.Cmzs.ForEach(cmz =>
                {
                    var processValueInfo = GetProcessValueInfo(cmz.Id, plant.PlantInfo.Id)?.Id;

                    if (processValueInfo != null && processValueInfo.HasValue)
                    {
                        lookupTable[cmz.Id] = processValueInfo.Value;
                    }
                });
            });
            return lookupTable;
        }

        private Dictionary<CmzId, ProcessValueId> AddHardwareZoneCmzsToLookupTable(Dictionary<CmzId, ProcessValueId> lookupTable,
            ProjectItemCollectionHwInfo hw)
        {
            hw.CmzCollection.ForEach(cmzColl =>
            {
                cmzColl.Cmzs.ForEach(cmz =>
                {
                    var processValueInfo = GetProcessValueInfo(cmz.Id, hw.HardwareZoneInfo.Id)?.Id;

                    if (processValueInfo != null && processValueInfo.HasValue)
                    {
                        lookupTable[cmz.Id] = processValueInfo.Value;
                    }
                });
            });
            return lookupTable;
        }

        private Dictionary<CmzId, ProcessValueId> AddSequenceCmzsToLookupTable(Dictionary<CmzId, ProcessValueId> lookupTable,
            ProjectItemCollectionSequence sequence)
        {
            sequence.CmzCollection.Cmzs.ForEach(cmz =>
            {
                var processValueInfo = GetProcessValueInfo(cmz.Id, sequence.SequenceInfo.Id)?.Id;

                if (processValueInfo != null && processValueInfo.HasValue)
                {
                    lookupTable[cmz.Id] = processValueInfo.Value;
                }
            });
            return lookupTable;
        }

        public Dictionary<ZoneId, ProcessValuesZoneInfo> GetZoneLookupTable(List<ZoneId> zoneIds, SequenceId seqId)
        {
            Dictionary<ZoneId, ProcessValuesZoneInfo> lookupTable = new();
            foreach (var id in zoneIds)
            {
                var processValueInfo = GetProcessValueInfo(id, seqId);

                if (processValueInfo != null)
                {
                    lookupTable[id] = processValueInfo;
                }
            }

            return lookupTable;
        }

        public Dictionary<HardwareZoneId, List<IProcessValueInfo>> GetLookUpTableForHwStatus(List<HardwareZoneInfoDto> hardwareZoneInfo)
        {
            Dictionary<HardwareZoneId, List<IProcessValueInfo>> lookupTable = new();
            foreach (var info in hardwareZoneInfo)
            {
                var processValueInfo = GetProcessValueInfo(info.Id);
                var infos = new List<IProcessValueInfo>();
                infos.Add(processValueInfo.AnySeqEocReached);
                infos.Add(processValueInfo.AnySeqGhostMode);
                infos.Add(processValueInfo.AnySeqSingleStep);
                infos.Add(processValueInfo.AnySeqTimeout);
                infos.Add(processValueInfo.ManualMode);
                infos.Add(processValueInfo.AnySequencesReady);
                infos.Add(processValueInfo.AllSequencesAutomaticRelease);
                infos.Add(processValueInfo.AnySeqInterlockFault);
                infos.Add(processValueInfo.AnySeqCmzFault);
                lookupTable[info.Id] = infos;
            }

            return lookupTable;
        }

        public ValuesConnectionRegistration CreateSeqStatusRegistration(List<ProjectItemCollectionSequence> sequences)
        {
            List<IProcessValueInfo> infos = new();
            foreach (var seqInfo in sequences)
            {
                var processValueInfo = GetProcessValueInfo(seqInfo.SequenceInfo.Id);
                infos.Add(processValueInfo.Status.AutomaticReleased);
                infos.Add(processValueInfo.Status.AutomaticModeSelected);
                infos.Add(processValueInfo.Status.InterlockFault);
                infos.Add(processValueInfo.Status.NoCmzFault);
                infos.Add(processValueInfo.Status.ManualReleased);
                infos.Add(processValueInfo.Status.GhostModeOutput);
                infos.Add(processValueInfo.TriggerSingleStepOn);
                infos.Add(processValueInfo.Status.StepTimeout);
                infos.Add(processValueInfo.Status.EocReached);
            }
            return ValuesConnectionRegistration.Create(infos.ToArray());
        }

        public Dictionary<SequenceId, ProcessValuesSequenceStatus> GetLookUpTableForSeqStatus(
            List<ProjectItemCollectionSequence> projectItemCollectionSequences)
        {
            Dictionary<SequenceId, ProcessValuesSequenceStatus> lookupTable = new();
            foreach (var info in projectItemCollectionSequences)
            {
                var processValueInfo = GetProcessValueInfo(info.SequenceInfo.Id);
                lookupTable[info.SequenceInfo.Id] = processValueInfo.Status;
            }

            return lookupTable;
        }

        public ValuesConnectionRegistration CreateSeqOverviewRegistration(List<SequenceInfoDto> sequenceInfos)
        {
            List<IProcessValueInfo> infos = new();
            foreach (var seqInfo in sequenceInfos)
            {
                var processValueInfo = GetProcessValueInfo(seqInfo.Id);
                infos.Add(processValueInfo.Status.AutomaticModeSelected);
                infos.Add(processValueInfo.Status.AutomaticReleased);
                infos.Add(processValueInfo.Status.InterlockFault);
                infos.Add(processValueInfo.Status.NoCmzFault);
                infos.Add(processValueInfo.Status.ManualReleased);
                infos.Add(processValueInfo.Status.GhostModeOutput);
                infos.Add(processValueInfo.TriggerSingleStepOn);
                infos.Add(processValueInfo.Status.StepTimeout);
                infos.Add(processValueInfo.Status.EocReached);
                infos.Add(processValueInfo.Status.StepCount);
            }
            return ValuesConnectionRegistration.Create(infos.ToArray());
        }

        public Dictionary<SequenceId, List<IProcessValueInfo>> GetLookUpTableForSeqOverview(List<SequenceInfoDto> sequenceInfos)
        {
            Dictionary<SequenceId, List<IProcessValueInfo>> lookupTable = new();
            foreach (var info in sequenceInfos)
            {
                var processValueInfo = GetProcessValueInfo(info.Id);
                var infos = new List<IProcessValueInfo>();
                infos.Add(processValueInfo.Status.AutomaticModeSelected);
                infos.Add(processValueInfo.Status.AutomaticReleased);
                infos.Add(processValueInfo.Status.InterlockFault);
                infos.Add(processValueInfo.Status.NoCmzFault);
                infos.Add(processValueInfo.Status.ManualReleased);
                infos.Add(processValueInfo.Status.GhostModeOutput);
                infos.Add(processValueInfo.TriggerSingleStepOn);
                infos.Add(processValueInfo.Status.StepTimeout);
                infos.Add(processValueInfo.Status.EocReached);
                infos.Add(processValueInfo.Status.StepCount);
                lookupTable[info.Id] = infos;
            }

            return lookupTable;
        }

        public Dictionary<SequenceId, ProcessValuesSequence> GetProcessValueInfoLookUpTableOverview(List<SequenceInfoDto> sequenceInfos)
        {
            Dictionary<SequenceId, ProcessValuesSequence> lookupTable = new();

            foreach (var info in sequenceInfos)
            {
                var seqInfo = GetProcessValueInfo(info.Id);
                if (seqInfo != null)
                {
                    lookupTable[info.Id] = seqInfo;
                }
            }

            return lookupTable;
        }

        public Dictionary<StepId, List<IProcessValue>> GetProcessValueLookUpMonitoringSteps(SequenceId id)
        {
            Dictionary<StepId, List<IProcessValue>> lookupTable = new();
            var seqInfo = GetProcessValueInfo(id);
            foreach (var monitoringStep in seqInfo.MonitoringSteps)
            {
                var steps = new List<IProcessValue>();
                steps.Add(new TestValuesForDemo.TestProcessValue()
                {
                    Value = 0,
                    ValueInfo = monitoringStep.Value.TimeAvg
                });
                steps.Add(new TestValuesForDemo.TestProcessValue()
                {
                    Value = 0,
                    ValueInfo = monitoringStep.Value.TimeLast
                });
                steps.Add(new TestValuesForDemo.TestProcessValue()
                {
                    Value = 0,
                    ValueInfo = monitoringStep.Value.TimeMin
                });
                steps.Add(new TestValuesForDemo.TestProcessValue()
                {
                    Value = 0,
                    ValueInfo = monitoringStep.Value.TimeMax
                });
                steps.Add(new TestValuesForDemo.TestProcessValue()
                {
                    Value = 0,
                    ValueInfo = monitoringStep.Value.TimeoutAdd
                });
                steps.Add(new TestValuesForDemo.TestProcessValue()
                {
                    Value = 0,
                    ValueInfo = monitoringStep.Value.TimeoutCount
                });
                steps.Add(new TestValuesForDemo.TestProcessValue()
                {
                    Value = false,
                    ValueInfo = monitoringStep.Value.TimeoutDisabled
                });
                steps.Add(new TestValuesForDemo.TestProcessValue()
                {
                    Value = 0,
                    ValueInfo = monitoringStep.Value.TimeoutSet
                });
                steps.Add(new TestValuesForDemo.TestProcessValue()
                {
                    Value = 0,
                    ValueInfo = monitoringStep.Value.ActualTime
                });
                lookupTable.Add(new(monitoringStep.Key.Guid), steps);
            }
            return lookupTable;
        }

        public Dictionary<StepId, ProcessValueMonitoringStep> GetProcessValueInfoLookUpMonitoringSteps(SequenceId id)
        {
            Dictionary<StepId, ProcessValueMonitoringStep> lookupTable = new();
            var seqInfo = GetProcessValueInfo(id);
            foreach (var monitoringStep in seqInfo.MonitoringSteps)
            {
                lookupTable.Add(new(monitoringStep.Key.Guid), monitoringStep.Value);
            }
            return lookupTable;
        }

        public IProcessValue GetTeachMode(SequenceId id)
        {
            var seqInfo = GetProcessValueInfo(id);
            if (seqInfo != null)
            {
                return new TestValuesForDemo.TestProcessValue()
                {
                    Value = false,
                    ValueInfo = seqInfo.Status.TeachMode
                };
            }
            return null;
        }
    }
}