using Khd.Core.Domain.Dto.webapi;
using Khd.Core.Domain.Models;
using Khd.Core.EntityFramework;
using Khd.Core.Library;
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 FiveFloorBearAgv
    {
        private readonly LoggerUtils _logger = new LoggerUtils();
        private readonly IHost _host;
        int FloorNo { get; set; }
        int agvID = 10;
        public FiveFloorBearAgv(IHost host, int floor)
        {
            this._host = host;
            FloorNo = floor;
        }
        /// <summary>
        /// 启动上件扫描监听
        /// </summary>
        public void StartPoint()
        {

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

        public void MonitorInLocatorPoint()
        {
            using var scope = _host.Services.CreateScope();
            using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
            List<int?> taskType = new() { 1, 3, 5, 7 };
            BaseEquip baseEquip = StaticData.BaseEquip.First(t => t.objid == agvID);
            while (true)
            {
                try
                {
                    dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                    var taskList = dbContext.WcsTask
                        .Where(t => t.IsDelete == 0 || t.IsDelete == null)
                        .Where(t => t.nextPointId == agvID)
                        .OrderBy(t => t.createTime).ToList();

                    foreach (var item in taskList)//出库
                    {
                        item.updateTime = DateTime.Now;
                        if (item.taskStatus == 0)//下发任务
                        {
                            BaseEquip startEquip = StaticData.BaseEquip.First(t => t.objid == item.currPointId);
                            BaseEquip endEquip = StaticData.BaseEquip.First(t => t.objid == item.endPointId);
                            BaseDictionary baseDictionary = dbContext.BaseDictionary.First(t => t.objid == item.taskType);
                            var agvTask = new RequestAGVTaskDto
                            {
                                reqCode = StaticData.SnowId.NextId().ToString(),
                                positionCodePath = new List<Position>
                                    {
                                        new ()
                                        {
                                            positionCode=startEquip.agvPositionCode,
                                            type=baseDictionary.agvType
                                        },
                                        new ()
                                        {
                                            positionCode=endEquip.agvPositionCode,
                                            type=baseDictionary.agvType
                                        }
                                    },
                                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.code == "0")
                            {
                                _logger.Info("五楼背负式AGV线程下发任务" + agvTask.ToJsonString());
                                Console.WriteLine(DateTime.Now + ":五楼背负式AGV线程下发任务" + startEquip.agvPositionCode + "," + endEquip.agvPositionCode);
                                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("下发小车任务失败" + result);
                            }
                        }
                        else
                        {
                            //if (item.useFlag == 1)//接料位-工位默认为1，工位到接料位需Mes通知
                            if (item.taskStatus == 4)//通知捡料完成
                            {
                                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 == "成功")
                                {
                                    _logger.Info("五楼背负式AGV线程完成任务" + item.objid);
                                    Console.WriteLine(DateTime.Now + ":五楼背负式AGV线程完成任务" + item.currPointNo + "," + item.endPointNo);
                                    item.taskStatus = 5;
                                    dbContext.Update(item);
                                    dbContext.SaveChanges();
                                    dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 5 });
                                }
                            }
                            else if (item.taskStatus == 7)//通知拿料完成
                            {
                                _logger.Info("五楼背负式AGV线程完成任务" + item.objid);
                                Console.WriteLine(DateTime.Now + ":五楼背负式AGV线程完成任务" + item.currPointNo + "," + item.endPointNo);
                                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 == "成功")
                                {
                                    if (item.taskType == 48)
                                    {
                                        WmsRawReturn? wmsRawReturn = dbContext.WmsRawReturn.Where(t => t.rawReturnId == item.orderId).FirstOrDefault();
                                        if (wmsRawReturn != null)
                                        {
                                            wmsRawReturn.executeStatus = "2";
                                            dbContext.Update(wmsRawReturn);
                                        }
                                    }
                                    dbContext.Remove(item);
                                    dbContext.SaveChanges();
                                    dbContext.WcsTaskLog.Where(t => t.objid == item.objid).Update(t => new WcsTaskLog() { taskStatus = 8 });
                                }
                            }
                        }
                        break;
                    }
                }
                catch (Exception ex)
                {
                    _logger.Error(ex.Message + "\n" + ex.StackTrace);
                }
                finally
                {
                    Thread.Sleep(1000);
                }
            }
        }
    }
}
