using PlcSiemens.Core.Extension;
using ServiceCenter.Extensions;
using ServiceCenter.Logs;
using ServiceCenter.SqlSugars;
using SqlSugar;
using System.ComponentModel;
using WCS.Core;
using WCS.Entity;
using WCS.Entity.Protocol.Station;
using WCS.WorkEngineering.Extensions;
using WCS.WorkEngineering.WebApi.Controllers;
using WCS.WorkEngineering.Worlds;
using TaskStatus = WCS.Entity.TaskStatus;

namespace WCS.WorkEngineering.Systems
{
    /// <summary>
    ///  分流点
    /// </summary>
    [BelongTo(typeof(SortingBranchWorld))]
    [Description("环形库分流点")]
    public class 环形库分流点 : DeviceSystem<Device<IStation520, IStation521, IStation523, IStation91>>
    {
        protected override bool ParallelDo => true;

        public override void Do(Device<IStation520, IStation521, IStation523, IStation91> obj)
        {
            if (obj.Data.VoucherNo != obj.Data2.VoucherNo)
            {
                if (obj.Data2.TaskNumber != 0 && obj.Data2.TaskNumber != 2)
                {
                    obj.Data.TaskNumber = obj.Data2.TaskNumber;
                    World.Log($"复写:{obj.Data.TaskNumber}");
                }
                World.Log($"凭证号不一致,DB520:{obj.Data.VoucherNo}-DB521:{obj.Data2.VoucherNo}", LogLevelEnum.Mid);
                return;
            }

            if (obj.Data3.Status.HasFlag(StationStatus.Run))
            {
                World.Log("设备运行中");
                return;
            }

            ;
            if (!obj.Data3.Status.HasFlag(StationStatus.OT_Status))
            {
                World.Log("站台货物信息与实际占用不一致", LogLevelEnum.Mid);
                return;
            }

            if (!obj.Data3.Status.HasFlag(StationStatus.PH_Status))
            {
                World.Log("站台无光电信息", LogLevelEnum.Mid);
                return;
            }
            ;
            if (obj.Data2.Request != 1)
            {
                World.Log("无请求", LogLevelEnum.Mid);
                return;
            }

            var isPut = false;
            var nextAdd = GetNext(obj);
            if (nextAdd == 9999) return;
            var goodsType = obj.Data4.Length.ToInt();
            int taskId = 0;
            SqlSugarHelper.Do(_db =>
            {
                var db = _db.Default;
                var taskInfo = db.Queryable<WCS_TaskInfo>().UpdLock().First(v => v.ID == obj.Data2.TaskNumber && v.Status < TaskStatus.FinishOfShunt && !v.BarCode.Contains("Error"));
                if (obj.Data2.TaskNumber == 1 || obj.Data2.TaskNumber == 3 || obj.Data2.TaskNumber == 2)
                {
                    var type = goodsType.ToString();
                    //找到一条起点是当前位置且状态小于2的任务
                    taskInfo = db.Queryable<WCS_TaskInfo>().UpdLock().OrderBy(x => x.AddTime).First(x => x.AddrFrom == obj.Entity.Code && x.BarCode.Contains("Error") && x.AddrNext == null && x.GoodsType == goodsType);
                    if (taskInfo == null)
                    {
                        if (obj.Data2.TaskNumber == 1)
                        {
                            WmsApi.PalletizingCreateseErrorTasks(obj.Entity.Code, type);
                        }
                        //bc质量
                        else if (obj.Data2.TaskNumber == 3)
                        {
                            WmsApi.PalletizingCreateseErrorTasks(obj.Entity.Code, type, 3);
                        }
                        //南北流错
                        else if (obj.Data2.TaskNumber == 2)
                        {
                            WmsApi.PalletizingCreateseErrorTasks(obj.Entity.Code, type, 2);
                        }
                        return;
                    }
                    if (taskInfo.Status == TaskStatus.NewBuild)
                    {
                        World.Log($"等待任务{taskInfo.ID}完成初始化");
                        return;
                    }
                }
                else if (taskInfo == null)
                {
                    World.Log($"未找到对应的WCS任务{obj.Data2.TaskNumber}", LogLevelEnum.Mid);
                    return;
                }
                else if (taskInfo.AddTime < DateTime.Now.AddHours(-12) && obj.Data2.TaskNumber == taskInfo.ID)
                {
                    obj.Data.TaskNumber = 1;
                    obj.Data.GoodsEnd = obj.Entity.Code.ToShort();
                    obj.Data.VoucherNo++;
                    World.Log($"超时执行记录:任务号[{taskInfo.ID}]-[{obj.Data.TaskNumber}]-[{obj.Data.VoucherNo}]");
                    return;
                }
                else if (taskInfo.Grade != null && (taskInfo.Grade.ToUpper() != "A") && obj.Data2.TaskNumber == taskInfo.ID)
                {
                    obj.Data.TaskNumber = 3;
                    obj.Data.GoodsEnd = obj.Entity.Code.ToShort();
                    obj.Data.VoucherNo++;
                    World.Log($"BC执行记录:任务号[{taskInfo.ID}]-[{obj.Data.TaskNumber}]-[{obj.Data.VoucherNo}]");
                    return;
                }

                if (!taskInfo.BarCode.Contains("Error"))
                {
                    switch (goodsType)

                    {
                        case 9:
                            if (!taskInfo.BarCode.Contains("HAWS09")) throw new Exception("外检结果与任务条码不匹配");
                            break;

                        case 18:
                            if (!taskInfo.BarCode.Contains("HAWS18")) throw new Exception("外检结果与任务条码不匹配");
                            break;

                        case 34:
                            if (!taskInfo.BarCode.Contains("HAWS34")) throw new Exception("外检结果与任务条码不匹配");
                            break;

                        case 50:
                            if (!taskInfo.BarCode.Contains("HAWS50")) throw new Exception("外检结果与任务条码不匹配");
                            break;
                    }
                }

                switch (obj.Entity.Code)
                {
                    case "418":
                        if (taskInfo.WarehouseCode != "1N") //throw new KnownException($"当前任务应该当前往{taskInfo.WarehouseCode}库", LogLevelEnum.Mid);
                        {
                            EditFlow(taskInfo, "1N", db, obj.Entity.Code);
                            return;
                        }
                        break;

                    case "618":
                        if (taskInfo.WarehouseCode != "1S") //throw new KnownException($"当前任务应该当前往{taskInfo.WarehouseCode}库", LogLevelEnum.Mid);
                        {
                            EditFlow(taskInfo, "1S", db, obj.Entity.Code);
                            return;
                        }
                        break;

                    case "818":
                        if (taskInfo.WarehouseCode != "2N") //throw new KnownException($"当前任务应该当前往{taskInfo.WarehouseCode}库", LogLevelEnum.Mid);
                        {
                            EditFlow(taskInfo, "2N", db, obj.Entity.Code);
                            return;
                        }
                        break;

                    case "1018":
                        if (taskInfo.WarehouseCode != "2S") //throw new KnownException($"当前任务应该当前往{taskInfo.WarehouseCode}库", LogLevelEnum.Mid);
                        {
                            EditFlow(taskInfo, "2S", db, obj.Entity.Code);
                            return;
                        }
                        break;

                    case "1218":
                        if (taskInfo.WarehouseCode != "3N") //throw new KnownException($"当前任务应该当前往{taskInfo.WarehouseCode}库", LogLevelEnum.Mid);
                        {
                            EditFlow(taskInfo, "3N", db, obj.Entity.Code);
                            return;
                        }
                        break;

                    case "1418":
                        if (taskInfo.WarehouseCode != "3S") //throw new KnownException($"当前任务应该当前往{taskInfo.WarehouseCode}库", LogLevelEnum.Mid);
                        {
                            EditFlow(taskInfo, "3S", db, obj.Entity.Code);
                            return;
                        }
                        break;
                };

                var isTruss = false; //表示这个工字轮是要去桁架区域码垛的，默认不作处理
                if (goodsType == 18)
                {
                    //判断这个垛型是否是到桁架区域进行码垛
                    isTruss = db.Queryable<BillBomsetgrp>().First(x => x.BomCode.Contains(taskInfo.MatCode) && x.IsStop == 0).IsTruss;
                    if (isTruss)
                    {
                        nextAdd = obj.Entity.Code switch
                        {
                            "418" => 455,
                            "618" => 655,
                            "818" => 855,
                            "1018" => 1055,
                            "1218" => 1255,
                            "1418" => 1455,
                            _ => 9999
                        };
                    }
                }

                taskId = taskInfo.ID;
                if (goodsType != 9 && !isTruss) //09工字轮在环形库分流点只分配下一个地址，不作任何变更
                {
                    taskInfo.AddrNext = nextAdd.ToString();
                    taskInfo.Status = TaskStatus.FinishOfShunt;
                    taskInfo.EditTime = DateTime.Now;
                    taskInfo.WarehouseCode = taskInfo.WarehouseCode.Contains("R") ? taskInfo.WarehouseCode : taskInfo.WarehouseCode + "R";
                    taskInfo.AddrTo = "Robot";
                    taskInfo.GoodsType = goodsType;
                    db.UpdateableRowLock(taskInfo).UpdateColumns(x => new { x.AddrNext, x.Status, x.EditTime, x.WarehouseCode, x.AddrTo, x.GoodsType }).ExecuteCommand();
                    taskInfo.AddWCS_TASK_DTL(db, obj.Entity.Code, nextAdd.ToString(), "工字轮完成环形库分流");
                }
                else
                {
                    taskInfo.AddrNext = nextAdd.ToString();
                    taskInfo.EditTime = DateTime.Now;
                    taskInfo.GoodsType = goodsType;
                    db.UpdateableRowLock(taskInfo).UpdateColumns(x => new { x.AddrNext, x.EditTime, x.GoodsType }).ExecuteCommand();
                    taskInfo.AddWCS_TASK_DTL(db, obj.Entity.Code, nextAdd.ToString(), "工字轮途径环形库分流点");
                }
                isPut = true;
            });
            if (!isPut) return;
            obj.Data.TaskNumber = taskId;
            obj.Data.TaskNumber = taskId;
            obj.Data.GoodsStart = obj.Entity.Code.ToShort();
            obj.Data.GoodsStart = obj.Entity.Code.ToShort();
            obj.Data.GoodsEnd = nextAdd;
            obj.Data.GoodsEnd = nextAdd;
            obj.Data.SetVoucherNo();
            World.Log($"执行记录:任务号[{taskId}]-[{obj.Data.VoucherNo}]");
        }

