using Khd.Core.Domain.Dto.webapi;
using Khd.Core.Domain.Models;
using Khd.Core.EntityFramework;
using Khd.Core.Library;
using Khd.Core.Library.Mapper;
using Khd.Core.Plc.S7;
using Khd.Core.Wcs.Global;
using Masuit.Tools;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using Z.EntityFramework.Plus;

namespace Khd.Core.Wcs.Wcs
{
    public class SystemTimer
    {
        private readonly LoggerUtils _logger = new();
        private readonly IHost host;

        public SystemTimer(IHost host)
        {
            this.host = host;
        }

        public void Start()
        {
            var messageSynchronousThread = new Thread(MessageSynchronousLogic)
            {
                Name = "MessageSynchronousThread",
                IsBackground = true
            };
            messageSynchronousThread.Start();//陈工设备信息推送

            var PlcHeartBeat30Thread = new Thread(PlcHeartBeat30Logic)
            {
                Name = "PlcHeartBeat30Thread",
                IsBackground = true
            };
            PlcHeartBeat30Thread.Start();//脉冲

            var PlcHeartBeat31Thread = new Thread(PlcHeartBeat31Logic)
            {
                Name = "PlcHeartBeat31Thread",
                IsBackground = true
            };
            PlcHeartBeat31Thread.Start();//脉冲

            var PlcHearBeat220Thread = new Thread(PlcHearBeat220Logic)
            {
                Name = "PlcHeartBeat220Thread",
                IsBackground = true
            };
            PlcHearBeat220Thread.Start();

            var deleteTaskThread = new Thread(DeleteTaskLogic)
            {
                Name = "DeleteTaskThread",
                IsBackground = true
            };
            deleteTaskThread.Start();

            var deleteLogsThread = new Thread(DeleteLogsLogic)
            {
                Name = "DeleteLogsThread",
                IsBackground = true
            };
            deleteLogsThread.Start();

            //var AgvAlarmThread = new Thread(AgvAlarmLogic)
            //{
            //    Name = "AgvAlarmThread",
            //    IsBackground = true
            //};
            //AgvAlarmThread.Start();
            Console.WriteLine($"{DateTime.Now}: SystemTimer started");
        }

        private void AgvAlarmLogic()
        {
            using var scope = host.Services.CreateScope();
            using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
            while (true)
            {
                using var transaction = dbContext.Database.BeginTransaction();
                try
                {
                    dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                    var dmsBaseDeviceLedgers = dbContext.DmsBaseDeviceLedger.ToList();
                    var wcsAgvStatuses = dbContext.WcsAgvStatus.ToList();
                    var agvStatus = from a in dmsBaseDeviceLedgers
                                    from b in wcsAgvStatuses
                                    where a.DeviceCode == b.RobotCode
                                    select new
                                    {
                                        a.DeviceId,
                                        b.Online,
                                        b.Status
                                    };
                    foreach (var item in agvStatus)
                    {
                        //var dmsBaseAlarmRule = StaticData.DmsBaseAlarmRuleList.Where(t => t.Status == item.Status).FirstOrDefault();
                        var dmsBaseAlarmRule = StaticData.DmsBaseAlarmRuleList.FirstOrDefault();
                        if (dmsBaseAlarmRule != null)
                        {
                            DmsRecordAlarmTime alarmTime = new DmsRecordAlarmTime
                            {
                                AlarmBeginTime = DateTime.Now,
                                AlarmReason = dmsBaseAlarmRule.AlarmReason,
                                HandleSuggest = dmsBaseAlarmRule.HandleSuggest,
                                AlarmRuleId = dmsBaseAlarmRule.AlarmRuleId,
                                ContinueTime = dmsBaseAlarmRule.ContinueTime,
                                CreateBy = "WCS",
                                CreateTime = DateTime.Now,
                                DeviceId = item.DeviceId,
                            };
                            var dmsRecordAlarmInfo = CoreMapper.Map<DmsRecordAlarmInfo>(alarmTime);
                            dmsRecordAlarmInfo.AlarmStatus = "0";
                            dmsRecordAlarmInfo.NoticeStatus = "0";
                            dbContext.Add(dmsRecordAlarmInfo);
                            dbContext.SaveChanges();
                            transaction.Commit();
                        }
                        else
                        {
                            var alarmTime = dbContext.DmsRecordAlarmTime
                                .Where(t => t.CreateBy == "WCS")
                                .Where(t => t.DeviceId == item.DeviceId)
                                .FirstOrDefault();
                            if (alarmTime != null)
                            {
                                dbContext.Remove(alarmTime);
                                dbContext.DmsRecordAlarmInfo
                                    .Where(t => t.AlarmId == alarmTime.AlarmId)
                                    .Update(t => new DmsRecordAlarmInfo
                                    {
                                        AlarmEndTime = DateTime.Now,
                                        UpdateBy = "WCS",
                                        UpdateTime = DateTime.Now
                                    });
                                dbContext.SaveChanges();
                                transaction.Commit();
                            }
                        }
                    }
                }
                catch
                {
                    try
                    {
                        transaction.Rollback();
                    }
                    catch
                    {

                    }
                }
                Thread.Sleep(3000);
            }
        }

