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

namespace Khd.Core.Wcs.Wcs
{
    /// <summary>
    /// 二楼AGV调度
    /// </summary>
    public class SecondFloorAGV
    {
        private readonly IHost _host;
        private readonly LoggerUtils _logger = new LoggerUtils();
        int FloorNo { get; set; }
        int EquipID = 8; //2楼AGV

        public SecondFloorAGV(IHost host, int floor)
        {
            this._host = host;
            FloorNo = floor;

        }
        /// <summary>
        /// 启动上件扫描监听
        /// </summary>
        public void StartPoint()
        {

            Thread FlowPointThread = new Thread(MonitorInLocatorPoint);
            FlowPointThread.IsBackground = true;
            FlowPointThread.Name = "SecondFloorAGV";
            FlowPointThread.Start();
            Console.WriteLine(DateTime.Now + ":二楼AGV上件扫描监听启动成功");
            _logger.Info("二楼AGV上件扫描监听启动成功");
        }


        /// <summary>
        ///  开启线程监听2分钟小包出口光电信号，如果小包出口到位信号消失，即取托盘完成，发送信号通知线体
        /// </summary>
        /// <param name="timeoutMinutes"></param>
        public static void ListenForSignal(int timeoutMinutes = 2)
        {
            // 创建一个 CancellationTokenSource 来控制超时
            var cts = new CancellationTokenSource(TimeSpan.FromMinutes(timeoutMinutes));

            Task.Run(async () =>
            {
                var agvGetPoint = StaticData.BasePlcpointList.First(t => t.id == 53);
                var agvGetValue = StaticData.PlcDic[2].Read(agvGetPoint.plcpointAddress);

                while (!cts.Token.IsCancellationRequested)
                {
                    // 每隔 1 秒检查一次小包出口光电信号
                    await Task.Delay(1000, cts.Token);

                    agvGetValue = StaticData.PlcDic[2].Read(agvGetPoint.plcpointAddress);

                    if (agvGetValue != null && Convert.ToInt32(agvGetValue) == 0)
                    {
                        // 信号消失，20s后执行相关操作
                        Thread.Sleep(1000*20);

                        // 取托盘确认信号DB4.DBX310.1写true
                        BasePlcpoint secondOutGetOverPoint = StaticData.BasePlcpointList.First(t => t.id == 71);
                        StaticData.PlcDic[2].WriteToPoint(secondOutGetOverPoint.plcpointAddress, true, secondOutGetOverPoint.plcpointLength.ToString());

                        // 清空小包出口RFID
                        BasePlcpoint rfid2001Point = StaticData.BasePlcpointList.First(t => t.id == 52);
                        StaticData.PlcDic[2].WriteRFID(rfid2001Point.plcpointAddress, "", 12);

                        // 满足条件后退出循环
                        break;
                    }
                }

                // 任务被取消或者超时
                if (cts.Token.IsCancellationRequested)
                {
                    Console.WriteLine("任务超时或被取消");
                }
            }).Wait();
        }



