using PlcSiemens.Core.Extension;
using ServiceCenter;
using ServiceCenter.SqlSugars;
using WCS.Core;
using WCS.Entity;
using WCS.Entity.Protocol.BCR;
using WCS.Entity.Protocol.RGV;
using WCS.Entity.Protocol.Robot;
using WCS.Entity.Protocol.SRM;
using WCS.Entity.Protocol.Station;
using WCS.Entity.Protocol.Truss;
using WCS.WorkEngineering.Extensions;
using WCS.WorkEngineering.Systems;
using DeviceFlags = WCS.WorkEngineering.Extensions.DeviceFlags;

namespace WCS.WorkEngineering
{
    /// <summary>
    /// 业务工程配置信息
    /// </summary>
    public static class WorkStart
    {
        /// <summary>
        ///  初始化 设备信息
        /// </summary>

        public static void InitializeDeviceInfo()
        {
            #region 无交互触发设备

            var devs = new List<string>() { nameof(分线计算09), nameof(桁架码垛区补空托盘任务生成), "出库AGV", "入库AGV", nameof(NoInteractionSystems) };
            foreach (var conv in devs.Select(code => new Device(code)))
            {
                conv.AddProtocol<IStation520>(0, 520, "1");
            }

            #endregion 无交互触发设备

            #region 设置设备IP集合

            ServiceHub.DeviceIPList = new List<string>() { };

            #endregion 设置设备IP集合

            #region 初始化RGV相关信息

            List<RgvSegmentInfo> RgvInfo = new List<RgvSegmentInfo>
            {
                new RgvSegmentInfo( 1, "10.30.37.113"),
                //new RGVSegmentInfo( 2, "10.30.37.118"),
                //new RGVSegmentInfo( 3, "10.30.37.123"),
                //new RGVSegmentInfo( 4, "10.30.37.128"),
                //new RGVSegmentInfo( 5, "10.30.37.133"),
                //new RGVSegmentInfo( 6, "10.30.37.138")
            };

            foreach (var item in RgvInfo)
            {
                var conv = new Device($"RGV{item.Code}");
                conv.AddFlag(DeviceFlags.RGV);
                conv.AddProtocol<IRGV520>(0, 520, item.Ip);
                conv.AddProtocol<IRGV521>(0, 521, item.Ip);
                //conv.AddProtocol<IStation523>(, 523, item.IP);
            }

            #endregion 初始化RGV相关信息

            #region 初始化输送机相关信息

            #region 基本信息

            #region 托盘线输送线

            var tuples = new List<Tuple<string, List<Tuple<int, int>>>>
            {
                new("10.30.37.89",new List<Tuple<int, int>>()
                {
                    new(1601, 1620),
                    new(2501, 2540),
                    new(2701, 2740),
                    new(1661, 1690),
                })
            };

            foreach (var item in tuples)
            {
                var db520 = 0;
                var db521 = 0;
                var db523 = 0;
                foreach (var item1 in item.Item2)
                {
                    for (var i = item1.Item1; i <= item1.Item2; i++)
                    {
                        var conv = new Device(i.ToString());
                        conv.AddFlag(DeviceFlags.输送机);

                        conv.AddProtocol<IStation520>(db520, 520, item.Item1);
                        conv.AddProtocol<IStation521>(db521, 521, item.Item1);
                        conv.AddProtocol<IStation523>(db523, 523, item.Item1);

                        db520 += 14;
                        db521 += 16;
                        db523 += 12;
                    }
                }
            }

            #endregion 托盘线输送线

            #region 满轮输送线

            #region DB523，所有线体都会有DB523

            var mLtuples523 = new List<Tuple<string, List<Tuple<int, int>>>>()
            {
                new("10.30.37.166",new List<Tuple<int, int>>()
                {
                    new(1, 110),
                    new(401, 599),
                })
            };

            foreach (var item in mLtuples523)
            {
                var db523 = 0;
                var db524 = 0;
                foreach (var item1 in item.Item2)
                {
                    for (var i = item1.Item1; i <= item1.Item2; i++)
                    {
                        var conv = new Device(i.ToString());
                        conv.AddFlag(DeviceFlags.输送机);
                        conv.AddProtocol<IStation523>(db523, 523, item.Item1);
                        conv.AddProtocol<IStation524>(db524, 524, item.Item1);

                        db523 += 12;
                        db524 += 16;
                    }
                }
            }

            #endregion DB523，所有线体都会有DB523

            #region 520、521 交互线体会有520、521

            //Item2表示线体号集合，Item1表示IP
            var mLTuples520 = new List<Tuple<string, List<int>>>()
            {
                new("10.30.37.166",new List<int>(){1,22,41,61,418,426,435,444,455,466,480,494,508,522,536,550,564,578})
            };

            foreach (var item in mLTuples520)
            {
                var db520 = 0;
                var db521 = 0;

                foreach (var device in item.Item2.Select(item1 => Device.All.FirstOrDefault(v => v.Code == item1.ToString())))
                {
                    if (device != null)
                    {
                        device.AddProtocol<IStation520>(db520, 520, item.Item1);
                        device.AddProtocol<IStation521>(db521, 521, item.Item1);
                    }

                    db520 += 14;
                    db521 += 16;
                }
            }

            #endregion 520、521 交互线体会有520、521

            #region 满轮扫码器

            //Item2表示线体号集合，Item1表示IP
            var mLTuples83 = new List<Tuple<string, List<int>>>()
            {
                new("10.30.37.166",new List<int>(){1,22,41,61,18})
            };

            foreach (var item in mLTuples83)
            {
                var db83 = 0;

                foreach (var device in item.Item2.Select(item1 => Device.All.FirstOrDefault(v => v.Code == item1.ToString())))
                {
                    device?.AddProtocol<IBCR83>(db83, 83, item.Item1);

                    db83 += 604;
                }
            }

            #endregion 满轮扫码器

            #region 满轮线告诉分拣预分配

            //Item2表示线体号集合，Item1表示IP
            var mLTuples525 = new List<Tuple<string, List<int>>>()
            {
                new("10.30.37.166",new List<int>(){18})
            };

            foreach (var item in mLTuples525)
            {
                var db525 = 0;

                foreach (var device in item.Item2.Select(item1 => Device.All.FirstOrDefault(v => v.Code == item1.ToString())))
                {
                    device?.AddProtocol<IStation525>(db525, 525, item.Item1);
                    db525 += 3266;
                }
            }

            #endregion 满轮线告诉分拣预分配

            #region 外检信息

            //Item2表示线体号集合，Item1表示IP
            var mLTuples91 = new List<Tuple<string, List<int>>>()
            {
                new("10.30.37.166",new List<int>(){418})
            };

            foreach (var item in mLTuples91)
            {
                var db91 = 0;

                foreach (var device in item.Item2.Select(item2 => Device.All.FirstOrDefault(v => v.Code == item2.ToString())))
                {
                    device?.AddProtocol<IStation91>(db91, 91, item.Item1);
                    db91 += 14;
                }
            }

            #endregion 外检信息

            #endregion 满轮输送线

            #endregion 基本信息

            #region 托盘线扫码器

            var bcrInfo = new List<BcrInfo>
            {
                new(new [] { "2532", "2732" }, "10.30.37.89"),
                new(new [] {"RGV1"},"10.30.37.113")
            };

            foreach (var item in bcrInfo)
            {
                for (var i = 0; i < item.DeviceNo.Length; i++)
                {
                    var device = Device.All.FirstOrDefault(v => v.Code == item.DeviceNo[i]);
                    device.AddFlag(DeviceFlags.扫码);
                    var pos = i * 20;
                    device.AddProtocol<IBCR81>(pos, 81, item.Ip);
                }
            }

            #endregion 托盘线扫码器

            #region 外检信息

            List<ShapeInfo> shapeInfo = new List<ShapeInfo>
            {
                new ShapeInfo(new int[] { 2732,2532 }, "10.30.37.89")
            };

            foreach (var item in shapeInfo)
            {
                for (int i = 0; i < item.DeviceNo.Length; i++)
                {
                    var conv = Device.All.FirstOrDefault(x => x.Code == item.DeviceNo[i].ToString());
                    conv.AddFlag(DeviceFlags.外检);
                    int pos = i * 14;
                    conv.AddProtocol<IStation91>(pos, 91, item.Ip);
                }
            }

            #endregion 外检信息

            #endregion 初始化输送机相关信息

            #region 初始化桁架相关信息

            List<TrussSegmentInfo> TrussInfo = new List<TrussSegmentInfo>
            {
                new TrussSegmentInfo( 1, "10.30.37.211"),
            };

            foreach (var item in TrussInfo)
            {
                var conv = new Device($"Truss{item.Code}");
                conv.AddFlag(DeviceFlags.桁架);
                conv.AddProtocol<ITruss520>(0, 520, item.Ip);
                conv.AddProtocol<ITruss521>(0, 521, item.Ip);
                conv.AddProtocol<ITruss523>(0, 523, item.Ip);
            }

            var tuples1 = new List<Tuple<string, List<int>>>
            {
                //桁架
                //new("10.30.37.211",new  List<int>(){1662,1663,1664,1665,1670,1671,1672,1673,1674,1675,1677,1678,1679,1680,1685,1686,1687,1688,1689,1690}),
                new("10.30.37.211",new  List<int>(){1685,1686,1687,1688,1689,1690,1675,1674,1673,1672,1671,1670,1677,1678,1679,1680,1665,1664,1663,1662}),
                //机械臂
                new("10.30.37.230",new  List<int>(){ 1666, 1661}),
            };

            foreach (var item in tuples1)
            {
                var db530 = 0;
                var db531 = 0;
                foreach (var conv in item.Item2.Select(item1 => Device.All.FirstOrDefault(x => x.Code == item1.ToString())))
                {
                    if (item.Item1 == "10.30.37.211")
                    {
                        conv!.AddProtocol<ITruss530>(db530, 530, item.Item1);
                        conv!.AddProtocol<ITruss531>(db531, 531, item.Item1);
                        db530 += 8;
                        db531 += 250;
                    }
                    else
                    {
                        conv!.AddProtocol<IRobot530>(db530, 530, item.Item1);
                        conv!.AddProtocol<IRobot531>(db531, 531, item.Item1);
                        db530 += 8;
                        db531 += 130;
                    }
                }
            }

            #endregion 初始化桁架相关信息

            #region 初始化机械臂相关信息

            List<TrussSegmentInfo> TrussInfo1 = new List<TrussSegmentInfo>
            {
                new TrussSegmentInfo( 1, "10.30.37.230"),
            };

            foreach (var item in TrussInfo1)
            {
                var conv = new Device($"Robot{item.Code}");
                conv.AddFlag(DeviceFlags.Robot);
                conv.AddProtocol<IRobot520>(0, 520, item.Ip);
                conv.AddProtocol<IRobot521>(0, 521, item.Ip);
                conv.AddProtocol<IRobot522>(0, 522, item.Ip);
                //conv.AddProtocol<IRobot530>(0, 521, item.Ip);
                //conv.AddProtocol<IRobot531>(0, 522, item.Ip);
            }

            #endregion 初始化机械臂相关信息

            #region 初始化堆垛机相关信息

            int ip = 41;

            for (int i = 0; i <= 1; i++)
            {
                var srm = new Device($"SRM{i + 1}");
                srm.AddFlag(DeviceFlags.堆垛机);
                ip = i == 0 ? ip : ip + 8;
                //三台堆垛机IP主机位分别是 41、49、57、65、73、81
                srm.AddProtocol<ISRM520>(0, 520, $"10.30.37.{ip}");
                srm.AddProtocol<ISRM521>(0, 521, $"10.30.37.{ip}");
                srm.AddProtocol<ISRM537>(0, 537, $"10.30.37.{ip}");

                //增加巷道
                var tunnel = new Device($"TY{i + 1}");
                tunnel.AddFlag(DeviceFlags.巷道);
            }

            #endregion 初始化堆垛机相关信息

            #region 配置路径信息

            List<RouteInfo> routeInfos = new List<RouteInfo>();

            #region 分拣库一

            routeInfos.AddRange(new List<RouteInfo>() {

                #region 出库路径

                //堆垛机--巷道
                new RouteInfo("SRM1", new string[] { "TY1" }),
                new RouteInfo("SRM2", new string[] { "TY2" }),
                //巷道--一楼堆垛机放货口
                new RouteInfo("TY1", new string[] { "2532" }), //人工取货口
                new RouteInfo("TY2", new string[] { "2732" }),
                new RouteInfo("TY1", new string[] { "2534","2533" }),//AGV取货口
                new RouteInfo("TY2", new string[] { "2734","2733" }),
                //巷道--二楼堆垛机放货口
                new RouteInfo("TY1", new string[] { "1601","1605" }),
                new RouteInfo("TY2", new string[] { "1611","1615" }),
                //二楼堆垛机放货口--二楼拆盘机
                new RouteInfo("1601", new string[] { "1602" }),//非09拆盘机
                new RouteInfo("1611", new string[] { "1612"}),
                new RouteInfo("1605", new string[] { "1606" }),//09拆盘机
                new RouteInfo("1615", new string[] { "1616" }),
                //二楼拆盘机--RGV
                new RouteInfo("1602", new string[] { "RGV1" }),//非09拆盘机
                //new RouteInfo("1612", new string[] { "RGV2"}),
                new RouteInfo("1606", new string[] { "RGV1" }),//09拆盘机
                //new RouteInfo("1616", new string[] { "RGV2" }),
                //RGV--码垛区域
                new RouteInfo("RGV1", new string[] { "1661","1666" }),//北区机械臂码垛区
                //new RouteInfo("RGV2", new string[] { }),//南区机械臂
                new RouteInfo("RGV1", new string[] { "1662","1663","1664","1665", "1670","1671","1672","1673","1674","1675"}),//桁架北区码垛站台
                //new RouteInfo("RGV2", new string[] { }),//南区桁架

                //Robot码垛工位
                new RouteInfo("Robot1", new string[] { "1666" }),

                #endregion 出库路径

                #region 入库

                //一楼人工入库口-巷道
                new RouteInfo("2532", new string[] { "TY1" }),
                new RouteInfo("2732", new string[] { "TY2" }),
                //一楼叠盘机(堆垛机入口)--巷道
                new RouteInfo("2527", new string[] { "TY1" }),
                new RouteInfo("2528", new string[] { "TY1" }),
                new RouteInfo("2727", new string[] { "TY2" }),
                new RouteInfo("2728", new string[] { "TY2" }),
                //一楼AGV入口
                //主线入口--预分配点
                new RouteInfo("1", new string[] { "18" }),
                //预分配点--主线分流点
                new RouteInfo("18", new string[] { "22" }),
                //主线分流点--环形库分流点
                new RouteInfo("22", new string[] { "418" }),
                //环形库分流点--环形库取货点
                new RouteInfo("418", new string[] { "424","433","442" }),
                //环形库分流点--桁架分流点
                new RouteInfo("418", new string[] { "455" }),
                //桁架分流点--桁架缓存放行点
                new RouteInfo("455", new string[] { "466","480","494","508", "522","536","550","564","578"}),
                //桁架分流点--异常缓存放行点
                new RouteInfo("455", new string[] { "491" }),
                //桁架缓存放行点--桁架取货点
                new("466", new[] { "461" }),
                new("480", new[] { "475" }),
                new("494", new[] { "489" }),
                new("508", new[] { "503" }),
                new("522", new[] { "517" }),
                new("536", new[] { "531" }),
                new("550", new[] { "545" }),
                new("564", new[] { "559" }),
                new("578", new[] { "573" }),
                //桁架取货点--桁架
                new("461", new[] { "Truss1" }),
                new("475", new[] { "Truss1" }),
                new("489", new[] { "Truss1" }),
                new("503", new[] { "Truss1" }),
                new("517", new[] { "Truss1" }),
                new("531", new[] { "Truss1" }),
                new("545", new[] { "Truss1" }),
                new("559", new[] { "Truss1" }),
                new("573", new[] { "Truss1" }),
                //桁架--码垛工位
                new("Truss1", new[] { "1662" }),
                new("Truss1", new[] { "1663" }),
                new("Truss1", new[] { "1664" }),
                new("Truss1", new[] { "1665" }),
                new("Truss1", new[] { "1670" }),
                new("Truss1", new[] { "1671" }),
                new("Truss1", new[] { "1672" }),
                new("Truss1", new[] { "1673" }),
                new("Truss1", new[] { "1674" }),
                new("Truss1", new[] { "1675" }),
                //码垛工位--RGV
                new RouteInfo("1661", new string[] { "RGV1" }),//机械手码垛工位
                new RouteInfo("1666", new string[] { "RGV1" }),
                new RouteInfo("1662", new string[] { "RGV1" }),//绗架码垛工位
                new RouteInfo("1663", new string[] { "RGV1" }),
                new RouteInfo("1664", new string[] { "RGV1" }),
                new RouteInfo("1665", new string[] { "RGV1" }),
                new RouteInfo("1670", new string[] { "RGV1" }),
                new RouteInfo("1671", new string[] { "RGV1" }),
                new RouteInfo("1672", new string[] { "RGV1" }),
                new RouteInfo("1673", new string[] { "RGV1" }),
                new RouteInfo("1674", new string[] { "RGV1" }),
                new RouteInfo("1675", new string[] { "RGV1" }),
                //RGV--RGV放货点
                new RouteInfo("RGV1", new string[] { "1604" }),
                //RGV放货点--堆垛机取货口
                new RouteInfo("1604", new string[] { "1603" }),//北侧

                //二楼堆垛机入库--巷道
                new RouteInfo("1603", new string[] { "TY1" }),//北侧
                new RouteInfo("1613", new string[] { "TY2" }),//南侧

                //巷道--堆垛机
                new RouteInfo("TY1", new string[] { "SRM1" }),
                new RouteInfo("TY2", new string[] { "SRM2" }),

                //线体取货位--Robot
                new RouteInfo("442", new string[] { "Robot1" }),
                new RouteInfo("433", new string[] { "Robot1" }),
                new RouteInfo("424", new string[] { "Robot1" }),

                #endregion 入库
            });

            #endregion 分拣库一

            foreach (var item in routeInfos)
            {
                var device = Device.All.FirstOrDefault(x => x.Code == item.DeviceCode);
                device.AddTarget(item.NextList);

                foreach (var next in item.NextList)
                {
                    var dev = Device.All.FirstOrDefault(x => x.Code == next);
                    dev.Parent = device;
                }
            }

            #endregion 配置路径信息

            #region 添加设备组

            var tuples2 = new List<Tuple<string, List<string>>>()
            {
                //环形库一北侧机械手取货位
                new("424",new List<string> {"424","425"}),
                new("433",new List<string> {"433","434"}),
                new("442",new List<string> {"442","443"})
            };
            foreach (var item in tuples2)
            {
                var device = Device.All.FirstOrDefault(x => x.Code == item.Item1);
                device.AddDeviceGroup(item.Item2.ToArray());
            }

            #endregion 添加设备组

            #region 标签配置

            Dictionary<DeviceFlags, List<string>> devices = new Dictionary<DeviceFlags, List<string>>
            {
                { DeviceFlags.入库, new List<string>() { "2532", "2533", "2534", "2732", "2733", "2734","1603" } },
                { DeviceFlags.出库, new List<string>() { "2532", "2533", "2534", "2732", "2733", "2734" } },
                { DeviceFlags.扫码, new List<string>() { "2532", "2732" } },
                { DeviceFlags.一列堆垛机, new List<string>() { "SRM1"/*, "SRM3", "SRM5"*/} },
                { DeviceFlags.二列堆垛机, new List<string>() { "SRM2"/*, "SRM4", "SRM6"*/ } },
                { DeviceFlags.一楼扫码,new List<string>(){ "2532","2732"} },
                { DeviceFlags.一楼叠盘机,new List<string>() { "2527","2528","2727","2728"} },
                { DeviceFlags.主线分流点,new List<string>() { "22","41","61"} },
                { DeviceFlags.满轮主线第一次扫码,new List<string>() { "1"} },
                { DeviceFlags.环形库分流点,new List<string>(){ "418"} },
                { DeviceFlags.桁架分流点,new List<string>() { "455" } },
                { DeviceFlags.桁架缓存放行点, new List<string>(){ "466", "480", "494", "508","522","536" } },
                { DeviceFlags.桁架取货点, new List<string>(){ "461", "475", "489", "503","517","531" } },
                { DeviceFlags.拆盘机09, new List<string>(){ "1606" } },
                { DeviceFlags.拆盘机非09, new List<string>(){ "1602" } },
                { DeviceFlags.桁架码垛位, new List<string>(){ "1670", "1671", "1672", "1673", "1674", "1675","1664","1662","1665" } },
                { DeviceFlags.环形库码垛工位, new List<string>(){ "1666" } },
                { DeviceFlags.AGV取货站台口, new List<string>(){ "2533", "2534", "2734" } },
                { DeviceFlags.Robot, new List<string>(){ "Robot1" } },
        };

            devices.ForEach(item =>
            {
                item.Value.ForEach(code =>
                {
                    var device = Device.All.FirstOrDefault(v => v.Code == code);
                    device.AddFlag(item.Key);
                });
            });

            #endregion 标签配置
        }