        private void WriteInfo(Device<IStation520, IStation521, IStation523, IStation91> device, WCS_TaskInfo task)
        {
            device.Data.TaskNumber = 2;
            device.Data.GoodsEnd = device.Entity.Code.ToShort();
            device.Data.VoucherNo++;
            World.Log($"南北流错执行记录:任务号[{task.ID}]-[{device.Data.TaskNumber}]-[{device.Data.VoucherNo}]");
        }

        /// <summary>
        ///  编辑流向
        /// </summary>
        public void EditFlow(WCS_TaskInfo task, string warehouseCode, SqlSugarScopeProvider db, string locCode)
        {
            WmsApi.EditorialFlow(new FjEditorialFlowRequest() { TaskId = task.ID, LocCode = locCode, WareCode = warehouseCode });
            task.WarehouseCode = warehouseCode;
            db.UpdateableRowLock(task);
            task.AddWCS_TASK_DTL(db, locCode, $"变更流向至{warehouseCode}");
        }

        public override bool Select(Device dev)
        {
            return dev.Code is "418" or "618" or "818" or "1018" or "1218" or "1418";
        }

        /// <summary>
        ///  计算非零九的去向
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public short GetNext(Device<IStation520, IStation521, IStation523, IStation91> obj)
        {
            return obj.Data4.Length switch
            {
                9 => obj.Entity.Code switch
                {
                    "418" => 455,
                    "618" => 655,
                    "818" => 855,
                    "1018" => 1055,
                    "1218" => 1255,
                    "1418" => 1455,
                    _ => 9999
                },
                18 => obj.Entity.Code switch
                {
                    "418" => 444,
                    "618" => 644,
                    "818" => 844,
                    "1018" => 1044,
                    "1218" => 1244,
                    "1418" => 1444,
                    _ => 9999
                },
                50 => obj.Entity.Code switch
                {
                    "418" => 426,
                    "618" => 626,
                    "818" => 826,
                    "1018" => 1026,
                    "1218" => 1226,
                    "1418" => 1426,
                    _ => 9999
                },
                34 => obj.Entity.Code switch
                {
                    "418" => 435,
                    "618" => 635,
                    "818" => 835,
                    "1018" => 1035,
                    "1218" => 1235,
                    "1418" => 1435,
                    _ => 9999
                },
                _ => 9999
            };
        }
    }
}