        /// <summary>
        /// 定时清除日志文件
        /// </summary>
        private void DeleteLogsLogic()
        {
            while (true)
            {
                try
                {
                    //获取当前程序运行目录下的logs文件夹
                    string logPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs");
                    string[] strings = Directory.GetDirectories(logPath);
                    foreach (string s in strings)
                    {
                        string? dirName = Path.GetFileName(s);
                        if (dirName != null)
                        {
                            if (DateTime.TryParse(dirName, out DateTime dt))
                            {
                                if (dt < DateTime.Now.AddDays(-StaticData.DeleteLogDay))
                                {
                                    Directory.Delete(s, true);
                                    _logger.Info($"日志{dirName}已删除");
                                }
                            }
                        }
                    }

                }
                catch
                {

                }
                Thread.Sleep(1000 * 60 * 60 * 23);
            }
        }

        /// <summary>
        /// 删除任务
        /// </summary>
        private void DeleteTaskLogic()
        {
            using var scope = host.Services.CreateScope();
            using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
            while (true)
            {
                try
                {
                    dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                    List<WcsTask> wcsTasks = dbContext.WcsTask.Where(t => t.IsDelete == 1).ToList();
                    foreach (var item in wcsTasks)
                    {
                        BaseEquip agvEquip = StaticData.BaseEquip.First(t => t.objid == item.nextPointId);
                        if (!string.IsNullOrEmpty(item.taskCode) && !string.IsNullOrEmpty(agvEquip.serverIp))
                        {
                            if (item.endPointId == 11)
                            {
                                dbContext.WcsTask.Remove(item);
                                if (item.taskStatus == 6)
                                {
                                    dbContext.SaveChanges();
                                }
                                else
                                {
                                    var cancelTask = new
                                    {
                                        reqCode = StaticData.SnowId.NextId().ToString(),
                                        taskCode = item.taskCode
                                    };
                                    string reponse = HttpHelper.SendPostMessage(agvEquip.serverIp, agvEquip.serverPort.Value, "rcms/services/rest/hikRpcService/cancelTask", cancelTask.ToJsonString());
                                    var result = JsonConvert.DeserializeObject<ReponseMessage>(reponse);
                                    if (result != null && result.code == "0")
                                    {
                                        dbContext.SaveChanges();
                                        _logger.Info($"任务{item.taskCode}已删除");
                                    }
                                    else
                                    {
                                        _logger.Error($"任务{item.taskCode}删除失败，原因：{result?.message}");
                                    }
                                }
                            }
                            else
                            {
                                dbContext.WcsTask.Remove(item);
                                var cancelTask = new
                                {
                                    reqCode = StaticData.SnowId.NextId().ToString(),
                                    taskCode = item.taskCode
                                };
                                string reponse = HttpHelper.SendPostMessage(agvEquip.serverIp, agvEquip.serverPort.Value, "rcms/services/rest/hikRpcService/cancelTask", cancelTask.ToJsonString());
                                var result = JsonConvert.DeserializeObject<ReponseMessage>(reponse);
                                if (result != null && result.code == "0")
                                {
                                    dbContext.SaveChanges();
                                    _logger.Info($"任务{item.taskCode}已删除");
                                }
                                else
                                {
                                    _logger.Error($"任务{item.taskCode}删除失败，原因：{result?.message}");
                                }
                            }
                        }
                        else
                        {
                            dbContext.WcsTask.Remove(item);
                            dbContext.SaveChanges();
                            _logger.Info($"任务{item.objid}已删除");
                        }
                    }
                }
                catch
                {

                }
                Thread.Sleep(1000);
            }
        }