        /// <summary>
        ///  初始化数据库连接
        /// </summary>
        /// <param name="datas"></param>
        public static void InitDB(this List<DataBaseConnectionString> datas)
        {
            //初始化数据库
            SqlSugarHelper.Do(db =>
            {
                foreach (var connectionString in datas!)
                {
                    var _db = db.Connect.GetConnectionScope(connectionString.Key);
                    switch (connectionString.Key)
                    {
                        case "WCSDB"://WCS基本数据库
                            SqlSugarHelper.SetDefault(connectionString.Key);
                            _db.CodeFirst.InitTables(typeof(WCS_PlcData));
                            _db.CodeFirst.InitTables(typeof(WCS_TaskInfo));
                            _db.CodeFirst.InitTables(typeof(WCS_TaskDtl));
                            _db.CodeFirst.InitTables(typeof(WCS_TaskOld));
                            _db.CodeFirst.InitTables(typeof(WCS_AgvTaskInfo));
                            _db.CodeFirst.InitTables(typeof(WCS_Palletizing));
                            _db.CodeFirst.InitTables(typeof(WCS_PalletizingLayer));
                            _db.CodeFirst.InitTables(typeof(WCS_PalletizingRow));
                            _db.CodeFirst.InitTables(typeof(WCS_PalletizingLoc));
                            _db.CodeFirst.InitTables(typeof(WCS_CacheLine));
                            _db.CodeFirst.InitTables(typeof(WCS_CacheLineLoc));

                            break;

                        case "WCSDlog"://WCS日志数据库

                            break;

                        default: //其他库
                            break;
                    };
                };
            });
        }
    }
}
