using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using HBLConsole.Model;
using HBLConsole.Factory;
using HBLConsole.Attributes;
using System.Reflection;
using HBLConsole.Service;
using System.Threading;

namespace HBLConsole.ViewModel
{
    public class VariableMonitorViewModel : ViewModelBase
    {
        public VariableMonitorViewModel()
        {
            WindowName = "变量监控";
        }

        static VariableMonitorViewModel()
        {
            AddMonitorData();
            UpdateValue();
        }

        private static void AddMonitorData()
        {
            if (SimpleFactory.GetInstance.GVL == null) return;
            foreach (var item in SimpleFactory.GetInstance.GVL.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(SimpleFactory.GetInstance.GVL, null);
                            if (arrayRes != null && arrayRes is Array arr)
                            {
                                for (int i = 0; i < arr.Length; i++)
                                {
                                    var res = VariableMonitors.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]}";
                                        }

                                        VariableMonitors.Add(new VariableMonitor()
                                        {
                                            Id = VariableMonitors.Count,
                                            VarName = $"{item.Name}_{i + 1}",
                                            Notes = $"{notes}_{i + 1}",
                                            ModbusTcpAddress = $"{int.Parse(modadd) + i}",
                                            PLCAddress = TempPlcAddress,

                                        });
                                    }
                                }
                            }
                        }
                        else
                        {
                            var arrayRes = item.GetValue(SimpleFactory.GetInstance.GVL, null);
                            if (arrayRes != null && arrayRes is Array arr)
                            {
                                for (int i = 0; i < arr.Length; i++)
                                {
                                    var res = VariableMonitors.FirstOrDefault(p => p.VarName == $"{item.Name}_{i + 1}");
                                    if (res == null)
                                    {
                                        VariableMonitors.Add(new VariableMonitor()
                                        {
                                            Id = VariableMonitors.Count,
                                            VarName = $"{item.Name}_{i + 1}",
                                            Notes = $"{notes}_{i + 1}",

                                        });
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        var res = VariableMonitors.FirstOrDefault(p => p.VarName == item.Name);
                        if (res == null)
                        {
                            VariableMonitors.Add(new VariableMonitor()
                            {
                                Id = VariableMonitors.Count,
                                VarName = item.Name,
                                Notes = notes,
                                ModbusTcpAddress = modadd,
                                PLCAddress = plcadd,

                            });
                        }
                    }

                }
            }
        }

        private static void UpdateValue()
        {
            if (SimpleFactory.GetInstance.GVL == null) return;
            ThreadManage.GetInstance.StartLong(new Action(() =>
            {
                foreach (var item in SimpleFactory.GetInstance.GVL.GetType().GetProperties())
                {
                    if (item.CustomAttributes.Count() > 0)
                    {
                        if (item.PropertyType?.BaseType?.Name == "Array")
                        {
                            var arrayRes = item.GetValue(SimpleFactory.GetInstance.GVL);
                            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)
                                    {
                                        App.Current.Dispatcher.Invoke(new Action(() =>
                                        {
                                            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)
                            {
                                App.Current.Dispatcher.Invoke(new Action(() =>
                                {
                                    VariableMonitors.ElementAt(index).CurrentValue = item.GetValue(SimpleFactory.GetInstance.GVL)?.ToString();
                                }));
                            }
                        }

                    }
                }
                Thread.Sleep(1000);
            }), "变量监控");
        }


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

    }
}