        /// <summary>
        /// 定时发送心跳包
        /// </summary>
        private void PlcHearBeat220Logic()
        {
            using var scope = host.Services.CreateScope();
            using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
            BasePlcpoint HeartBeat30 = StaticData.BasePlcpointList.First(t => t.plcpointNo == "putTray");
            int errorCount = 0;
            while (true)
            {
                try
                {
                    if (errorCount > 20)
                    {
                        _logger.Error($"Plc220短线重连失败超过{errorCount}次");
                        dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                        var dmsRecordAlarmTime = dbContext.DmsRecordAlarmTime.Where(t => t.CreateBy == "WCS" && t.DeviceId == 15).FirstOrDefault();
                        if (dmsRecordAlarmTime == null)
                        {
                            var alarmTime = new DmsRecordAlarmTime
                            {
                                DeviceId = 15,
                                AlarmBeginTime = DateTime.Now,
                                AlarmReason = "Plc220短线重连失败",
                                HandleSuggest = "检查Plc220网络连接",
                                AlarmRuleId = 4,
                                ContinueTime = 10000,
                                CreateBy = "WCS",
                                CreateTime = DateTime.Now,
                            };
                            var dmsRecordAlarmInfo = CoreMapper.Map<DmsRecordAlarmInfo>(alarmTime);
                            dmsRecordAlarmInfo.AlarmStatus = "0";
                            dmsRecordAlarmInfo.NoticeStatus = "0";
                            dbContext.Add(dmsRecordAlarmInfo);
                            dbContext.SaveChanges();
                        }
                    }
                    StaticData.PlcDic[2].Read(HeartBeat30.plcpointAddress);
                    if (errorCount > 0)
                    {
                        dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                        var dmsRecordAlarmTime = dbContext.DmsRecordAlarmTime.Where(t => t.CreateBy == "WCS" && t.DeviceId == 15).FirstOrDefault();
                        if (dmsRecordAlarmTime != null)
                        {
                            dbContext.DmsRecordAlarmTime.Remove(dmsRecordAlarmTime);
                            dbContext.DmsRecordAlarmInfo.Where(t => t.AlarmId == dmsRecordAlarmTime.AlarmId).Update(t => new DmsRecordAlarmInfo
                            {
                                AlarmEndTime = DateTime.Now,
                                AlarmStatus = "1",
                                UpdateBy = "WCS",
                                UpdateTime = DateTime.Now
                            });
                            dbContext.SaveChanges();
                            errorCount = 0;
                        }
                    }
                }
                catch
                {
                    try
                    {
                        StaticData.PlcDic[2] = new Plc.S7.Plc(StaticData.PlcDic[2].CPU, StaticData.PlcDic[2].IP, StaticData.PlcDic[2].Port, StaticData.PlcDic[2].Rack, StaticData.PlcDic[2].Slot);
                        StaticData.PlcDic[2].Open();
                    }
                    catch (Exception ex2)
                    {
                        errorCount++;
                        _logger.Error("Plc短线重连失败" + ex2.Message);
                    }
                }
                Thread.Sleep(1000);
            }
        }

        /// <summary>
        /// 定时发送心跳包
        /// </summary>
        private void PlcHeartBeat30Logic()
        {
            using var scope = host.Services.CreateScope();
            using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
            BasePlcpoint HeartBeat30 = StaticData.BasePlcpointList.First(t => t.plcpointNo == "HeartBeat30");
            bool heartBeatCount = false;
            int errorCount = 0;
            while (true)
            {
                try
                {
                    if (errorCount > 20)
                    {
                        _logger.Error($"Plc30短线重连失败超过{errorCount}次");
                        dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                        var dmsRecordAlarmTime = dbContext.DmsRecordAlarmTime.Where(t => t.CreateBy == "WCS" && t.DeviceId == 13).FirstOrDefault();
                        if (dmsRecordAlarmTime == null)
                        {
                            var alarmTime = new DmsRecordAlarmTime
                            {
                                DeviceId = 13,
                                AlarmBeginTime = DateTime.Now,
                                AlarmReason = "Plc30短线重连失败",
                                HandleSuggest = "检查Plc30网络连接",
                                AlarmRuleId = 4,
                                ContinueTime = 10000,
                                CreateBy = "WCS",
                                CreateTime = DateTime.Now,
                            };
                            var dmsRecordAlarmInfo = CoreMapper.Map<DmsRecordAlarmInfo>(alarmTime);
                            dmsRecordAlarmInfo.AlarmStatus = "0";
                            dmsRecordAlarmInfo.NoticeStatus = "0";
                            dbContext.Add(dmsRecordAlarmInfo);
                            dbContext.SaveChanges();
                        }
                    }
                    heartBeatCount = !heartBeatCount;
                    StaticData.PlcDic[0].WriteToPoint(HeartBeat30.plcpointAddress, heartBeatCount, HeartBeat30.plcpointLength?.ToString());
                    if (errorCount > 0)
                    {
                        dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                        var dmsRecordAlarmTime = dbContext.DmsRecordAlarmTime.Where(t => t.CreateBy == "WCS" && t.DeviceId == 13).FirstOrDefault();
                        if (dmsRecordAlarmTime != null)
                        {
                            dbContext.DmsRecordAlarmTime.Remove(dmsRecordAlarmTime);
                            dbContext.DmsRecordAlarmInfo.Where(t => t.AlarmId == dmsRecordAlarmTime.AlarmId).Update(t => new DmsRecordAlarmInfo
                            {
                                AlarmEndTime = DateTime.Now,
                                AlarmStatus = "1",
                                UpdateBy = "WCS",
                                UpdateTime = DateTime.Now
                            });
                            dbContext.SaveChanges();
                            errorCount = 0;
                        }
                    }
                }
                catch
                {
                    try
                    {
                        StaticData.PlcDic[0] = new Plc.S7.Plc(StaticData.PlcDic[0].CPU, StaticData.PlcDic[0].IP, StaticData.PlcDic[0].Port, StaticData.PlcDic[0].Rack, StaticData.PlcDic[0].Slot);
                        StaticData.PlcDic[0].Open();
                    }
                    catch (Exception ex2)
                    {
                        errorCount++;
                        _logger.Error("Plc短线重连失败" + ex2.Message);
                    }
                }
                Thread.Sleep(1000);
            }
        }

