using Admin.Core.Common;
using Aucma.Core.HwPLc;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using System.Collections.Generic;
using System.Timers;

namespace Aucma.Core.RunPlc
{
    /// <summary>
    /// PLC任务
    /// </summary>
    public class RunPlcService : IRunPlcService
    {
        #region 构造函数
        public RunPlcService()
        {

        }
        #endregion

        public async Task StartMelsecMcSeverAsync()
        {
            await Task.Run(async () =>
            {
                await StartMelsecMcPlcServer();
            });

        }
        public async Task StartSiemensSever()
        {
            //await Task.Run(async () =>
            //{
            //    await StartSiemensPlcServer();
            //});
            await StartSiemensPlcServer();
        }
        #region 心跳
        public async Task StartMelsecPlcAsync()
        {
                System.Timers.Timer timer = new System.Timers.Timer(3000);
                timer.Elapsed += new System.Timers.ElapsedEventHandler(ExecMelsecMcHeartTask);  //到达时间的时候执行事件;
                timer.AutoReset = true;//设置是执行一次(false)还是一直执行(true); 
                timer.Enabled = true;//需要调用 timer.Start()或者timer.Enabled = true来启动它,
                timer.Start();//timer.Start()的内部原理还是设置timer.Enabled = true;
                await Task.CompletedTask;
        }
        public async Task StartSiemensPlcAsync()
        {
                System.Timers.Timer timer = new System.Timers.Timer(3000);//创建定时器,设置间隔时间为1000毫秒
                timer.Elapsed += new System.Timers.ElapsedEventHandler(ExecSiemensHeartTask);
                timer.AutoReset = true;//设置是执行一次(false)还是一直执行(true); 
                timer.Enabled = true;//需要调用 timer.Start()或者timer.Enabled = true来启动它,
                timer.Start();//timer.Start()的内部原理还是设置timer.Enabled = true;
                await Task.CompletedTask;
     
        }
        private static async Task StartMelsecMcPlcServer()
        {
            var allPlcServices = Appsettings.app<PlcModel>("PLCServer").ToList();
            if (allPlcServices == null) return;
            var list = allPlcServices.FindAll(d => d.PlcType == "Melsec" && d.Enabled == true);

            for (int i = 1; i <= list.Count; i++)
            {
                PlcModel model = new PlcModel();
                model.Id = list[i - 1].Id;
                model.EquipName = list[i - 1].EquipName;
                model.IP = list[i - 1].IP;
                model.Port = list[i - 1].Port;
                model.PlcType = list[i - 1].PlcType;
                model.plc = new MelsecPlc(list[i - 1].IP, list[i - 1].Port);
                PlcHelper.melsecList.Add(model);
            }
            await Task.CompletedTask;
        }

        private static async Task StartSiemensPlcServer()
        {
            List<PlcModel> allPlcServices = Appsettings.app<PlcModel>("PLCServer").ToList();
            if (allPlcServices == null) return;
            var list = allPlcServices.FindAll(d => d.PlcType == "Siemens" && d.Enabled == true);

            foreach (var item in list)
            {
                PlcModel model = new PlcModel();
                model.Id = item.Id;
                model.EquipName = item.EquipName;
                model.IP = item.IP;
                model.Port = item.Port;
                model.PlcType = item.PlcType;
                model.plc = new SiemensPlc(item.IP, item.Port);
                PlcHelper.siemensList.Add(model);
            }
            await Task.CompletedTask;
        }
        #endregion

        #region 心跳检测
        private async void ExecMelsecMcHeartTask(object? sender, ElapsedEventArgs e)
        {
            int num = PlcHelper.melsecList.Count;
            if (num == 0) return;
            for (int i = 1; i <= num; i++)
            {
                var item = PlcHelper.melsecList.Where(c => c.Id == i).FirstOrDefault();
                if (item == null) continue;
                var test = item.plc.ReadInt16("D6050");
                if (item.plc.Read("M100").Result)
                {
                    item.IsConnect = true;
                    item.plc.IsConnected = true;
                    //Console.WriteLine(item.melsecPlc.ReadBool("M100"));
                    //Console.WriteLine($"{item.EquipName}:PLC连接成功!");
                }
                else
                {
                    if (item.plc.IsConnected == false)
                    {
                        item.IsConnect = false;
                        //Console.WriteLine($"{item.EquipName}:PLC连接失败!");
                        //    System.GC.Collect();
                        bool r = item.plc.Connect(item.IP, item.Port);
                        if (r)
                        {
                            item.plc.IsConnected = r;
                            item.IsConnect = r;
                        }
                        else
                        {
                            item.plc.IsConnected = r;
                            item.IsConnect = r;
                        }
                    }
                }
            }
            await Task.CompletedTask;
        }
        private async void ExecSiemensHeartTask(object? sender, ElapsedEventArgs e)
        {
            int num = PlcHelper.siemensList.Count;
            if (num == 0) return;
            for (int i = 1; i <= num; i++)
            {
                var item = PlcHelper.siemensList.Where(c => c.Id == i).FirstOrDefault();
                if (item == null) continue;

                if (await item.plc.Read("M100"))
                {
                    item.IsConnect = true;
                    item.plc.IsConnected = true;
                    //Console.WriteLine(item.melsecPlc.ReadBool("M100"));
                    //Console.WriteLine($"{item.EquipName}:PLC连接成功!");
                }
                else
                {
                    if (item.plc.IsConnected == false)
                    {
                        item.IsConnect = false;
                        //Console.WriteLine($"{item.EquipName}:PLC连接失败!");
                        System.GC.Collect();
                        bool r = item.plc.Connect(item.IP, item.Port);
                        if (r)
                        {
                            item.plc.IsConnected = r;
                            item.IsConnect = r;
                        }
                        else
                        {
                            item.plc.IsConnected = r;
                            item.plc.DisConnect();
                        }
                    }
                }
            }
        }
        #endregion
    }
}