using System.ComponentModel;
using WCS.Core;
using WCS.Entity.Protocol.Station;

namespace WCS.WorkEngineering.Systems
{
    /// <summary>
    ///  分线计算09
    /// </summary>
    //[BelongTo(typeof(NoInteractionWorld))]
    [Description("分线计算09")]
    public class 分线计算09 : DeviceSystem<Device<IStation520>>
    {
        protected override bool ParallelDo => true;

        protected override bool SaveLogsToFile => true;

        public override void Do(Device<IStation520> obj)
        {
            //SqlSugarHelper.Do(_db =>
            //{
            //    //获取所有待执行的任务
            //    var db = _db.Default;
            //    var taskList = db.Queryable<WCS_TaskInfo>().Where(x => x.Status == TaskStatus.WaitingToExecute && x.Type == TaskType.SetPlate && x.AddrFrom == "Robot").Take(1).ToList();
            //    //开始对任务进行处理
            //    foreach (var taskInfo in taskList)
            //    {
            //        //TODO：暂时不来考虑动态计算可前往的目标
            //        var nextAdd = taskInfo.WarehouseCode switch
            //        {
            //            "1N" => "455",
            //            "1S" => "455",
            //            "2N" => "455",
            //            "2S" => "455",
            //            "3N" => "455",
            //            "3S" => "455",
            //            _ => "0"
            //        };
            //        //获取这个地址的下一个地址集合
            //        var cacheLineDevList = Device.All.First(x => x.Code == nextAdd).Targets.Where(x => x.HasFlag(DeviceFlags.桁架缓存放行点));
            //        var cacheLineCodes = cacheLineDevList.Select(x => x.Code.ToShort());
            //        var cacheLineList = db.Queryable<WCS_CacheLine>().Includes(x => x.Locations).ToList();

            //        #region 跟据缓存信息寻找可以到达的缓存点

            //        //找到当前任务可用的缓存线信息
            //        var cacheLine = cacheLineList.Where(x => x.Locations.Any(l => l is { InStock: false, IsEmpty: false })).FirstOrDefault(x => cacheLineCodes.Contains(x.LocationNo) && x.MatCodeList.Contains(taskInfo.MatCode) && !x.InStock);

            //        if (cacheLine != null)//这个任务可以直接去一条线体，不需要新建缓存信息
            //        {
            //            //找到这条线体中序号最小的一条位信息 非空置且无货
            //            var cacheLoc = cacheLine.Locations.Where(x => x is { InStock: false, IsEmpty: false }).MinBy(x => x.XYNo);
            //            if (cacheLoc != null)
            //            {
            //                cacheLoc = db.Queryable<WCS_CacheLineLoc>().Single(x => x.Id == cacheLoc.Id);
            //                cacheLoc.InStock = true;
            //                cacheLoc.TaskId = taskInfo.ID;
            //                cacheLoc.EditTime = DateTime.Now;
            //                db.Updateable(cacheLoc).ExecuteCommand();

            //                //WCS任务相关信息
            //                taskInfo.Status = TaskStatus.FinishOfShunt;
            //                taskInfo.AddrNext = cacheLine.LocationNo.ToString();
            //                taskInfo.EditWho = "WCS";
            //                taskInfo.EditTime = DateTime.Now;
            //                taskInfo.AddWCS_TASK_DTL(_db, obj.Entity.Code, taskInfo.AddrNext, $"完成分库计算,目标地址:{cacheLine.LocationNo}");
            //                db.Updateable(taskInfo).ExecuteCommand();
            //                taskInfo.UpdateRedisHash();
            //                return;
            //            }
            //        }

            //        #endregion 跟据缓存信息寻找可以到达的缓存点

            //        #region 初始化一个信息的缓存信息

            //        //找到所有当前轮子可以去的垛形
            //        var palletizingList = db.Queryable<WCS_Palletizing>()
            //            .Includes(x => x.Layers, r => r.Rows, l => l.Locs)
            //            .Where(x => x.MatCodeList.Contains(taskInfo.MatCode) && !x.Finish).ToList().Where(x => x.Layers.SelectMany(x => x.Rows).Any(r => r.LineCode == null)).OrderBy(x => x.AddTime).ToList();
            //        //如果没有对应的垛形信息就初始化一个垛形信息
            //        if (palletizingList.Count <= 0)
            //        {
            //            taskInfo.InitStackStructure();
            //            return;
            //        }
            //        foreach (var palletizing in palletizingList)
            //        {
            //            //TODO:当前不考虑不按顺序码垛的情况
            //            //按码垛顺序找到一个最近的没有码垛成功的行,
            //            //先找层：未空置、未结束 TODO:暂不考虑所有层全部结束，但是垛形信息未清除的情况
            //            var palletizingLayer = palletizing.Layers
            //                .Where(x => !x.IsEmpty)
            //                .Where(x => !x.Finish)
            //                .Where(x => x.MatCodeList.Contains(taskInfo.MatCode))
            //                .Where(x => x.Rows.Any(r => r.CacheLineId == 0))
            //                .MinBy(x => x.LayerNo);
            //            //如果没有哪一层需要这个物料号，就初始化一个新的垛形信息
            //            if (palletizingLayer == null)
            //            {
            //                taskInfo.InitStackStructure();
            //                return;
            //            }

            //            //再找行:未空置、未结束
            //            var palletizingRow = palletizingLayer.Rows.Where(x => x is { IsEmpty: false, Finish: false } && x.MatCodeList.Contains(taskInfo.MatCode) && x.CacheLineId == 0)
            //                .MinBy(x => x.RowNo);
            //            //如果没有哪一行需要这个物料号，就初始化一个新的垛形信息
            //            if (palletizingRow == null)
            //            {
            //                taskInfo.InitStackStructure();
            //                return;
            //            }
            //            //走到这一步就表示没有哪一段线体缓存了当前物料，需要选一段新的线体进行缓存

            //            //TODO:暂时不处理就近分线的逻辑
            //            //获取一个当前可以使用的分配锁
            //            var devCode = cacheLineDevList.Select(x => x.Code.ToShort()).FirstOrDefault(x => !cacheLineList.Select(s => s.LocationNo).Contains(x));
            //            if (devCode == 0)
            //            {
            //                World.Log($"无可用线体:{taskInfo.ID}");
            //                return;
            //            }

            //            //开始初始化缓存位信息
            //            cacheLine = new WCS_CacheLine()
            //            {
            //                LocationNo = devCode,
            //                AddTime = DateTime.Now,
            //                PalletizingRowId = palletizingRow.Id,
            //                InStock = false,
            //                Put = false,
            //                MatCodeList = palletizingRow.MatCodeList
            //            };

            //            var res = db.Insertable(cacheLine).ExecuteReturnEntity();
            //            palletizingRow = db.Queryable<WCS_PalletizingRow>().Includes(x => x.Locs).Single(x => x.Id == palletizingRow.Id);
            //            palletizingRow.Locs = palletizingRow.Locs.OrderBy(x => x.XYNo).ToList();
            //            palletizingRow.CacheLineId = res.Id;
            //            palletizingRow.EditTime = DateTime.Now;
            //            db.Updateable(palletizingRow).ExecuteCommand();

            //            for (var i = 0; i < palletizingRow.Locs.Count; i++)
            //            {
            //                var loc = new WCS_CacheLineLoc()
            //                {
            //                    XYNo = palletizingRow.Locs[i].XYNo,
            //                    InStock = i == 0,
            //                    IsEmpty = palletizingRow.Locs[i].IsEmpty,
            //                    MatCode = palletizingRow.Locs[i].MatCode,
            //                    TaskId = i == 0 ? taskInfo.ID : 0,
            //                    CacheLineId = res.Id
            //                };
            //                db.Insertable(loc).ExecuteCommand();
            //            }

            //            taskInfo.Status = TaskStatus.FinishOfShunt;
            //            taskInfo.AddrNext = devCode.ToString();
            //            taskInfo.EditWho = "WCS";
            //            taskInfo.EditTime = DateTime.Now;
            //            taskInfo.AddWCS_TASK_DTL(_db, obj.Entity.Code, taskInfo.AddrNext, $"完成分库计算,目标地址:{cacheLine.LocationNo}");
            //            db.Updateable(taskInfo).ExecuteCommand();
            //            taskInfo.UpdateRedisHash();
            //            return;
            //        }

            //        #endregion 初始化一个信息的缓存信息
            //    }
            //});
        }

        public override bool Select(Device dev)
        {
            return dev.Code == nameof(分线计算09);
        }
    }

    public class LineCache
    {
        /// <summary>
        ///  位置
        /// </summary>
        public string Location { get; set; }

        /// <summary>
        /// 是否放行
        /// </summary>
        public bool IsPut { get; set; }

        /// <summary>
        ///  具体缓存信息
        /// </summary>
        public List<LineCacheInfo> LineInfos { get; set; }
    }

    /// <summary>
    ///  线体缓存组员
    /// </summary>
    public class LineCacheInfo
    {
        /// <summary>
        ///  序号
        /// </summary>
        public string Index { get; set; }

        /// <summary>
        /// 物料号
        /// </summary>
        public string MatCode { get; set; }

        /// <summary>
        ///  任务号
        /// </summary>
        public int TaskNumber { get; set; }

        /// <summary>
        ///  是否有货
        /// </summary>
        public bool InStock { get; set; }

        /// <summary>
        ///  是否空置
        /// </summary>
        public bool IsEmpty { get; set; }
    }
}