        /// <summary>
        /// 定时发送心跳包
        /// </summary>
        private void PlcHeartBeat31Logic()
        {
            using var scope = host.Services.CreateScope();
            using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
            BasePlcpoint HeartBeat31 = StaticData.BasePlcpointList.First(t => t.plcpointNo == "CTUHeart");
            bool heartBeatCount = false;
            int errorCount = 0;
            while (true)
            {
                try
                {
                    if (errorCount > 20)
                    {
                        _logger.Error($"Plc31短线重连失败超过{errorCount}次");
                        dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                        var dmsRecordAlarmTime = dbContext.DmsRecordAlarmTime.Where(t => t.CreateBy == "WCS" && t.DeviceId == 14).FirstOrDefault();
                        if (dmsRecordAlarmTime == null)
                        {
                            var alarmTime = new DmsRecordAlarmTime
                            {
                                DeviceId = 14,
                                AlarmBeginTime = DateTime.Now,
                                AlarmReason = "Plc31短线重连失败",
                                HandleSuggest = "检查Plc31网络连接",
                                AlarmRuleId = 4,
                                ContinueTime = 10000,
                                CreateBy = "WCS",
                                CreateTime = DateTime.Now,
                            };
                            var dmsRecordAlarmInfo = CoreMapper.Map<DmsRecordAlarmInfo>(alarmTime);
                            dmsRecordAlarmInfo.AlarmStatus = "0";
                            dmsRecordAlarmInfo.NoticeStatus = "0";
                            dbContext.Add(dmsRecordAlarmInfo);
                            dbContext.SaveChanges();
                        }
                    }
                    heartBeatCount = !heartBeatCount;
                    StaticData.PlcDic[1].WriteToPoint(HeartBeat31.plcpointAddress, heartBeatCount, HeartBeat31.plcpointLength?.ToString());
                    if (errorCount > 0)
                    {
                        dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                        var dmsRecordAlarmTime = dbContext.DmsRecordAlarmTime.Where(t => t.CreateBy == "WCS" && t.DeviceId == 14).FirstOrDefault();
                        if (dmsRecordAlarmTime != null)
                        {
                            dbContext.DmsRecordAlarmTime.Remove(dmsRecordAlarmTime);
                            dbContext.DmsRecordAlarmInfo.Where(t => t.AlarmId == dmsRecordAlarmTime.AlarmId).Update(t => new DmsRecordAlarmInfo
                            {
                                AlarmEndTime = DateTime.Now,
                                AlarmStatus = "1",
                                UpdateBy = "WCS",
                                UpdateTime = DateTime.Now
                            });
                            dbContext.SaveChanges();
                            errorCount = 0;
                        }
                    }
                }
                catch (Exception ex)
                {
                    if (ex is PlcException)
                    {
                        try
                        {
                            StaticData.PlcDic[1] = new Plc.S7.Plc(StaticData.PlcDic[1].CPU, StaticData.PlcDic[1].IP, StaticData.PlcDic[1].Port, StaticData.PlcDic[1].Rack, StaticData.PlcDic[1].Slot);
                            StaticData.PlcDic[1].Open();
                        }
                        catch (Exception ex2)
                        {
                            errorCount++;
                            _logger.Error("Plc短线重连失败" + ex2.Message);
                        }
                    }
                    else
                    {
                        _logger.Error(ex.Message + "\n" + ex.StackTrace);
                    }
                }
                Thread.Sleep(1000);
            }
        }

        /// <summary>
        /// 定时更新基础设备信息
        /// </summary>
        private void BaseEquipLogic()
        {
            using var scope = host.Services.CreateScope();
            using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
            while (true)
            {
                try
                {
                    dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                    List<BaseEquip> updateEquips = dbContext.BaseEquip.Where(t => t.remark == "99").ToList();
                    if (updateEquips.Count > 0)
                    {
                        foreach (var equip in updateEquips)
                        {
                            equip.remark = "0";
                            dbContext.BaseEquip.Update(equip);
                            dbContext.SaveChanges();
                        }
                        StaticData.BaseEquip = dbContext.BaseEquip.ToList();
                    }
                }
                catch
                {

                }
                Thread.Sleep(5000);
            }
        }

        /// <summary>
        /// 定时同步消息
        /// </summary>
        private void MessageSynchronousLogic()
        {
            while (true)
            {
                FiveAgvStatusLogic();
                SecondAgvLogic();
                ThirdAgvLogic();
                SendTrayMessage();
                HositerLogic();
                CtuLineLogic();
                FiveAgvLogic();
                FiveBearAgvLogic();
                CtuCmdLogic();
                UpdatePlcPointValue();
                BasePlcPointUpdateLogic();
                Thread.Sleep(500);
            }
        }