        public void MonitorInLocatorPoint()
        {
            using var scope = _host.Services.CreateScope();
            using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
            BaseEquip inEquip = StaticData.BaseEquip.First(t => t.objid == 36);
            BaseEquip outEquip = StaticData.BaseEquip.First(t => t.objid == 37);
            BaseEquip lineEquip = StaticData.BaseEquip.First(t => t.objid == 2);
            BaseEquip baseEquip = StaticData.BaseEquip.First(t => t.objid == EquipID);
            BaseEquip wasteEquip = StaticData.BaseEquip.First(t => t.objid == 38);
            while (true)
            {
                try
                {
                    dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                    //获取条码号,如果该条码任务存在就继续任务,如果条码不存在,创建入库任务并调度agv
                    var taskList = dbContext.WcsTask
                        .Where(t => t.useFlag == 1)
                         .Where(t => t.IsDelete == 0 || t.IsDelete == null)
                        .Where(t => t.nextPointId == EquipID).OrderBy(t => t.createTime).ToList();
                    foreach (var item in taskList)
                    {
                        item.updateTime = DateTime.Now;
                        if (item.taskStatus == 0)//下发任务
                        {
                            BaseDictionary baseDictionary = StaticData.BaseDictionary.First(t => t.objid == item.taskType);
                            if (item.taskType == StaticTaskType.SecondLineToSmallPackage)//输送线-小包入口
                            {
                                var agvTask = new RequestAGVTaskDto
                                {
                                    reqCode = StaticData.SnowId.NextId().ToString(),
                                    positionCodePath = new List<Position>
                                    {
                                        new ()
                                        {
                                            positionCode= lineEquip.agvPositionCode,
                                            type="00"
                                        },
                                        new ()
                                        {
                                            positionCode=inEquip.agvPositionCode,
                                            type="00"
                                        }
                                    },
                                    taskTyp = baseDictionary.dicValue,
                                    ctnrTyp = "2",
                                };
                                string message = JsonConvert.SerializeObject(agvTask);
                                string result = HttpHelper.SendPostMessage(baseEquip.serverIp, baseEquip.serverPort.Value, "rcms/services/rest/hikRpcService/genAgvSchedulingTask", message);
                                var reponseMessage = JsonConvert.DeserializeObject<ReponseMessage>(result);
                                if (reponseMessage != null && reponseMessage.message == "成功")
                                {
                                    _logger.Info("二楼AGV线程下发任务" + agvTask.ToJsonString() + "\n" + message);
                                    Console.WriteLine(DateTime.Now + ":二楼AGV线程下发任务" + item.currPointNo + "," + item.endPointNo);
                                    item.taskCode = reponseMessage.data;
                                    item.taskStatus = 1;
                                    dbContext.Update(item);
                                    dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 1 });
                                    dbContext.SaveChanges();
                                }
                                else
                                {
                                    _logger.Info("五楼Agv下发任务失败" + item.taskType + result);
                                }
                            }
                            else if (item.taskType == StaticTaskType.SecondWasteToTransit)//废料工位-库位
                            {
                                var endEquip = StaticData.BaseEquip.First(t => t.objid == item.endPointId);
                                var agvTask = new RequestAGVTaskDto
                                {
                                    reqCode = StaticData.SnowId.NextId().ToString(),
                                    positionCodePath = new List<Position>
                                    {
                                        new ()
                                        {
                                            positionCode=wasteEquip.agvPositionCode,
                                            type="00"
                                        },
                                        new ()
                                        {
                                            positionCode= endEquip.agvPositionCode,
                                            type="00"
                                        }
                                    },
                                    taskTyp = baseDictionary.dicValue,
                                    ctnrTyp = "2",
                                };
                                string message = JsonConvert.SerializeObject(agvTask);
                                string result = HttpHelper.SendPostMessage(baseEquip.serverIp, baseEquip.serverPort.Value, "rcms/services/rest/hikRpcService/genAgvSchedulingTask", message);

                                var reponseMessage = JsonConvert.DeserializeObject<ReponseMessage>(result);
                                if (reponseMessage != null && reponseMessage.message == "成功")
                                {
                                    _logger.Info("二楼AGV线程下发任务" + agvTask.ToJsonString() + "\n" + message);
                                    Console.WriteLine(DateTime.Now + ":二楼AGV线程下发任务" + item.currPointNo + "," + item.endPointNo);
                                    item.taskCode = reponseMessage.data;
                                    item.taskStatus = 1;
                                    dbContext.Update(item);
                                    dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 1 });
                                    dbContext.SaveChanges();
                                }
                                else
                                {
                                    _logger.Info("五楼Agv下发任务失败" + item.taskType + result);
                                }
                            }
                            else if (item.taskType == StaticTaskType.SecondSmallPackageToStorage)//小包出口-库位
                            {
                                BaseEquip startEquip = dbContext.BaseEquip.First(t => t.objid == item.currPointId);
                                var agvTask = new RequestAGVTaskDto
                                {
                                    reqCode = StaticData.SnowId.NextId().ToString(),
                                    positionCodePath = new List<Position>
                                    {
                                        new ()
                                        {
                                            positionCode=startEquip.agvPositionCode,
                                            type="00"
                                        },
                                        new ()
                                        {
                                            positionCode=item.endPointNo,
                                            type="00"
                                        }
                                    },
                                    taskTyp = baseDictionary.dicValue,
                                    ctnrTyp = "2",
                                };
                                string message = JsonConvert.SerializeObject(agvTask);
                                string result = HttpHelper.SendPostMessage(baseEquip.serverIp, baseEquip.serverPort.Value, "rcms/services/rest/hikRpcService/genAgvSchedulingTask", message);
                                var reponseMessage = JsonConvert.DeserializeObject<ReponseMessage>(result);
                                if (reponseMessage != null && reponseMessage.message == "成功")
                                {
                                    _logger.Info("二楼AGV线程下发任务" + agvTask.ToJsonString() + "\n" + message);
                                    Console.WriteLine(DateTime.Now + ":二楼AGV线程下发任务" + item.currPointNo + "," + item.endPointNo);
                                    item.taskCode = reponseMessage.data;
                                    item.taskStatus = 1;
                                    dbContext.Update(item);
                                    dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 1 });
                                    dbContext.SaveChanges();
                                }
                                else
                                {
                                    _logger.Info("二楼Agv下发任务失败" + item.taskType + result);
                                }
                            }
                            else if (item.taskType == StaticTaskType.SecondTransitToLift)//周转位-提升机
                            {
                                var startPoint = StaticData.BaseEquip.First(t => t.objid == item.currPointId);
                                var agvTask = new RequestAGVTaskDto
                                {
                                    reqCode = StaticData.SnowId.NextId().ToString(),
                                    positionCodePath = new List<Position>
                                    {
                                        new ()
                                        {
                                            positionCode=startPoint.agvPositionCode,
                                            type="00"
                                        },
                                        new ()
                                        {
                                            positionCode=lineEquip.agvPositionCode,
                                            type="00"
                                        }
                                    },
                                    taskTyp = baseDictionary.dicValue,
                                    ctnrTyp = "2",
                                };
                                string message = JsonConvert.SerializeObject(agvTask);
                                string result = HttpHelper.SendPostMessage(baseEquip.serverIp, baseEquip.serverPort.Value, "rcms/services/rest/hikRpcService/genAgvSchedulingTask", message);
                                var reponseMessage = JsonConvert.DeserializeObject<ReponseMessage>(result);
                                if (reponseMessage != null && reponseMessage.message == "成功")
                                {
                                    _logger.Info("二楼AGV线程下发任务" + agvTask.ToJsonString() + "\n" + message);
                                    Console.WriteLine(DateTime.Now + ":二楼AGV线程下发任务" + item.currPointNo + "," + item.endPointNo);
                                    item.taskCode = reponseMessage.data;
                                    item.taskStatus = 1;
                                    dbContext.Update(item);
                                    dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 1 });
                                    dbContext.SaveChanges();
                                }
                                else
                                {
                                    _logger.Info("2楼Agv下发任务失败" + item.taskType + result);
                                }
                            }
                            else if (item.taskType == StaticTaskType.SecondStorageToLift)//库位-提升机
                            {
                                var startPoint = dbContext.WmsBaseLocation.First(t => t.locationId == item.currPointId);
                                lineEquip = dbContext.BaseEquip.First(t => t.objid == 2);
                                if (lineEquip.equipStatus == 0)
                                {
                                    var agvTask = new RequestAGVTaskDto
                                    {
                                        reqCode = StaticData.SnowId.NextId().ToString(),
                                        positionCodePath = new List<Position>
                                        {
                                            new ()
                                            {
                                                positionCode=startPoint.agvPositionCode,
                                                type="00"
                                            },
                                            new ()
                                            {
                                                positionCode= lineEquip.agvPositionCode,
                                                type="00"
                                            }
                                        },
                                        taskTyp = baseDictionary.dicValue,
                                        ctnrTyp = "2",
                                    };
                                    string message = JsonConvert.SerializeObject(agvTask);
                                    string result = HttpHelper.SendPostMessage(baseEquip.serverIp, baseEquip.serverPort.Value, "rcms/services/rest/hikRpcService/genAgvSchedulingTask", message);
                                    var reponseMessage = JsonConvert.DeserializeObject<ReponseMessage>(result);
                                    if (reponseMessage != null && reponseMessage.message == "成功")
                                    {
                                        _logger.Info("二楼AGV线程下发任务" + agvTask.ToJsonString() + "\n" + message);
                                        Console.WriteLine(DateTime.Now + ":二楼AGV线程下发任务" + item.currPointNo + "," + item.endPointNo);
                                        item.taskCode = reponseMessage.data;
                                        item.taskStatus = 1;
                                        lineEquip.equipStatus = 1;
                                        dbContext.Update(lineEquip);
                                        dbContext.Update(item);
                                        dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 1 });
                                        dbContext.SaveChanges();
                                    }
                                    else
                                    {
                                        _logger.Info("五楼Agv下发任务失败" + item.taskType + result);
                                    }
                                }
                            }
                            else if (item.taskType == StaticTaskType.SecondRemove)//2F移库
                            {
                                var agvTask = new RequestAGVTaskDto
                                {
                                    reqCode = StaticData.SnowId.NextId().ToString(),
                                    positionCodePath = new List<Position>
                                    {
                                        new()
                                        {
                                            positionCode = item.currPointNo,
                                            type = "00"
                                        },
                                        new()
                                        {
                                            positionCode = item.endPointNo,
                                            type = "00"
                                        }

                                    },
                                    taskTyp = baseDictionary.dicValue,
                                    ctnrTyp = "2",
                                };
                                string message = JsonConvert.SerializeObject(agvTask);
                                string result = HttpHelper.SendPostMessage(baseEquip.serverIp, baseEquip.serverPort.Value, "rcms/services/rest/hikRpcService/genAgvSchedulingTask", message);
                                var reponseMessage = JsonConvert.DeserializeObject<ReponseMessage>(result);
                                if (reponseMessage != null && reponseMessage.message == "成功")
                                {
                                    _logger.Info("二楼AGV线程下发任务" + agvTask.ToJsonString() + "\n" + message);
                                    Console.WriteLine(DateTime.Now + ":二楼AGV线程下发任务" + item.currPointNo + "," + item.endPointNo);
                                    item.taskCode = reponseMessage.data;
                                    item.taskStatus = 1;
                                    dbContext.Update(item);
                                    dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 1 });
                                    dbContext.SaveChanges();
                                }
                                else
                                {
                                    _logger.Info("五楼Agv下发任务失败" + item.taskType + result);
                                }
                            }
                            else if (item.taskType == StaticTaskType.SecondLiftToWaste)//提升机-废料工位
                            {
                                var agvTask = new RequestAGVTaskDto
                                {
                                    reqCode = StaticData.SnowId.NextId().ToString(),
                                    positionCodePath = new List<Position>
                                    {
                                        new ()
                                        {
                                            positionCode=lineEquip.agvPositionCode,
                                            type="00"
                                        },
                                        new ()
                                        {
                                            positionCode=wasteEquip.agvPositionCode,
                                            type="00"
                                        }
                                    },
                                    taskTyp = baseDictionary.dicValue,
                                    ctnrTyp = "2",
                                };
                                string message = JsonConvert.SerializeObject(agvTask);
                                string result = HttpHelper.SendPostMessage(baseEquip.serverIp, baseEquip.serverPort.Value, "rcms/services/rest/hikRpcService/genAgvSchedulingTask", message);
                                var reponseMessage = JsonConvert.DeserializeObject<ReponseMessage>(result);
                                if (reponseMessage != null && reponseMessage.message == "成功")
                                {
                                    _logger.Info("二楼AGV线程下发任务" + agvTask.ToJsonString() + "\n" + message);
                                    Console.WriteLine(DateTime.Now + ":二楼AGV线程下发任务" + item.currPointNo + "," + item.endPointNo);
                                    item.taskCode = reponseMessage.data;
                                    item.taskStatus = 1;
                                    dbContext.Update(item);
                                    dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 1 });
                                    dbContext.SaveChanges();
                                }
                                else
                                {
                                    _logger.Info("五楼Agv下发任务失败" + item.taskType + result);
                                }
                            }
                            else if (item.taskType == StaticTaskType.SecondTransitToWaste)//周转位-废料工位
                            {
                                var wasteEquipLocation = StaticData.BaseEquip.FirstOrDefault(t => t.objid == item.currPointId);
                                if (wasteEquipLocation != null)
                                {
                                    var agvTask = new RequestAGVTaskDto
                                    {
                                        reqCode = StaticData.SnowId.NextId().ToString(),
                                        positionCodePath = new List<Position>
                                        {
                                            new ()
                                            {
                                                positionCode=wasteEquipLocation.agvPositionCode,
                                                type="00"
                                            },
                                            new ()
                                            {
                                                positionCode=wasteEquip.agvPositionCode,
                                                type="00"
                                            }
                                        },
                                        taskTyp = baseDictionary.dicValue,
                                        ctnrTyp = "2",
                                    };
                                    string message = JsonConvert.SerializeObject(agvTask);
                                    string result = HttpHelper.SendPostMessage(baseEquip.serverIp, baseEquip.serverPort.Value, "rcms/services/rest/hikRpcService/genAgvSchedulingTask", message);
                                    var reponseMessage = JsonConvert.DeserializeObject<ReponseMessage>(result);
                                    if (reponseMessage != null && reponseMessage.message == "成功")
                                    {
                                        _logger.Info("二楼AGV线程下发任务" + agvTask.ToJsonString() + "\n" + message);
                                        Console.WriteLine(DateTime.Now + ":二楼AGV线程下发任务" + item.currPointNo + "," + item.endPointNo);
                                        item.taskCode = reponseMessage.data;
                                        item.taskStatus = 1;
                                        dbContext.Update(item);
                                        dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 1 });
                                        dbContext.SaveChanges();
                                    }
                                    else
                                    {
                                        _logger.Info("五楼Agv下发任务失败" + item.taskType + result);
                                    }
                                }
                            }
                            else if (item.taskType == StaticTaskType.SecondLiftToTransit)//提升机到周转位
                            {
                                var endEquip = StaticData.BaseEquip.First(t => t.objid == item.endPointId);
                                var agvTask = new RequestAGVTaskDto
                                {
                                    reqCode = StaticData.SnowId.NextId().ToString(),
                                    positionCodePath = new List<Position>
                                    {
                                        new ()
                                        {
                                            positionCode=lineEquip.agvPositionCode,
                                            type="00"
                                        },
                                        new ()
                                        {
                                            positionCode=endEquip.agvPositionCode,
                                            type="00"
                                        }
                                    },
                                    taskTyp = baseDictionary.dicValue,
                                    ctnrTyp = "2",
                                };
                                string message = JsonConvert.SerializeObject(agvTask);
                                string result = HttpHelper.SendPostMessage(baseEquip.serverIp, baseEquip.serverPort.Value, "rcms/services/rest/hikRpcService/genAgvSchedulingTask", message);
                                var reponseMessage = JsonConvert.DeserializeObject<ReponseMessage>(result);
                                if (reponseMessage != null && reponseMessage.message == "成功")
                                {
                                    _logger.Info("二楼AGV线程下发任务" + agvTask.ToJsonString() + "\n" + message);
                                    Console.WriteLine(DateTime.Now + ":二楼AGV线程下发任务" + item.currPointNo + "," + item.endPointNo);
                                    item.taskCode = reponseMessage.data;
                                    item.taskStatus = 1;
                                    dbContext.Update(item);
                                    dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 1 });
                                    dbContext.SaveChanges();
                                }
                                else
                                {
                                    _logger.Info("五楼Agv下发任务失败" + item.taskType + result);
                                }
                            }
                            else if (item.taskType == StaticTaskType.SecondTransitToSmallPackage)//周转位-小包入口
                            {
                                BaseEquip startEquip = StaticData.BaseEquip.First(t => t.objid == item.currPointId);

                                var agvTask = new RequestAGVTaskDto
                                {
                                    reqCode = StaticData.SnowId.NextId().ToString(),
                                    positionCodePath = new List<Position>
                                    {
                                        new ()
                                        {
                                            positionCode=startEquip.agvPositionCode,
                                            type="00"
                                        },
                                        new ()
                                        {
                                            positionCode=inEquip.agvPositionCode,
                                            type="00"
                                        }
                                    },
                                    taskTyp = baseDictionary.dicValue,
                                    ctnrTyp = "2",
                                };
                                string message = JsonConvert.SerializeObject(agvTask);
                                string result = HttpHelper.SendPostMessage(baseEquip.serverIp, baseEquip.serverPort.Value, "rcms/services/rest/hikRpcService/genAgvSchedulingTask", message);
                                var reponseMessage = JsonConvert.DeserializeObject<ReponseMessage>(result);
                                if (reponseMessage != null && reponseMessage.message == "成功")
                                {
                                    _logger.Info("二楼AGV线程下发任务" + agvTask.ToJsonString() + "\n" + message);
                                    Console.WriteLine(DateTime.Now + ":二楼AGV线程下发任务" + item.currPointNo + "," + item.endPointNo);
                                    item.taskCode = reponseMessage.data;
                                    item.taskStatus = 1;
                                    dbContext.Update(item);
                                    dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 1 });
                                    dbContext.SaveChanges();
                                }
                                else
                                {
                                    _logger.Info("五楼Agv下发任务失败" + item.taskType + result);
                                }
                            }
                        }
                        else
                        {
                            if (item.taskStatus == 3)
                            {
                                _logger.Info("二楼AGV线程继续任务" + item.objid);
                                if (item.currPointId == lineEquip.objid)
                                {
                                    var lineSignal02 = StaticData.PlcDic[0].Read(StaticData.BasePlcpointList.First(t => t.plcpointNo == "linesignal02").plcpointAddress);
                                    if (lineSignal02 != null && lineSignal02.ToString() == "1")
                                    {
                                        var agvTask = new RequestAGVTaskDto
                                        {
                                            reqCode = StaticData.SnowId.NextId().ToString(),
                                            taskCode = item.taskCode
                                        };
                                        string message = JsonConvert.SerializeObject(agvTask);
                                        string result = HttpHelper.SendPostMessage(baseEquip.serverIp, baseEquip.serverPort.Value, "rcms/services/rest/hikRpcService/continueTask", message);
                                        ReponseMessage? reponseMessage = JsonConvert.DeserializeObject<ReponseMessage>(result);
                                        if (reponseMessage != null && reponseMessage.message == "成功")
                                        {
                                            dbContext.WcsTask.Where(t => t.objid == item.objid).Update(t => new WcsTask() { taskStatus = 4 });
                                            dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 4 });
                                        }
                                    }
                                }
                                else if (item.currPointId == wasteEquip.objid)
                                {
                                    if (true)
                                    {
                                        var agvTask = new RequestAGVTaskDto
                                        {
                                            reqCode = StaticData.SnowId.NextId().ToString(),
                                            taskCode = item.taskCode
                                        };
                                        string message = JsonConvert.SerializeObject(agvTask);
                                        string result = HttpHelper.SendPostMessage(baseEquip.serverIp, baseEquip.serverPort.Value, "rcms/services/rest/hikRpcService/continueTask", message);
                                        ReponseMessage? reponseMessage = JsonConvert.DeserializeObject<ReponseMessage>(result);
                                        if (reponseMessage != null && reponseMessage.message == "成功")
                                        {
                                            dbContext.WcsTask.Where(t => t.objid == item.objid).Update(t => new WcsTask() { taskStatus = 4 });
                                            dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 4 });
                                        }
                                    }
                                }
                                else if (item.currPointId == outEquip.objid)
                                {
                                    if (true)
                                    {
                                        var agvTask = new RequestAGVTaskDto
                                        {
                                            reqCode = StaticData.SnowId.NextId().ToString(),
                                            taskCode = item.taskCode
                                        };
                                        string message = JsonConvert.SerializeObject(agvTask);
                                        string result = HttpHelper.SendPostMessage(baseEquip.serverIp, baseEquip.serverPort.Value, "rcms/services/rest/hikRpcService/continueTask", message);
                                        ReponseMessage? reponseMessage = JsonConvert.DeserializeObject<ReponseMessage>(result);
                                        if (reponseMessage != null && reponseMessage.message == "成功")
                                        {
                                            dbContext.WcsTask.Where(t => t.objid == item.objid).Update(t => new WcsTask() { taskStatus = 4 });
                                            dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 4 });

                                            // 开启线程监听2分钟小包出口光电信号，如果小包出口到位信号消失，即取托盘完成，发送信号通知线体
                                            ListenForSignal(2);
                                            

                                        }
                                    }

                                 
                                  
                                }
                                else
                                {
                                    var agvTask = new RequestAGVTaskDto
                                    {
                                        reqCode = StaticData.SnowId.NextId().ToString(),
                                        taskCode = item.taskCode
                                    };
                                    string message = JsonConvert.SerializeObject(agvTask);
                                    string result = HttpHelper.SendPostMessage(baseEquip.serverIp, baseEquip.serverPort.Value, "rcms/services/rest/hikRpcService/continueTask", message);
                                    ReponseMessage? reponseMessage = JsonConvert.DeserializeObject<ReponseMessage>(result);
                                    if (reponseMessage != null && reponseMessage.message == "成功")
                                    {
                                        dbContext.WcsTask.Where(t => t.objid == item.objid).Update(t => new WcsTask() { taskStatus = 4 });
                                        dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 4 });
                                    }
                                }

                             

                            }
                            else if (item.taskStatus == 5)
                            {
                                if (item.taskType == StaticTaskType.SecondLineToSmallPackage)
                                {
                                    // 托盘库叫料信号
                                    var agvPutPoint = StaticData.BasePlcpointList.First(t => t.id == 54);
                                    //2F托盘库产线数据通讯情况
                                    var ConnectStatus2FPoint = StaticData.BasePlcpointList.First(t => t.id == 73);
                                    //2F托盘库入口上料光电
                                    var PalletInIsHas2FPoint = StaticData.BasePlcpointList.First(t => t.id == 74);

                                    var agvPutValue = StaticData.PlcDic[2].Read(agvPutPoint.plcpointAddress);//托盘库叫料信号
                                    var ConnectStatus2F = StaticData.PlcDic[2].Read(ConnectStatus2FPoint.plcpointAddress);//2F托盘库产线数据通讯情况
                                    var PalletInIsHas2F = StaticData.PlcDic[2].Read(PalletInIsHas2FPoint.plcpointAddress);//2F托盘库入口上料光电

                                   
                                    if (agvPutValue !=null && ConnectStatus2F != null && PalletInIsHas2F !=null&& Convert.ToInt32(agvPutValue) == 1 && Convert.ToInt32(ConnectStatus2F) == 1 && Convert.ToInt32(PalletInIsHas2F) == 0)
                                    {
                                        // 托盘库叫料信号，并且通讯正常,并且小包入口无料 ,才可放托盘
                                        var agvTask = new RequestAGVTaskDto
                                        {
                                            reqCode = StaticData.SnowId.NextId().ToString(),
                                            taskCode = item.taskCode
                                        };
                                        string message = JsonConvert.SerializeObject(agvTask);
                                        string result = HttpHelper.SendPostMessage(baseEquip.serverIp, baseEquip.serverPort.Value, "rcms/services/rest/hikRpcService/continueTask", message);
                                        ReponseMessage? reponseMessage = JsonConvert.DeserializeObject<ReponseMessage>(result);
                                        if (reponseMessage != null && reponseMessage.message == "成功")
                                        {
                                            dbContext.WcsTask.Where(t => t.objid == item.objid).Update(t => new WcsTask() { taskStatus = 6 });
                                            dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 6 });
                                        }
                                    }
                                }
                               
                            }
                            else if (item.taskStatus == 7)
                            {
                                if (item.currPointId == 2)
                                {
                                    lineEquip = dbContext.BaseEquip.First(t => t.objid == 2);
                                    lineEquip.equipStatus = 0;
                                    dbContext.Update(lineEquip);
                                }
                                if (item.taskType == StaticTaskType.SecondSmallPackageToStorage) //小包出口到库位
                                {
                                    //WmsProductInstock? wmsProductInstock = dbContext.WmsProductInstock.FirstOrDefault(t => t.productInstockId == item.orderId);
                                    //if (wmsProductInstock != null)
                                    //{
                                    //    WmsProductInstockDetail? wmsProductInstockDetail = dbContext.WmsProductInstockDetail.FirstOrDefault(t => t.productInstockId == wmsProductInstock.productInstockId);
                                    //    if (wmsProductInstockDetail != null)
                                    //    {
                                    MesBasePalletInfo? mesBasePalletInfo = dbContext.MesBasePalletInfo.FirstOrDefault(t => t.palletInfoCode == item.containerNo);
                                    if (mesBasePalletInfo != null)
                                    {
                                        MesBaseBarcodeInfo? mesBaseBarcodeInfo = dbContext.MesBaseBarcodeInfo.FirstOrDefault(t => t.palletInfoCode == item.containerNo);
                                        if (mesBaseBarcodeInfo != null)
                                        {
                                            WmsBaseLocation wmsBaseLocation = dbContext.WmsBaseLocation.First(t => t.locationId == item.endPointId);
                                            wmsBaseLocation.locationStatus = "1";
                                            wmsBaseLocation.containerCode = item.containerNo;
                                            WmsProductStock wmsProductStock = new WmsProductStock()
                                            {
                                                
                                                productId = mesBasePalletInfo.materialId,
                                                activeFlag = "1",
                                                frozenAmount = 0,
                                                createBy = "WCS",
                                                createDate = DateTime.Now,
                                                updateBy = "WCS",
                                                updateDate = DateTime.Now,
                                                instockDate = DateTime.Now,
                                                locationCode = wmsBaseLocation.locationCode,
                                                occupyAmount = 0,
                                                totalAmount = 1,
                                                palletInfoCode = item.containerNo,
                                                planCode = StaticData.SnowId.NextId().ToString(),
                                                planDetailCode = mesBaseBarcodeInfo.planDetailCode,
                                                productBatch = mesBasePalletInfo.materialBarcode,
                                                saleorderCode = mesBaseBarcodeInfo.saleorderCode,
                                                productStockId = StaticData.SnowId.NextId(),
                                                saleOrderId = mesBaseBarcodeInfo.saleOrderId,
                                                stockType = "3",
                                                qualityStatus = "0",
                                                warehouseFloor = 2,
                                                warehouseId = wmsBaseLocation.warehouseId
                                            };
                                            #region 插入WmsProductInstock表

                                            WmsProductInstock wmsProductInstock = new WmsProductInstock();
                                            wmsProductInstock.taskCode = StaticData.SnowId.NextId().ToString();
                                            wmsProductInstock.warehouseId = wmsBaseLocation.warehouseId;
                                            wmsProductInstock.warehouseFloor = 2;
                                            wmsProductInstock.locationCode = wmsBaseLocation.locationCode;
                                            wmsProductInstock.productType = "3";
                                            wmsProductInstock.operationType = "3";
                                            wmsProductInstock.planCode = StaticData.SnowId.NextId().ToString();
                                            wmsProductInstock.planDetailCode = mesBaseBarcodeInfo.planDetailCode;
                                            wmsProductInstock.SaleOrderId = mesBaseBarcodeInfo.saleOrderId;
                                            wmsProductInstock.saleorderCode = mesBaseBarcodeInfo.saleorderCode;
                                            wmsProductInstock.instockType = "1";
                                            wmsProductInstock.productId = mesBaseBarcodeInfo.materialId;
                                            wmsProductInstock.productBatch = mesBaseBarcodeInfo.barcodeInfo;
                                            wmsProductInstock.instockAmount = mesBaseBarcodeInfo.amount;
                                            wmsProductInstock.palletInfoCode = mesBaseBarcodeInfo.palletInfoCode;
                                            wmsProductInstock.auditStatus = "1";
                                            wmsProductInstock.executeStatus = "2";
                                            wmsProductInstock.applyBy = "WCS";
                                            wmsProductInstock.applyDate = DateTime.Now;
                                            wmsProductInstock.updateBy = "WCS";
                                            wmsProductInstock.updateDate = DateTime.Now;
                                            wmsProductInstock.beginTime = DateTime.Now;
                                            wmsProductInstock.endTime = DateTime.Now;
                                            dbContext.Add(wmsProductInstock);
                                            #endregion
                                            //wmsProductInstockDetail.executeStatus = "2";
                                            //wmsProductInstock.endTime = DateTime.Now;
                                            //wmsProductInstock.executeStatus = "2";
                                            //dbContext.Update(wmsProductInstockDetail);
                                            dbContext.Add(wmsProductStock);
                                            dbContext.Update(wmsBaseLocation);
                                            SystemData.UnLockOutLocation(wmsBaseLocation, dbContext);
                                            //dbContext.Update(wmsProductInstock);
                                            dbContext.Remove(item);
                                            dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 8 });
                                            dbContext.SaveChanges();
                                            _logger.Info("二楼AGV线程完成任务" + item.objid);
                                        }
                                        //    }
                                        //}
                                    }
                                }
                                else if (item.taskType == StaticTaskType.SecondStorageToLift)//成品出库
                                {
                                    WmsProductOutstock? wmsProductOutstock = dbContext.WmsProductOutstock.FirstOrDefault(t => t.productOutstockId == item.orderId);
                                    if (wmsProductOutstock != null)
                                    {
                                      
                                        var wmsBaseLocation = dbContext.WmsBaseLocation.Where(t => t.locationId == item.currPointId).First();
                                        WmsProductStock wmsProductStock = dbContext.WmsProductStock.First(t => t.locationCode == wmsBaseLocation.locationCode);

                                        wmsProductOutstock.outstockQty++;
                                        if (wmsProductOutstock.applyQty <= wmsProductOutstock.outstockQty)
                                        {
                                            wmsProductOutstock.endTime = DateTime.Now;
                                            wmsProductOutstock.executeStatus = "2";
                                        }


                                        WmsProductOutstockDetail newWmsProductOutstockDetail = new WmsProductOutstockDetail();
                                        newWmsProductOutstockDetail.productOutstockId = wmsProductOutstock.productOutstockId;
                                        newWmsProductOutstockDetail.warehouseId = wmsProductOutstock.warehouseId;
                                        newWmsProductOutstockDetail.locationCode = wmsBaseLocation.locationCode;
                                        newWmsProductOutstockDetail.productBarcode = wmsProductStock.productBatch;
                                        newWmsProductOutstockDetail.productId = wmsProductStock.productId;
                                        newWmsProductOutstockDetail.planAmount = wmsProductOutstock.applyQty;
                                        newWmsProductOutstockDetail.outstockAmount = wmsProductOutstock.outstockQty;
                                        newWmsProductOutstockDetail.executeStatus = "2";
                                        newWmsProductOutstockDetail.updateBy = "WCS";
                                        newWmsProductOutstockDetail.updateDate = DateTime.Now;
                                        newWmsProductOutstockDetail.beginTime = DateTime.Now;
                                        newWmsProductOutstockDetail.endTime = DateTime.Now;

                                       
                                        wmsBaseLocation.locationStatus = "1";
                                        wmsBaseLocation.containerCode = null;
                                        item.nextPointId = 2;
                                        item.taskStatus = 8;
                                        SystemData.UnLockOutLocation(wmsBaseLocation, dbContext);
                                        dbContext.Remove(wmsProductStock);
                                        dbContext.Update(wmsBaseLocation);
                                        dbContext.Add(newWmsProductOutstockDetail);
                                        dbContext.Update(wmsProductOutstock);
                                        dbContext.Update(item);
                                        dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 8 });
                                        dbContext.SaveChanges();
                                        _logger.Info("二楼AGV线程完成任务" + item.objid);

                                    }
                                }
                                else if (item.taskType == StaticTaskType.SecondLiftToTransit)//空托盘入周转位
                                {
                                    BaseEquip endEquip = StaticData.BaseEquip.First(t => t.objid == item.endPointId);
                                    endEquip.equipStatus = 1;
                                    endEquip.emptyCount = item.qty;
                                    dbContext.Update(endEquip);
                                    dbContext.Remove(item);
                                    dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 8 });
                                    dbContext.SaveChanges();
                                    _logger.Info("二楼AGV线程完成任务" + item.objid);
                                }
                                else if (item.taskType == StaticTaskType.SecondLiftToWaste)//提升机到废料口
                                {
                                    BaseEquip startEquip = dbContext.BaseEquip.First(t => t.objid == item.currPointId);
                                    startEquip.equipStatus = 0;
                                    BaseEquip endEquip = StaticData.BaseEquip.First(t => t.objid == item.endPointId);
                                    endEquip.equipStatus = 1;
                                    endEquip.emptyCount = 1;
                                    endEquip.containerNo = item.containerNo;
                                    dbContext.Update(endEquip);
                                    dbContext.Update(startEquip);
                                    dbContext.Remove(item);
                                    dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 8 });
                                    dbContext.SaveChanges();
                                    _logger.Info("二楼AGV线程完成任务" + item.objid);
                                }
                                else if (item.taskType == StaticTaskType.SecondLineToSmallPackage)//输送线到小包入口
                                {
                                    // 小包入口放料完成确认信号
                                    //放托盘确认信号DB4.DBX310.0写true
                                    BasePlcpoint SecondInPutOverPoint = StaticData.BasePlcpointList.First(t => t.id == 72);
                                    StaticData.PlcDic[2].WriteToPoint(SecondInPutOverPoint.plcpointAddress, true, SecondInPutOverPoint.plcpointLength.ToString());


                                    BaseEquip startEquip = dbContext.BaseEquip.First(t => t.objid == item.currPointId);
                                    startEquip.equipStatus = 0;
                                    dbContext.Update(startEquip);
                                    dbContext.Remove(item);
                                    dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 8 });
                                    dbContext.SaveChanges();
                                    _logger.Info("二楼AGV线程完成任务" + item.objid);
                                }
                                else if (item.taskType == StaticTaskType.SecondTransitToWaste)//周转位到废料口
                                {
                                    BaseEquip startEquip = StaticData.BaseEquip.First(t => t.objid == item.currPointId);
                                    startEquip.equipStatus = 0;
                                    startEquip.emptyCount = 0;
                                    startEquip.containerNo = null;
                                    BaseEquip endEquip = StaticData.BaseEquip.First(t => t.objid == item.endPointId);
                                    endEquip.equipStatus = 1;
                                    endEquip.emptyCount = 1;
                                    endEquip.containerNo = item.containerNo;
                                    dbContext.Update(startEquip);
                                    dbContext.Update(endEquip);
                                    dbContext.Remove(item);
                                    dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 8 });
                                    dbContext.SaveChanges();
                                    _logger.Info("二楼AGV线程完成任务" + item.objid);
                                }
                                else if (item.taskType == StaticTaskType.SecondRemove)//移库
                                {
                                    using var transaction = dbContext.Database.BeginTransaction();
                                    try
                                    {
                                        var wmsProductStock = dbContext.WmsProductStock.FirstOrDefault(t => t.locationCode == item.currPointNo);
                                        WmsBaseLocation wmsBaseLocation = dbContext.WmsBaseLocation.Where(t => t.locationId == item.currPointId).First();
                                        WmsBaseLocation toLocation = dbContext.WmsBaseLocation.Where(t => t.locationId == item.endPointId).First();
                                        SystemData.UnLockOutLocation(wmsBaseLocation, dbContext);
                                        SystemData.UnLockOutLocation(toLocation, dbContext);
                                        if (wmsProductStock != null)
                                        {
                                            wmsProductStock.locationCode = item.endPointNo;
                                            dbContext.Update(wmsProductStock);
                                        }
                                        dbContext.WmsBaseLocation.Where(t => t.locationId == item.currPointId).Update(t => new WmsBaseLocation
                                        {
                                            locationStatus = "1",
                                            containerCode = null,
                                            updateTime = DateTime.Now
                                        });
                                        dbContext.WmsBaseLocation.Where(t => t.locationId == item.endPointId).Update(t => new WmsBaseLocation
                                        {
                                            locationStatus = "1",
                                            containerCode = item.endPointNo,
                                            updateTime = DateTime.Now
                                        });
                                        dbContext.Remove(item);
                                        dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 8 });

                                        #region 插入移库记录
                                        WmsMove wmsMove = new WmsMove();
                                        wmsMove.MoveId = StaticData.SnowId.NextId();
                                        wmsMove.TaskCode = StaticData.SnowId.NextId().ToString();
                                        wmsMove.WarehouseId = wmsBaseLocation.warehouseId;
                                        wmsMove.OriLocationCode = wmsBaseLocation.locationCode;
                                        wmsMove.TargetLocationCode = toLocation.locationCode;
                                        wmsMove.InstockBatch = wmsProductStock.productBatch;
                                        wmsMove.MaterialId = wmsProductStock.productId;
                                        wmsMove.PlanAmount = 1;
                                        wmsMove.RealOutstockAmount = 1;
                                        wmsMove.RealInstockAmount = 1;
                                        wmsMove.OperationType = "3";
                                        wmsMove.MoveWay = "2";
                                        wmsMove.MoveType = "1";
                                        wmsMove.AuditStatus = "1";
                                        wmsMove.ExecuteStatus = "2";
                                        wmsMove.UpdateBy = "WCS";
                                        wmsMove.UpdateDate = DateTime.Now;
                                        wmsMove.BeginTime = DateTime.Now;
                                        wmsMove.EndTime = DateTime.Now;

                                        WmsMoveDetail wmsMoveDetail = new WmsMoveDetail();
                                        wmsMoveDetail.MoveId = wmsMove.MoveId;
                                        wmsMoveDetail.MaterialBarcode = wmsMove.InstockBatch;
                                        wmsMoveDetail.InstockBatch = wmsMove.InstockBatch;
                                        wmsMoveDetail.MaterialId = (long)wmsProductStock.productId;
                                        wmsMoveDetail.LocationCode = toLocation.locationCode;
                                        wmsMoveDetail.PlanAmount = 1;
                                        wmsMoveDetail.RealInstockAmount = 1;
                                        wmsMoveDetail.RealAmount = 1;
                                        wmsMoveDetail.ExecuteStatus = "2";
                                        wmsMoveDetail.ExecuteTime = DateTime.Now;
                                        wmsMoveDetail.ExecuteEndTime = DateTime.Now;
                                        wmsMoveDetail.ExecutePerson = "WCS";
                                        wmsMoveDetail.UpdateBy = "WCS";
                                        wmsMoveDetail.UpdateDate = DateTime.Now;

                                        dbContext.WmsMove.Add(wmsMove);
                                        dbContext.WmsMoveDetail.Add(wmsMoveDetail);
                                        #endregion


                                        transaction.Commit();
                                        dbContext.SaveChanges();
                                        _logger.Info("二楼AGV线程完成任务" + item.objid);
                                    }
                                    catch (Exception ex)
                                    {
                                        try
                                        {
                                            transaction.Rollback();
                                        }
                                        catch
                                        {

                                        }
                                        _logger.Error(ex.Message + "\n" + ex.StackTrace);
                                    }
                                }
                                else if (item.taskType == StaticTaskType.SecondWasteToTransit)//废料区到周转区
                                {
                                    wasteEquip.emptyCount = 0;
                                    wasteEquip.equipStatus = 0;
                                    BaseEquip endEquip = dbContext.BaseEquip.First(t => t.objid == item.endPointId);
                                    endEquip.emptyCount = 1;
                                    endEquip.equipStatus = 2;
                                    endEquip.containerNo = item.containerNo;
                                    dbContext.Remove(item);
                                    dbContext.Update(wasteEquip);
                                    dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 8 });
                                    dbContext.SaveChanges();
                                    _logger.Info("二楼AGV线程完成任务" + item.objid);
                                }
                                else if (item.taskType == StaticTaskType.SecondTransitToLift)//周转位-提升机
                                {
                                    BaseEquip emptyEquip = StaticData.BaseEquip.First(t => t.objid == item.currPointId);
                                    emptyEquip.emptyCount = 0;
                                    emptyEquip.equipStatus = 0;
                                    emptyEquip.containerNo = null;
                                    item.nextPointId = 2;
                                    item.taskStatus = 8;
                                    dbContext.Update(item);
                                    dbContext.Update(emptyEquip);
                                    dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 6 });
                                    dbContext.SaveChanges();
                                    _logger.Info("二楼AGV线程完成任务" + item.objid);
                                }
                                else if (item.taskType == StaticTaskType.SecondTransitToSmallPackage)//周转区-小包入口
                                {
                                    BaseEquip startEquip = StaticData.BaseEquip.First(t => t.objid == item.currPointId);
                                    startEquip.equipStatus = 0;
                                    startEquip.emptyCount = 0;
                                    startEquip.containerNo = null;
                                    dbContext.Update(startEquip);
                                    dbContext.Remove(item);
                                    dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 8 });
                                    dbContext.SaveChanges();
                                    _logger.Info("二楼AGV线程完成任务" + item.objid);
                                }
                            }
                        }
                        break;
                    }
                }
                catch (Exception ex)
                {
                    if (ex is PlcException)
                    {

                    }
                    else
                    {
                        _logger.Error(ex.Message + "\n" + ex.StackTrace);
                    }
                }
                finally
                {
                    Thread.Sleep(1000);
                }
            }
        }

    }
}
