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.Library.Mapper;
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 ThirdFloorAGV
    {
        private readonly LoggerUtils _logger = new LoggerUtils();
        private readonly IHost _host;
        int FloorNo { get; set; }
        private readonly BasePlcpoint putTrayPoint;
        private readonly BasePlcpoint getTrayPoint;
        private bool IsTrayGet { get; set; }
        public ThirdFloorAGV(IHost host, int floor)
        {
            this._host = host;
            FloorNo = floor;
            this.putTrayPoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "putTray");
            this.getTrayPoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "getTray");

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

            Thread FlowPointThread = new Thread(MonitorInLocatorPoint);
            FlowPointThread.Name = "ThirdFloorAGVTrayIn";
            FlowPointThread.IsBackground = true;
            FlowPointThread.Start();

            Thread FZJThread = new Thread(MonitorInFZJPoint);
            FZJThread.Name = "ThirdFloorAGV";
            FZJThread.IsBackground = true;
            FZJThread.Start();

            Thread MonitorTraySignalThread = new Thread(MonitorTraySignal);
            MonitorTraySignalThread.Name = "ThirdFloorAGVTraySignal";
            MonitorTraySignalThread.IsBackground = true;
            MonitorTraySignalThread.Start();

            Console.WriteLine(DateTime.Now + ":三楼AGV 启动上件扫描监听");
            _logger.Info("三楼AGV 启动上件扫描监听");
        }

        private void MonitorTraySignal()
        {
            BasePlcpoint GetTrayPoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "getTray");
            BasePlcpoint GetTrayOverPoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "GetTrayOver");
            while (true)
            {
                while (IsTrayGet)
                {
                    try
                    {
                        var getTrayValue = StaticData.PlcDic[2].Read(GetTrayPoint.plcpointAddress);
                        if (getTrayValue != null && !Convert.ToBoolean(getTrayValue))
                        {
                            StaticData.PlcDic[2].WriteToPoint(GetTrayOverPoint.plcpointAddress, false, GetTrayOverPoint.plcpointLength.ToString());
                            IsTrayGet = false;
                            _logger.Info("三楼AGV 托盘已取走信号复位");
                        }
                    }
                    catch
                    {

                    }
                    Thread.Sleep(3000);
                }
                Thread.Sleep(3000);
            }
        }

        private void MonitorInFZJPoint(object? obj)
        {
            using var scope = _host.Services.CreateScope();
            using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
            while (true)
            {
                try
                {
                    dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                    var getTrayValue = StaticData.PlcDic[2].Read(getTrayPoint.plcpointAddress);
                    if (getTrayValue != null && Convert.ToBoolean(getTrayValue))
                    {
                        var task = dbContext.WcsTask.Where(t => t.IsDelete == 0 || t.IsDelete == null).Where(t => t.taskType == StaticTaskType.ThirdFlipToBin && t.useFlag == 0).FirstOrDefault();
                        if (task != null)
                        {
                            BaseEquip endEquip = dbContext.BaseEquip.First(t => t.objid == 35);
                            BaseEquip startEquip = StaticData.BaseEquip.First(t => t.objid == 31);
                            BaseEquip agvEquip = StaticData.BaseEquip.First(t => t.objid == 9);
                            //if (endEquip.emptyCount != (SystemData.maxTray / 2) && endEquip.emptyCount != SystemData.maxTray)                     
                            if (endEquip.emptyCount < SystemData.maxTray)
                            {
                                task.taskType = StaticTaskType.ThirdFlipToBin;
                                task.useFlag = 1;
                                task.taskStatus = 0;
                                task.isEmpty = "1";
                                task.qty = 1;
                                task.nextPointId = agvEquip.objid;
                                task.nextPointNo = agvEquip.agvPositionCode;
                                task.currPointId = startEquip.objid;
                                task.currPointNo = startEquip.agvPositionCode;
                                task.endPointId = endEquip.objid;
                                task.endPointNo = endEquip.agvPositionCode;
                                task.createTime = DateTime.Now;
                                dbContext.Update(task);
                                WcsTaskLog wcsTaskLog = CoreMapper.Map<WcsTaskLog>(task);
                                dbContext.Add(wcsTaskLog);
                                dbContext.SaveChanges();
                                _logger.Info("三楼AGV 生成空托盘入收集架任务：" + task.objid);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    if (ex is PlcException)
                    {

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

        public void MonitorInLocatorPoint()
        {
            using var scope = _host.Services.CreateScope();
            using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
            BaseEquip baseEquip = StaticData.BaseEquip.First(t => t.objid == 9);
            while (true)
            {
                try
                {
                    dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                    //获取条码号,如果该条码任务存在就继续任务,如果条码不存在,创建入库任务并调度agv
                    var taskList = dbContext.WcsTask.Where(t => t.nextPointId == baseEquip.objid).Where(t => t.useFlag == 1).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.ThirdRemove)//移库
                            {
                                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.ThirdRawIn)//提升机-库位
                            {
                                BaseEquip startEquip = StaticData.BaseEquip.First(t => t.objid == 3);
                                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.ThirdRawToFlip)//库位-翻转机
                            {
                                BasePlcpoint basePlcpoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "putTray");
                                var callMaterial = StaticData.PlcDic[2].Read(basePlcpoint.plcpointAddress);
                                if (callMaterial != null && Convert.ToBoolean(callMaterial))
                                {
                                    WmsRawOutstockDetail? wmsRawOutstockDetail = dbContext.WmsRawOutstockDetail.FirstOrDefault(t => t.rawOutstockId == item.orderId && t.executeStatus == "0");
                                    if (wmsRawOutstockDetail != null)
                                    {
                                        wmsRawOutstockDetail.executeStatus = "1";
                                        wmsRawOutstockDetail.outstockTime = DateTime.Now;
                                        BaseEquip endEquip = StaticData.BaseEquip.First(t => t.objid == 31);
                                        WmsBaseLocation wmsBaseLocation = dbContext.WmsBaseLocation.First(t => t.locationId == item.currPointId);

                                        var agvTask = new RequestAGVTaskDto
                                        {
                                            reqCode = StaticData.SnowId.NextId().ToString(),
                                            positionCodePath = new List<Position>
                                        {
                                            new ()
                                            {
                                                positionCode=wmsBaseLocation.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(wmsRawOutstockDetail);
                                            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.ThirdTransitToBin)//周转位-收集架
                            {
                                BaseEquip startEquip = dbContext.BaseEquip.First(t => t.objid == item.currPointId);
                                BaseEquip endEquip = dbContext.BaseEquip.First(t => t.objid == item.endPointId);
                                var agvTask = new RequestAGVTaskDto
                                {
                                    reqCode = StaticData.SnowId.NextId().ToString().ToString(),
                                    positionCodePath = new List<Position>
                                    {
                                        new ()
                                        {
                                            positionCode= startEquip.agvPositionCode,
                                            type="00"
                                        },
                                        new ()
                                        {
                                            positionCode=endEquip.agvPositionCode,
                                            type="00"
                                        }
                                    },
                                    taskTyp = baseDictionary.dicValue,
                                    ctnrTyp = "2",
                                    ctnrNum = startEquip.emptyCount.ToString()
                                };
                                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.ThirdFlipToBin)//翻转机-收集架
                            {
                                BaseEquip startEquip = dbContext.BaseEquip.First(t => t.objid == item.currPointId);
                                BaseEquip endEquip = dbContext.BaseEquip.First(t => t.objid == item.endPointId);
                                var agvTask = new RequestAGVTaskDto
                                {
                                    reqCode = StaticData.SnowId.NextId().ToString().ToString(),
                                    positionCodePath = new List<Position>
                                    {
                                        new ()
                                        {
                                            positionCode=startEquip.agvPositionCode,
                                            type="00"
                                        },
                                        new ()
                                        {
                                            positionCode=endEquip.agvPositionCode,
                                            type="00"
                                        }
                                    },
                                    taskTyp = baseDictionary.dicValue,
                                    ctnrTyp = "2",
                                    ctnrNum = "1"
                                };
                                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.ThirdBinToTransit)//收集架-周转区
                            {
                                BaseEquip startEquip = dbContext.BaseEquip.First(t => t.objid == item.currPointId);
                                BaseEquip endEquip = dbContext.BaseEquip.First(t => t.objid == item.endPointId);

                                var agvTask = new RequestAGVTaskDto
                                {
                                    reqCode = StaticData.SnowId.NextId().ToString().ToString(),
                                    positionCodePath = new List<Position>
                                    {
                                        new ()
                                        {
                                            positionCode=startEquip.agvPositionCode,
                                            type="00"
                                        },
                                        new ()
                                        {
                                            positionCode=endEquip.agvPositionCode,
                                            type="00"
                                        }
                                    },
                                    taskTyp = baseDictionary.dicValue,
                                    ctnrTyp = "2",
                                    ctnrNum = startEquip.emptyCount.ToString()
                                };
                                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.ThirdTransitToLift)//周转区-提升机
                            {
                                BaseEquip startEquip = dbContext.BaseEquip.First(t => t.objid == item.currPointId);
                                BaseEquip lineEquip = dbContext.BaseEquip.First(t => t.objid == 3);
                                if (lineEquip.equipStatus == 0)
                                {

                                    var agvTask = new RequestAGVTaskDto
                                    {
                                        reqCode = StaticData.SnowId.NextId().ToString().ToString(),
                                        positionCodePath = new List<Position>
                                        {
                                            new()
                                            {
                                                positionCode =startEquip.agvPositionCode,
                                                type = "00"
                                            },
                                            new()
                                            {
                                                positionCode = lineEquip.equipNo,
                                                type = "00"
                                            }
                                        },
                                        taskTyp = baseDictionary.dicValue,
                                        ctnrTyp = "2",
                                        ctnrNum = startEquip.emptyCount.ToString()
                                    };
                                    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.ThirdTransitToSecond)//三楼空托盘转运到二楼
                            {
                                BaseEquip lineEquip = dbContext.BaseEquip.First(t => t.objid == 3);
                                BaseEquip startEquip = StaticData.BaseEquip.First(t => t.objid == item.currPointId);
                                if (lineEquip.equipStatus == 0)
                                {
                                    var agvTask = new RequestAGVTaskDto
                                    {
                                        reqCode = StaticData.SnowId.NextId().ToString().ToString(),
                                        positionCodePath = new List<Position>
                                        {
                                            new()
                                            {
                                                positionCode = startEquip.agvPositionCode,
                                                type = "00"
                                            },
                                            new()
                                            {
                                                positionCode = lineEquip.equipNo,
                                                type = "00"
                                            }
                                        },
                                        taskTyp = baseDictionary.dicValue,
                                        ctnrTyp = "2",
                                        ctnrNum = startEquip.emptyCount.ToString()
                                    };
                                    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.taskStatus == 3)
                                {
                                    if (item.currPointId == 3)//从提升机开始
                                    {
                                        BasePlcpoint lineSignal = StaticData.BasePlcpointList.First(t => t.plcpointNo == "linesignal03");
                                        BasePlcpoint Rfid = StaticData.BasePlcpointList.First(t => t.plcpointNo == "RFID003");
                                        var lineSignalValue = StaticData.PlcDic[0].Read(lineSignal.plcpointAddress);
                                        var RfidValue = StaticData.PlcDic[0].ReadRFID(Rfid.plcpointAddress);
                                        if (lineSignalValue == null || item.containerNo != RfidValue || Convert.ToInt32(lineSignalValue) == 0)
                                        {
                                            _logger.Info($"三楼Agv继续任务失败,所取货物与任务不符，任务货物为{item.containerNo},RFID为{RfidValue},线路信号为{lineSignalValue}");
                                            Console.WriteLine($"{DateTime.Now}:三楼Agv继续任务失败,所取货物与任务不符，任务货物为{item.containerNo},RFID为{RfidValue},线路信号为{lineSignalValue}");
                                            Thread.Sleep(1000);
                                            continue;
                                        }
                                    }
                                    if (item.endPointId == 3)
                                    {
                                        BasePlcpoint lineSignal = StaticData.BasePlcpointList.First(t => t.plcpointNo == "linesignal03");
                                        var lineSignalValue = StaticData.PlcDic[0].Read(lineSignal.plcpointAddress);
                                        if (lineSignalValue == null || Convert.ToInt32(lineSignalValue) == 1)
                                        {
                                            _logger.Info($"三楼Agv继续任务失败,提升机有货物");
                                            Console.WriteLine($"{DateTime.Now}:三楼Agv继续任务失败,提升机有货物");
                                            Thread.Sleep(1000);
                                            continue;
                                        }
                                    }
                                    var agvTask = new RequestAGVTaskDto
                                    {
                                        reqCode = StaticData.SnowId.NextId().ToString().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.currPointId == 3)//从接驳位出发
                                    {
                                        BaseEquip lineEquip = dbContext.BaseEquip.First(t => t.objid == 3);
                                        lineEquip.equipStatus = 0;
                                        dbContext.Update(lineEquip);
                                    }
                                    if (item.taskType == StaticTaskType.ThirdRemove)//移库
                                    {
                                        using var transaction = dbContext.Database.BeginTransaction();
                                        try
                                        {
                                            var wmsRawStock = dbContext.WmsRawStock.Where(t => t.locationCode == item.endPointNo).FirstOrDefault();
                                            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 (wmsRawStock != null)
                                            {
                                                wmsRawStock.locationCode = item.endPointNo;
                                                dbContext.Update(wmsRawStock);
                                            }
                                            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.containerNo,
                                                updateTime = DateTime.Now
                                            });
                                            dbContext.Remove(item);
                                            dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 6 });

                                            #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 = wmsRawStock.instockBatch;
                                            wmsMove.MaterialId = wmsRawStock.materialId;
                                            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)wmsRawStock.materialId;
                                            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


                                            dbContext.SaveChanges();
                                            transaction.Commit();
                                        }
                                        catch (Exception ex)
                                        {
                                            try
                                            {
                                                transaction.Rollback();
                                            }
                                            catch
                                            {

                                            }
                                            _logger.Error(ex.Message + "\n" + ex.StackTrace);
                                        }
                                    }
                                    if (item.taskType == StaticTaskType.ThirdRawIn)//入库
                                    {
                                        WmsBaseLocation wmsBaseLocation = dbContext.WmsBaseLocation
                                             .First(t => t.locationId == item.endPointId && t.warehouseFloor == 3);
                                        wmsBaseLocation.locationStatus = "1";
                                        wmsBaseLocation.containerCode = item.containerNo;
                                        wmsBaseLocation.updateTime = DateTime.Now;
                                        wmsBaseLocation.updateBy = "WCS";
                                        var mesBasePalletInfo = dbContext.MesBasePalletInfo.FirstOrDefault(t => t.palletInfoCode == item.containerNo);
                                        if (mesBasePalletInfo != null)
                                        {
                                            var mesBaseBarcodeInfo = dbContext.MesBaseBarcodeInfo.FirstOrDefault(t => t.barcodeInfo == mesBasePalletInfo.materialBarcode);
                                            if (mesBaseBarcodeInfo != null)
                                            {
                                                var wmsRawStock = new WmsRawStock()
                                                {
                                                    rawStockId = StaticData.SnowId.NextId(),
                                                    activeFlag = "1",
                                                    saleOrderId = mesBaseBarcodeInfo.saleOrderId == null ? 0 : mesBaseBarcodeInfo.saleOrderId,
                                                    stockType = "1",
                                                    supplierId = mesBaseBarcodeInfo.manufacturerId,
                                                    qualityStatus = "1",
                                                    completeFlag = "1",
                                                    createBy = "WCS",
                                                    createDate = DateTime.Now,
                                                    frozenAmount = 0,
                                                    instockBatch = mesBaseBarcodeInfo.barcodeInfo,
                                                    instockDate = DateTime.Now,
                                                    locationCode = wmsBaseLocation.locationCode,
                                                    materialId = mesBaseBarcodeInfo.materialId,
                                                    occupyAmount = 0,
                                                    palletInfoCode = item.containerNo,
                                                    safeFlag = mesBaseBarcodeInfo.safeFlag,
                                                    totalAmount = 1,
                                                    warehouseFloor = 3,
                                                    warehouseId = 311
                                                };
                                                WmsRawInstock wmsRawInstock = new WmsRawInstock()
                                                {
                                                    taskCode = item.taskCode,
                                                    materialBarCode = mesBaseBarcodeInfo.barcodeInfo,
                                                    materialBatchCode = mesBaseBarcodeInfo.batchCode,
                                                    applyBy = "wcs",
                                                    applyDate = System.DateTime.Now,
                                                    purchaseOrderId = mesBaseBarcodeInfo.PurchaseOrderId,

                                                    beginTime = System.DateTime.Now,
                                                    endTime = DateTime.Now,
                                                    locationCode = wmsBaseLocation.locationCode,
                                                    executeStatus = "2",
                                                    instockAmount = 1,
                                                    instockType = item.fromFloorNo == 1 ? "1" : "3",

                                                    materialId = mesBaseBarcodeInfo.materialId,
                                                    operationType = "3",
                                                    palletInfoCode = mesBaseBarcodeInfo.palletInfoCode,
                                                    poNo = mesBaseBarcodeInfo.poNo,
                                                    warehouseId = 311
                                                };
                                                SystemData.UnLockOutLocation(wmsBaseLocation, dbContext);
                                                dbContext.Add(wmsRawInstock);
                                                dbContext.Add(wmsRawStock);
                                                dbContext.Update(wmsBaseLocation);
                                                dbContext.Remove(item);
                                                dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog { taskStatus = 6 });
                                                dbContext.SaveChanges();
                                            }
                                        }
                                    }
                                    else if (item.taskType == StaticTaskType.ThirdTransitToBin)//周转区-收集架，暂不使用
                                    {
                                        BaseEquip startEquip = dbContext.BaseEquip.First(t => t.objid == item.currPointId);
                                        BaseEquip endEquip = dbContext.BaseEquip.First(t => t.objid == item.endPointId);
                                        startEquip.emptyCount = 0;
                                        startEquip.equipStatus = 0;
                                        startEquip.updateTime = DateTime.Now;
                                        startEquip.updateBy = "WCS";
                                        endEquip.emptyCount += item.qty;
                                        endEquip.equipStatus = 1;
                                        endEquip.updateTime = DateTime.Now;
                                        endEquip.updateBy = "WCS";
                                        dbContext.Update(startEquip);
                                        dbContext.Update(endEquip);
                                        dbContext.Remove(item);
                                        dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog { taskStatus = 6 });
                                        dbContext.SaveChanges();
                                    }
                                    else if (item.taskType == StaticTaskType.ThirdRawToFlip)//原材料出库
                                    {
                                        WmsBaseLocation wmsBaseLocation = dbContext.WmsBaseLocation
                                          .First(t => t.locationId == item.currPointId);
                                        wmsBaseLocation.locationStatus = "1";
                                        wmsBaseLocation.containerCode = null;
                                        wmsBaseLocation.updateTime = DateTime.Now;
                                        wmsBaseLocation.updateBy = "WCS";

                                        WmsRawOutstock? wmsRawOutstock = dbContext.WmsRawOutstock.FirstOrDefault(t => t.rawOutstockId == item.orderId);
                                        WmsRawStock? wmsRawStock = dbContext.WmsRawStock.Where(t => t.locationCode == item.currPointNo).FirstOrDefault();

                                        if (wmsRawOutstock != null && wmsRawStock != null)
                                        {

                                            wmsRawOutstock.realOutstockAmount += 1;
                                            if (wmsRawOutstock.realOutstockAmount >= wmsRawOutstock.outstockAmount)
                                            {
                                                wmsRawOutstock.endTime = DateTime.Now;
                                                wmsRawOutstock.executeStatus = "2";
                                            }


                                            WmsRawOutstockDetail newWmsRawOutstockDetail = new WmsRawOutstockDetail();
                                            newWmsRawOutstockDetail.rawOutstockId = wmsRawOutstock.rawOutstockId;
                                            newWmsRawOutstockDetail.taskCode = wmsRawOutstock.taskCode;
                                            newWmsRawOutstockDetail.warehouseId = wmsRawOutstock.warehouseId;
                                            newWmsRawOutstockDetail.locationCode = wmsRawStock.locationCode;
                                            newWmsRawOutstockDetail.materialBarcode = wmsRawStock.instockBatch;
                                            newWmsRawOutstockDetail.materialId = wmsRawStock.materialId;
                                            MesBaseBarcodeInfo? mesBaseBarcodeInfo = dbContext.MesBaseBarcodeInfo.Where(t => t.barcodeInfo == wmsRawStock.instockBatch).FirstOrDefault();
                                            if (mesBaseBarcodeInfo != null)
                                            {
                                                newWmsRawOutstockDetail.instockBatch = mesBaseBarcodeInfo.batchCode;
                                                newWmsRawOutstockDetail.materialProductionDate = mesBaseBarcodeInfo.productionDate;
                                            }
                                            newWmsRawOutstockDetail.planAmount = wmsRawOutstock.outstockAmount;
                                            newWmsRawOutstockDetail.outstockAmount = wmsRawOutstock.realOutstockAmount;
                                            newWmsRawOutstockDetail.executeStatus = "2";
                                            newWmsRawOutstockDetail.outstockPerson = wmsRawOutstock.applyBy;
                                            newWmsRawOutstockDetail.outstockTime = DateTime.Now;
                                            newWmsRawOutstockDetail.outstockWay = "2";
                                            newWmsRawOutstockDetail.createBy = "WCS";
                                            newWmsRawOutstockDetail.createDate = DateTime.Now;
                                            newWmsRawOutstockDetail.stackAmount = 1;

                                            BaseEquip endEquip = dbContext.BaseEquip.First(t => t.objid == 31);
                                            endEquip.emptyCount = 1;
                                           
                                            SystemData.UnLockOutLocation(wmsBaseLocation, dbContext);
                                            dbContext.Update(endEquip);
                                            dbContext.Update(wmsRawOutstock);
                                            dbContext.Remove(wmsRawStock);
                                            dbContext.Add(newWmsRawOutstockDetail);
                                            dbContext.Update(wmsBaseLocation);
                                            WcsTask wcsTask = CoreMapper.Map<WcsTask>(item);
                                            wcsTask.objid = StaticData.SnowId.NextId();
                                            wcsTask.taskStatus = 0;
                                            wcsTask.useFlag = 0;
                                            wcsTask.taskType = StaticTaskType.ThirdFlipToBin;
                                            wcsTask.createBy = "WCS";
                                            wcsTask.createTime = DateTime.Now;
                                            dbContext.Remove(item);
                                            dbContext.Add(wcsTask);
                                            dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog { taskStatus = 6 });
                                            dbContext.SaveChanges();

                                        }
                                    }
                                    else if (item.taskType == StaticTaskType.ThirdFlipToBin)//翻转机就到收集架
                                    {
                                        MesBasePalletInfo? mesBasePalletInfo = dbContext.MesBasePalletInfo.FirstOrDefault(t => t.palletInfoCode == item.containerNo);
                                        if (mesBasePalletInfo != null)
                                        {
                                            BasePlcpoint basePlcpoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "GetTrayOver");
                                            StaticData.PlcDic[2].WriteToPoint(basePlcpoint.plcpointAddress, true, basePlcpoint.plcpointLength.ToString());
                                            IsTrayGet = true;
                                            _logger.Info("通知PLC已经取走信号:true");
                                            MesBaseBarcodeInfo? mesBaseBarcodeInfo = dbContext.MesBaseBarcodeInfo.Where(t => t.palletInfoCode == item.containerNo).FirstOrDefault();
                                            if (mesBaseBarcodeInfo != null)
                                            {
                                                mesBaseBarcodeInfo.palletInfoCode = null;
                                                dbContext.Update(mesBaseBarcodeInfo);
                                            }
                                            mesBasePalletInfo.bindAmount = null;
                                            mesBasePalletInfo.materialBarcode = null;
                                            mesBasePalletInfo.materialCode = null;
                                            mesBasePalletInfo.materialId = null;
                                            mesBasePalletInfo.materialName = null;
                                            mesBasePalletInfo.updateBy = "WCS";
                                            mesBasePalletInfo.updateTime = DateTime.Now;
                                            dbContext.Update(mesBasePalletInfo);
                                            BaseEquip emptyEquip = dbContext.BaseEquip.First(t => t.objid == 35);
                                            BaseEquip endEquip = dbContext.BaseEquip.First(t => t.objid == 31);
                                            endEquip.emptyCount = 0;
                                            dbContext.Update(endEquip);
                                            emptyEquip.emptyCount += 1;
                                            emptyEquip.equipStatus = 1;
                                            emptyEquip.updateTime = DateTime.Now;
                                            emptyEquip.updateBy = "WCS";
                                            dbContext.Update(emptyEquip);
                                            dbContext.Remove(item);
                                            dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog { taskStatus = 6 });
                                            dbContext.SaveChanges();
                                        }
                                    }
                                    else if (item.taskType == StaticTaskType.ThirdBinToTransit)//收集架-周转区
                                    {
                                        BaseEquip emptyEquip = dbContext.BaseEquip.First(t => t.objid == 35);
                                        BaseEquip endEquip = dbContext.BaseEquip.First(t => t.objid == item.endPointId);
                                        emptyEquip.emptyCount = 0;
                                        emptyEquip.updateTime = DateTime.Now;
                                        emptyEquip.updateBy = "WCS";
                                        endEquip.emptyCount = item.qty;
                                        endEquip.equipStatus = 1;
                                        endEquip.updateTime = DateTime.Now;
                                        endEquip.updateBy = "WCS";
                                        dbContext.Update(endEquip);
                                        dbContext.Update(emptyEquip);
                                        dbContext.Remove(item);
                                        dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog { taskStatus = 6 });
                                        dbContext.SaveChanges();
                                    }
                                    else if (item.taskType == StaticTaskType.ThirdTransitToLift || item.taskType == StaticTaskType.ThirdTransitToSecond)//周转区-提升机
                                    {
                                        BaseEquip startEquip = dbContext.BaseEquip.First(t => t.objid == item.currPointId);
                                        BaseEquip lineEquip = StaticData.BaseEquip.First(t => t.objid == 3);
                                        startEquip.emptyCount = 0;
                                        startEquip.equipStatus = 0;
                                        startEquip.updateTime = DateTime.Now;
                                        startEquip.updateBy = "WCS";
                                        dbContext.Update(startEquip);
                                        BaseEquip endEquip = StaticData.BaseEquip.First(t => t.objid == item.endPointId);
                                        item.nextPointId = lineEquip.objid;
                                        item.nextPointNo = lineEquip.equipNo;
                                        item.fromFloorNo = 3;
                                        item.floorNo = endEquip.floorNo;
                                        item.taskStatus = 6;
                                        dbContext.Update(item);
                                        dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog { taskStatus = 6 });
                                        dbContext.SaveChanges();
                                    }
                                }
                            }
                        }
                        break;
                    }
                }
                catch (Exception ex)
                {
                    if (ex is PlcException)
                    {

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