        /// <summary>
        /// 五楼AGV状态
        /// </summary>
        private void FiveAgvStatusLogic()
        {
            try
            {
                using var scope = host.Services.CreateScope();
                using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
                var baseEquip = StaticData.BaseEquip.First(t => t.objid == 10);
                var data = new
                {
                    reqCode = StaticData.SnowId.NextId(),
                    mapCode = "EE"
                };
                string result = HttpHelper.SendPostMessage(baseEquip.serverIp, baseEquip.serverPort.Value, "rcms-dps/rest/queryAgvStatus", data.ToJsonString());
                var reponse = JsonConvert.DeserializeObject<AgvStatusDto>(result);
                if (reponse != null && reponse.code == "0")
                {
                    var AgvCardStatus = reponse.data.First(t => t.RobotCode == "2034");
                    AgvCardStatus.DateNow = DateTime.Now;
                    dbContext.Update(AgvCardStatus);
                    var BearCardStatus = reponse.data.First(t => t.RobotCode == "6011");
                    BearCardStatus.DateNow = DateTime.Now;
                    dbContext.Update(BearCardStatus);
                    var CtuCardStatus = reponse.data.First(t => t.RobotCode == "8161");
                    CtuCardStatus.DateNow = DateTime.Now;
                    dbContext.Update(CtuCardStatus);
                    dbContext.SaveChanges();
                }
            }
            catch
            {

            }
        }

        /// <summary>
        /// 获取Plc的值
        /// </summary>
        private void BasePlcPointUpdateLogic()
        {
            try
            {
                using var scope = host.Services.CreateScope();
                using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
                List<Plc.S7.Plc> plcs = StaticData.PlcDic.Values.ToList();
                foreach (var item in StaticData.BasePlcpointList.Where(t => !string.IsNullOrEmpty(t.plcpointAddress)))
                {
                    if (!string.IsNullOrEmpty(item.plcpointAddress))
                    {
                        try
                        {
                            if (item.plcpointNo.Contains("RFID"))
                                item.definefield1 = plcs.Where(t => t.IP == item.definefield3).First().ReadRFID(item.plcpointAddress)?.ToString();
                            else
                                item.definefield1 = plcs.Where(t => t.IP == item.definefield1).First().Read(item.plcpointAddress)?.ToString();
                        }
                        catch
                        {

                        }
                    }
                }
                dbContext.UpdateRange(StaticData.BasePlcpointList.Where(t => !string.IsNullOrEmpty(t.plcpointAddress)));
                dbContext.SaveChanges();
            }
            catch
            {

            }
        }

