using BPA.Model.Attributes;
using BPA.SingleDevice.Interface;
using System.Reflection;

namespace BPA.SingleDevice.ViewModel
{
    public class VarMonitorViewModel : NotifyBase
    {
        private readonly GlobalData global;

        public VarMonitorViewModel(GlobalData global)
        {
            this.global = global;
            GetMonitorData(global);

            TaskManage.GetInstance.StartLong(() =>
            {
                UpdateValue(global);
                Task.Delay(100).Wait();
            }, "UpdateValue", true);
        }

        public ObservableCollection<VariableMonitor> VariableMonitors { get; set; } = new ObservableCollection<VariableMonitor>();

        /// <summary>获取监控信息</summary>
        private void GetMonitorData(IStatus status)
        {
            if (status == null)
                return;
            List<VariableMonitor> vm = new List<VariableMonitor>();
            foreach (var item in status.GetType().GetProperties())
            {
                if (item.CustomAttributes.Count() > 0)
                {
                    var attributeName = item.CustomAttributes.FirstOrDefault(p => p.AttributeType.Name == "VariableMonitorAttribute");
                    if (attributeName == null)
                        return;
                    var plcadd = item.GetCustomAttribute<VariableMonitorAttribute>()?.PLCAddress;
                    var modadd = item.GetCustomAttribute<VariableMonitorAttribute>()?.ModbusTcpAddress;
                    var notes = item.GetCustomAttribute<VariableMonitorAttribute>()?.Notes;

                    if (item.PropertyType?.BaseType?.Name == "Array")
                    {
                        if (plcadd?.Length > 0)
                        {
                            var arrayRes = item.GetValue(status, null);
                            if (arrayRes != null && arrayRes is Array arr)
                            {
                                for (int i = 0; i < arr.Length; i++)
                                {
                                    var res = vm.FirstOrDefault(p => p.VarName == $"{item.Name}_{i + 1}");
                                    if (res == null)
                                    {
                                        string[] plc = plcadd?.Substring(1).Split('.');
                                        string TempPlcAddress = string.Empty;
                                        if (plc?.Length == 2)
                                        {
                                            int add = int.Parse(plc[1]);
                                            int firstAdd = int.Parse(plc[0]);
                                            if (add >= 0 && add < 7)
                                            {
                                                add += i;
                                            }
                                            else if (add >= 7)
                                            {
                                                add = 0;
                                                firstAdd++;
                                            }
                                            plc[0] = firstAdd.ToString();
                                            plc[1] = add.ToString();
                                            TempPlcAddress = $"M{plc[0]}.{plc[1]}";
                                        }

                                        vm.Add(new VariableMonitor()
                                        {
                                            Id = vm.Count + 1,
                                            VarName = $"{item.Name}_{i + 1}",
                                            Notes = $"{notes}_{i + 1}",
                                            ModbusTcpAddress = $"{int.Parse(modadd) + i}",
                                            PLCAddress = TempPlcAddress,
                                        });
                                    }
                                }
                            }
                        }
                        else
                        {
                            var arrayRes = item.GetValue(status, null);
                            if (arrayRes != null && arrayRes is Array arr)
                            {
                                for (int i = 0; i < arr.Length; i++)
                                {
                                    var res = vm.FirstOrDefault(p => p.VarName == $"{item.Name}_{i + 1}");
                                    if (res == null)
                                    {
                                        vm.Add(new VariableMonitor()
                                        {
                                            Id = vm.Count + 1,
                                            VarName = $"{item.Name}_{i + 1}",
                                            Notes = $"{notes}_{i + 1}",
                                        });
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        var res = vm.FirstOrDefault(p => p.VarName == item.Name);
                        if (res == null)
                        {
                            vm.Add(new VariableMonitor()
                            {
                                Id = vm.Count + 1,
                                VarName = item.Name,
                                Notes = notes,
                                ModbusTcpAddress = modadd,
                                PLCAddress = plcadd,
                            });
                        }
                    }
                }
            }

            vm.ForEach(item => { VariableMonitors.Add(item); });
        }

        public void UpdateValue(IStatus status)
        {
            if (status == null)
                return;
            foreach (var item in status.GetType().GetProperties())
            {
                if (item.CustomAttributes.Count() > 0)
                {
                    if (item.PropertyType?.BaseType?.Name == "Array")
                    {
                        var arrayRes = item.GetValue(status);
                        if (arrayRes != null && arrayRes is Array arr)
                        {
                            for (int i = 0; i < arr.Length; i++)
                            {
                                int index = Array.FindIndex(VariableMonitors.ToArray(), p => p.VarName == $"{item.Name}_{i + 1}");
                                if (index >= 0 && index < VariableMonitors.Count)
                                {
                                    VariableMonitors.ElementAt(index).CurrentValue = arr.GetValue(i)?.ToString();
                                }
                            }
                        }
                    }
                    else
                    {
                        int index = Array.FindIndex(VariableMonitors.ToArray(), p => p.VarName == item.Name);
                        if (index >= 0 && index < VariableMonitors.Count)
                        {
                            VariableMonitors.ElementAt(index).CurrentValue = item.GetValue(status)?.ToString();
                        }
                    }
                }
            }
        }
    }
}