        /// <summary>
        /// 托盘库
        /// </summary>
        private void SendTrayMessage()
        {
            try
            {
                using var scope = host.Services.CreateScope();
                using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
                BaseEquip baseEquip = dbContext.BaseEquip.First(t => t.objid == 40);
                BasePlcpoint oneInPoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "oneIn");
                BasePlcpoint oneOutPoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "oneOut");
                BasePlcpoint someOutPoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "someOut");
                BasePlcpoint someInPoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "someIn");
                BasePlc basePlc = StaticData.basePlcs.First(t => t.Name == "托盘库去向");
                BasePlc basePlc2 = StaticData.basePlcs.First(t => t.Name == "托盘库数量");
                string? value = "0";
                if (StaticData.PlcDic[0].Read(oneInPoint.plcpointAddress)?.ToString() == "1")
                {
                    value = "1";
                }
                else if (StaticData.PlcDic[0].Read(oneOutPoint.plcpointAddress)?.ToString() == "1")
                {
                    value = "2";
                }
                else if (StaticData.PlcDic[0].Read(someOutPoint.plcpointAddress)?.ToString() == "1")
                {
                    value = "3";
                }
                else if (StaticData.PlcDic[0].Read(someInPoint.plcpointAddress)?.ToString() == "1")
                {
                    value = "4";
                }
                StaticData.PlcDic[2].WriteToPoint(basePlc.Address, value, basePlc.type);
                StaticData.PlcDic[2].WriteToPoint(basePlc2.Address, baseEquip.emptyCount.ToString(), basePlc2.type);
            }
            catch
            {

            }
        }

        /// <summary>
        /// 修改Plc点位信息
        /// </summary>
        private void UpdatePlcPointValue()
        {
            try
            {
                using var scope = host.Services.CreateScope();
                using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
                foreach (var item in StaticData.basePlcs)
                {
                    item.Value = StaticData.PlcDic[2].Read(item.Address)?.ToString();
                }
                dbContext.UpdateRange(StaticData.basePlcs);
                dbContext.SaveChanges();
            }
            catch
            {

            }
        }

        /// <summary>
        /// 定时更新三楼AGV信息
        /// </summary>
        private void ThirdAgvLogic()
        {
            try
            {
                using var scope = host.Services.CreateScope();
                using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
                var baseEquip = StaticData.BaseEquip.First(t => t.objid == 9);
                dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                var basePlcs = StaticData.basePlcs.Where(t => t.Station == "3楼AGV").ToList();
                var data = new
                {
                    reqCode = StaticData.SnowId.NextId(),
                    mapCode = "BB"
                };
                string result = HttpHelper.SendPostMessage(baseEquip.serverIp, baseEquip.serverPort.Value, "rcms-dps/rest/queryAgvStatus", data.ToJsonString());
                var reponse = JsonConvert.DeserializeObject<AgvStatusDto>(result);
                if (reponse != null && reponse.code == "0")
                {
                    var cardStatus = reponse.data.First(t => t.RobotCode == "2032");
                    cardStatus.DateNow = DateTime.Now;
                    dbContext.Update(cardStatus);
                    dbContext.SaveChanges();
                    var quantityPlc = basePlcs.First(t => t.Name.Contains("电量"));
                    StaticData.PlcDic[2].WriteToPoint(quantityPlc.Address, cardStatus.Battery, quantityPlc.type);
                    var XPlc = basePlcs.First(t => t.Name.Contains('X'));
                    var Ylc = basePlcs.First(t => t.Name.Contains('Y'));
                    StaticData.PlcDic[2].WriteToPoint(XPlc.Address, cardStatus.PosX.ToString(), XPlc.type);
                    StaticData.PlcDic[2].WriteToPoint(Ylc.Address, cardStatus.PosY.ToString(), Ylc.type);
                }
            }
            catch
            {

            }
        }

        /// <summary>
        /// 定时更新二楼AGV信息
        /// </summary>
        private void SecondAgvLogic()
        {
            try
            {
                using var scope = host.Services.CreateScope();
                using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
                dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                var baseEquip = StaticData.BaseEquip.First(t => t.objid == 8);
                var basePlcs = StaticData.basePlcs.Where(t => t.Station == "2楼AGV").ToList();
                var data = new
                {
                    reqCode = StaticData.SnowId.NextId(),
                    mapCode = "CC"
                };
                string result = HttpHelper.SendPostMessage(baseEquip.serverIp, baseEquip.serverPort.Value, "rcms-dps/rest/queryAgvStatus", data.ToJsonString());
                var reponse = JsonConvert.DeserializeObject<AgvStatusDto>(result);
                if (reponse != null && reponse.code == "0")
                {
                    var cardStatus = reponse.data.First(t => t.RobotCode == "2033");
                    cardStatus.DateNow = DateTime.Now;
                    dbContext.Update(cardStatus);
                    dbContext.SaveChanges();
                    var quantityPlc = basePlcs.First(t => t.Name.Contains("电量"));
                    StaticData.PlcDic[2].WriteToPoint(quantityPlc.Address, cardStatus.Battery, quantityPlc.type);
                    var XPlc = basePlcs.First(t => t.Name.Contains('X'));
                    var Ylc = basePlcs.First(t => t.Name.Contains('Y'));
                    StaticData.PlcDic[2].WriteToPoint(XPlc.Address, cardStatus.PosX.ToString(), XPlc.type);
                    StaticData.PlcDic[2].WriteToPoint(Ylc.Address, cardStatus.PosY.ToString(), Ylc.type);
                }
            }
            catch
            {

            }
        }

        /// <summary>
        /// 定时更新五楼AGV信息
        /// </summary>
        private void FiveAgvLogic()
        {
            try
            {
                using var scope = host.Services.CreateScope();
                using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
                var baseEquip = StaticData.BaseEquip.First(t => t.objid == 28);
                dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                var basePlcs = StaticData.basePlcs.Where(t => t.Station == "5楼AGV").ToList();
                var wcsCmds = dbContext.WcsTask.Where(t => t.nextPointId == 28).ToList();
                if (wcsCmds.Count > 0)
                {
                    var wcsCmd = wcsCmds.First();
                    var endPlc = basePlcs.Where(t => t.Name.Contains("目的地")).First();
                    StaticData.PlcDic[2].WriteToPoint(endPlc.Address, wcsCmd.nextPointId.ToString(), endPlc.type);
                    var startPlc = basePlcs.First(t => t.Name.Contains("起始点"));
                    StaticData.PlcDic[2].WriteToPoint(startPlc.Address, wcsCmd.currPointId.ToString(), startPlc.type);
                    var cmdPlc = basePlcs.First(t => t.Name.Contains("任务代号"));
                    string cmdType = StaticData.BaseDictionary.First(t => t.objid == wcsCmd.taskType).ToPlc;
                    StaticData.PlcDic[2].WriteToPoint(cmdPlc.Address, cmdType, cmdPlc.type);
                }
                else
                {
                    var endPlc = basePlcs.Where(t => t.Name.Contains("目的地")).First();
                    StaticData.PlcDic[2].WriteToPoint(endPlc.Address, "0", endPlc.type);
                    var startPlc = basePlcs.First(t => t.Name.Contains("起始点"));
                    StaticData.PlcDic[2].WriteToPoint(startPlc.Address, "0", startPlc.type);
                    var cmdPlc = basePlcs.First(t => t.Name.Contains("任务代号"));
                    StaticData.PlcDic[2].WriteToPoint(cmdPlc.Address, "0", cmdPlc.type);
                }
                var data = new
                {
                    reqCode = StaticData.SnowId.NextId(),
                    mapCode = "EE"
                };
                string result = HttpHelper.SendPostMessage(baseEquip.serverIp, baseEquip.serverPort.Value, "rcms-dps/rest/queryAgvStatus", data.ToJsonString());
                var reponse = JsonConvert.DeserializeObject<AgvStatusDto>(result);
                if (reponse != null && reponse.code == "0")
                {
                    var cardStatus = reponse.data.First(t => t.RobotCode == "2034");
                    var quantityPlc = basePlcs.First(t => t.Name.Contains("电量"));
                    StaticData.PlcDic[2].WriteToPoint(quantityPlc.Address, cardStatus.Battery, quantityPlc.type);
                    var XPlc = basePlcs.First(t => t.Name.Contains('X'));
                    var Ylc = basePlcs.First(t => t.Name.Contains('Y'));
                    StaticData.PlcDic[2].WriteToPoint(XPlc.Address, cardStatus.PosX.ToString(), XPlc.type);
                    StaticData.PlcDic[2].WriteToPoint(Ylc.Address, cardStatus.PosY.ToString(), Ylc.type);


                    basePlcs = StaticData.basePlcs.Where(t => t.Station == "5楼背负式").ToList();
                    cardStatus = reponse.data.First(t => t.RobotCode == "6011");
                    quantityPlc = basePlcs.First(t => t.Name.Contains("电量"));
                    StaticData.PlcDic[2].WriteToPoint(quantityPlc.Address, cardStatus.Battery, quantityPlc.type);
                    XPlc = basePlcs.First(t => t.Name.Contains('X'));
                    Ylc = basePlcs.First(t => t.Name.Contains('Y'));
                    StaticData.PlcDic[2].WriteToPoint(XPlc.Address, cardStatus.PosX.ToString(), XPlc.type);
                    StaticData.PlcDic[2].WriteToPoint(Ylc.Address, cardStatus.PosY.ToString(), Ylc.type);


                    basePlcs = StaticData.basePlcs.Where(t => t.Station == "5楼CTU").ToList();
                    cardStatus = reponse.data.First(t => t.RobotCode == "8161");
                    quantityPlc = basePlcs.First(t => t.Name.Contains("电量"));
                    StaticData.PlcDic[2].WriteToPoint(quantityPlc.Address, cardStatus.Battery, quantityPlc.type);
                    XPlc = basePlcs.First(t => t.Name.Contains("X"));
                    Ylc = basePlcs.First(t => t.Name.Contains("Y"));
                    StaticData.PlcDic[2].WriteToPoint(XPlc.Address, cardStatus.PosX.ToString(), XPlc.type);
                    StaticData.PlcDic[2].WriteToPoint(Ylc.Address, cardStatus.PosY.ToString(), Ylc.type);
                }
            }
            catch
            {

            }
        }

        /// <summary>
        /// 定时更新五楼背负式AGV信息
        /// </summary>
        private void FiveBearAgvLogic()
        {
            try
            {
                using var scope = host.Services.CreateScope();
                using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
                dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                var basePlcs = StaticData.basePlcs.Where(t => t.Station == "5楼背负式").ToList();
                var wcsCmds = dbContext.WcsTask.Where(t => t.nextPointId == 10).ToList();
                if (wcsCmds.Count > 0)
                {
                    var wcsCmd = wcsCmds.First();
                    var endPlc = basePlcs.Where(t => t.Name.Contains("目的地")).First();
                    StaticData.PlcDic[2].WriteToPoint(endPlc.Address, wcsCmd.nextPointId.ToString(), endPlc.type);
                    var startPlc = basePlcs.First(t => t.Name.Contains("起始点"));
                    StaticData.PlcDic[2].WriteToPoint(startPlc.Address, wcsCmd.currPointId.ToString(), startPlc.type);
                    var cmdPlc = basePlcs.First(t => t.Name.Contains("任务代号"));
                    string cmdType = StaticData.BaseDictionary.First(t => t.objid == wcsCmd.taskType).ToPlc;
                    StaticData.PlcDic[2].WriteToPoint(cmdPlc.Address, cmdType, cmdPlc.type);
                }
                else
                {
                    var endPlc = basePlcs.Where(t => t.Name.Contains("目的地")).First();
                    StaticData.PlcDic[2].WriteToPoint(endPlc.Address, "0", endPlc.type);
                    var startPlc = basePlcs.First(t => t.Name.Contains("起始点"));
                    StaticData.PlcDic[2].WriteToPoint(startPlc.Address, "0", startPlc.type);
                    var cmdPlc = basePlcs.First(t => t.Name.Contains("任务代号"));
                    StaticData.PlcDic[2].WriteToPoint(cmdPlc.Address, "0", cmdPlc.type);
                }
            }
            catch
            {

            }
        }

        /// <summary>
        /// 定时更新五楼CTU信息
        /// </summary>
        private void CtuCmdLogic()
        {
            try
            {
                using var scope = host.Services.CreateScope();
                using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
                var baseEquip = StaticData.BaseEquip.First(t => t.objid == 11);
                dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                var basePlcs = StaticData.basePlcs.Where(t => t.Station == "5楼CTU").ToList();
                var wcsCmds = dbContext.WcsTask.Where(t => t.nextPointId == 11).ToList();
                if (wcsCmds.Count > 0)
                {
                    var wcsCmd = wcsCmds.First();
                    List<long?> startList = new List<long?>();
                    List<long?> endList = new List<long?>();
                    if (wcsCmd.taskType != 30)
                    {
                        startList.Add(wcsCmd.currPointId);
                        endList.AddRange(wcsCmds.Select(t => t.nextPointId).ToList());
                    }
                    else
                    {
                        startList.Add(wcsCmd.nextPointId);
                        endList.AddRange(wcsCmds.Select(t => t.currPointId).ToList());
                    }
                    while (endList.Count < 6)
                    {
                        endList.Add(0);
                    }
                    var endPlcs = basePlcs.Where(t => t.Name.Contains("目的地")).OrderBy(t => t.Name).ToList();
                    for (int i = 0; i < endPlcs.Count; i++)
                    {
                        StaticData.PlcDic[2].WriteToPoint(endPlcs[i].Address, endList[i].ToString(), endPlcs[i].type);
                    }
                    var startPlc = basePlcs.First(t => t.Name.Contains("起始点"));
                    StaticData.PlcDic[2].WriteToPoint(startPlc.Address, wcsCmd.currPointId.ToString(), startPlc.type);
                    var cmdPlc = basePlcs.First(t => t.Name.Contains("任务代号"));
                    string cmdType = StaticData.BaseDictionary.First(t => t.objid == wcsCmd.taskType).ToPlc;
                    StaticData.PlcDic[2].WriteToPoint(cmdPlc.Address, cmdType, cmdPlc.type);

                }
                else
                {
                    var endPlcs = basePlcs.Where(t => t.Name.Contains("目的地")).OrderBy(t => t.Name).ToList();
                    for (int i = 0; i < endPlcs.Count; i++)
                    {
                        StaticData.PlcDic[2].WriteToPoint(endPlcs[i].Address, "0", endPlcs[i].type);
                    }
                    var startPlc = basePlcs.First(t => t.Name.Contains("起始点"));
                    StaticData.PlcDic[2].WriteToPoint(startPlc.Address, "0", startPlc.type);
                    var cmdPlc = basePlcs.First(t => t.Name.Contains("任务代号"));
                    StaticData.PlcDic[2].WriteToPoint(cmdPlc.Address, "0", cmdPlc.type);
                }
            }
            catch
            {

            }
        }

        /// <summary>
        /// 定时更新五楼U型线信息
        /// </summary>
        private void CtuLineLogic()
        {
            try
            {
                var basePlcpoints = StaticData.BasePlcpointList.ToList();
                var basePlcs = StaticData.basePlcs.ToList();
                var bill = from a in basePlcpoints
                           from b in basePlcs
                           where a.plcpointNo == b.Name && b.Station == "U型线"
                           select new { a, b };
                foreach (var item in bill)
                {
                    if (item.a.plcpointNo.Contains("RFID"))
                    {
                        string? rfid = StaticData.PlcDic[1].ReadRFID(item.a.plcpointAddress);
                        if (!string.IsNullOrEmpty(rfid))
                        {
                            rfid = rfid[(rfid.IndexOf("C") + 1)..];
                            StaticData.PlcDic[2].WriteToPoint(item.b.Address, rfid, item.b.type);
                        }
                        else
                        {
                            StaticData.PlcDic[2].WriteToPoint(item.b.Address, "0", item.b.type);
                        }
                    }
                    else
                    {
                        var value = StaticData.PlcDic[1].Read(item.a.plcpointAddress);
                        if (value != null && !string.IsNullOrEmpty(value.ToString()))
                        {
                            StaticData.PlcDic[2].WriteToPoint(item.b.Address, value.ToString(), item.b.type);
                        }
                        else
                        {
                            StaticData.PlcDic[2].WriteToPoint(item.b.Address, "0", item.b.type);
                        }
                    }
                }
            }
            catch
            {

            }
        }

        /// <summary>
        /// 提升机和接驳位信息同步
        /// </summary>
        private void HositerLogic()
        {
            try
            {
                var basePlcpoints = StaticData.BasePlcpointList.ToList();
                var basePlcs = StaticData.basePlcs.ToList();
                var bill = from a in basePlcpoints
                           from b in basePlcs
                           where a.plcpointNo == b.Name && b.Station != "U型线"
                           select new { a, b };
                foreach (var item in bill)
                {
                    if (item.a.plcpointNo.Contains("RFID"))
                    {
                        string? rfid = StaticData.PlcDic[0].ReadRFID(item.a.plcpointAddress);
                        if (!string.IsNullOrEmpty(rfid))
                        {
                            rfid = rfid[(rfid.IndexOf("JYHB") + 4)..];
                            StaticData.PlcDic[2].WriteToPoint(item.b.Address, rfid, item.b.type);
                        }
                        else
                        {
                            StaticData.PlcDic[2].WriteToPoint(item.b.Address, "0", item.b.type);
                        }
                    }
                    else
                    {
                        var value = StaticData.PlcDic[0].Read(item.a.plcpointAddress);
                        if (value != null && !string.IsNullOrEmpty(value.ToString()))
                        {
                            StaticData.PlcDic[2].WriteToPoint(item.b.Address, value.ToString(), item.b.type);
                        }
                        else
                        {
                            StaticData.PlcDic[2].WriteToPoint(item.b.Address, "0", item.b.type);
                        }
                    }
                }
            }
            catch
            {

            }
        }
    }

}

