using Elastic.Clients.Elasticsearch.Tasks;
using Furion.Logging;
using Microsoft.AspNetCore.SignalR;
using RazorEngine.Compilation.ImpromptuInterface.Dynamic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WCS.Application;
public static class PLCCommon
{
    private static readonly ISqlSugarClient _db = SqlSugarSetup.ITenant.GetConnectionScope(SqlSugarConst.MainConfigId);

    /// <summary>
    /// 获取任务相关信息
    /// </summary>
    /// <param name="endLocat">目标位置</param>
    /// <param name="taskType">1:出库任务 2:移库任务</param>
    /// <param name="roadWay">起始巷道</param>
    /// <param name="endRoadWay">目标巷道</param>
    /// <returns></returns>
    public static PlcTaskInfo GetCTaskInfo(string endLocat,string taskType,string roadWay,string endRoadWay) 
    {
        if (!endLocat.IsNullOrEmpty()) 
        {
            endLocat = endLocat.PadLeft(3, '0');
        }

        // 各层输送线跺机放货工位集合
        var conveyList1 = new List<string>() { "152", "153", "155", "160", "094", "019", "037", "054", "078" };
        var conveyList4 = new List<string>() { "266", "265"};

        PlcTaskInfo taskInfo = new PlcTaskInfo();
        taskInfo.EndCeng = "3";
        taskInfo.EndLie = "60";
        taskInfo.EndPai = int.Parse(roadWay.Substring(1,2)).ToString();
        taskInfo.StartStation = "0";

        // 移库任务
        if (taskType == "2") 
        {
            if (roadWay == endRoadWay)                                              // 同巷道移库,获取目标地址
            {
                taskInfo = GetEndPai(endRoadWay.Substring(1, 2),endLocat.Substring(2, 2), endLocat.Substring(0, 2), endLocat.Substring(4, 2), endLocat.Substring(6, 2));
            }
            else                                                                    // 跨巷道移库,获取一楼出库口
            {
                taskInfo.Ip = "192.168.120.1";
                switch (roadWay)
                {
                    case "R01":
                        taskInfo.EndStation = "004";
                        break;
                    case "R02":
                        taskInfo.EndStation = "099";
                        break;
                    case "R03":
                        taskInfo.EndStation = "107";
                        break;
                    case "R04":
                        taskInfo.EndStation = "115";
                        break;
                    case "R05":
                        taskInfo.EndStation = "125";
                        break;
                    case "R06":
                        taskInfo.EndStation = "133";
                        break;
                    case "R07":
                        taskInfo.EndStation = "141";
                        break;
                }
            }
        }

        // 出库任务
        if (taskType == "1") 
        {
            if (conveyList1.Contains(endLocat))
            {
                taskInfo.Ip = "192.168.120.1";
                taskInfo.EndCeng = "1";
                #region 一层输送线
                switch (roadWay)
                {
                    case "R01":
                        taskInfo.EndStation = "004";
                        break;
                    case "R02":
                        taskInfo.EndStation = "099";
                        break;
                    case "R03":
                        taskInfo.EndStation = "107";
                        break;
                    case "R04":
                        taskInfo.EndStation = "115";
                        break;
                    case "R05":
                        taskInfo.EndStation = "125";
                        break;
                    case "R06":
                        taskInfo.EndStation = "133";
                        break;
                    case "R07":
                        taskInfo.EndStation = "141";
                        break;
                }
                #endregion
            }
            else if (conveyList4.Contains(endLocat))
            {
                taskInfo.Ip = "192.168.120.90";
                taskInfo.EndCeng = "2";
                #region 四层输送线
                switch (endLocat)
                {
                    case "266":
                        //if (roadWay == "R06") 
                        //{
                        //    taskInfo.Ip = "192.168.120.1";
                        //    taskInfo.EndCeng = "1";
                        //    taskInfo.EndStation = "133";
                        //    break;
                        //}

                        taskInfo.EndStation = "277";
                        break;
                    case "265":
                        if (roadWay == "R05")
                        {
                            taskInfo.EndStation = "253";
                            break;
                        }
                        taskInfo.EndStation = "250";
                        break;
                }
                #endregion
            }
            else
            {
                throw new Exception("出库口工位未查询到");
            }

        }
        //根据巷道口和层数确认出库工位排

        //---------------------待改
        switch (roadWay)
        {
            case "R01":

                if (taskInfo.EndCeng == "1")
                {
                    taskInfo.EndPai = "2";
                }
                if (taskInfo.EndCeng == "2")
                {
                    taskInfo.EndPai = "2";
                }
                break;
            case "R02":

                if (taskInfo.EndCeng == "1")
                {
                    taskInfo.EndPai = "2";
                }
                if (taskInfo.EndCeng == "2")
                {
                    taskInfo.EndPai = "2";
                }
                break;
            case "R03":
                if (taskInfo.EndCeng == "1")
                {
                    taskInfo.EndPai = "2";
                }
                if (taskInfo.EndCeng == "2")
                {
                    taskInfo.EndPai = "2";
                }
                break;
            case "R04":
                if (taskInfo.EndCeng == "1")
                {
                    taskInfo.EndPai = "2";
                }
                if (taskInfo.EndCeng == "2")
                {
                    taskInfo.EndPai = "2";
                }
                break;
            case "R05":
                if (taskInfo.EndCeng == "1")
                {
                    taskInfo.EndPai = "2";
                }
                if (taskInfo.EndCeng == "2")
                {
                    if (endLocat == "265")
                    {
                        taskInfo.EndPai = "2";
                    }
                    if (endLocat == "266")
                    {
                        taskInfo.EndPai = "3";
                    }
                }
                break;
            case "R06":
                if (taskInfo.EndCeng == "1")
                {
                    taskInfo.EndPai = "2";
                }
                if ( taskInfo.EndCeng == "2")
                {
                    taskInfo.EndPai = "3";
                }
                break;
            case "R07":
                if (taskInfo.EndCeng == "1" )
                {
                    taskInfo.EndPai = "2";
                }
                if ( taskInfo.EndCeng == "2")
                {
                    taskInfo.EndPai = "2";
                }
                break;
        }

        return taskInfo;
    }

    /// <summary>
    /// 根据工位号获取对应的输送线Ip
    /// </summary>
    /// <param name="startStation"></param>
    /// <returns></returns>
    public static PLCUtil GetPlcIp(string startStation) 
    {
        string strIp = "";
        startStation = startStation.PadLeft(3, '0');
        var conveyList1 = new List<string>() { "078","093", "094", "155", "160", "063", "072", "050", "045", "048", "052", "056", "055", "032", "027", "030", "034", "039", "038", "015", "010", "017", "021", "020", "003", "004", "097", "099", "105", "107", "113", "115", "123", "125", "131", "133", "139", "141", "152", "153", "019", "037", "054" };
        var conveyList4 = new List<string>() { "265", "266", "250", "253", "277" };
        if (conveyList1.Contains(startStation))
        {
            strIp = "192.168.120.1";
        }
        else if (conveyList4.Contains(startStation))
        {

            strIp = "192.168.120.90";
        }
        else
        {
            throw Oops.Bah("工位未查询到");
        }
        var plcConveyorConn = PLCTaskAction.listPlcConn.First(m => m.PlcIP == strIp);
        return plcConveyorConn;
    }

    /// <summary>
    /// 根据wms目标地址转换为Plc目标地址
    /// </summary>
    /// <param name="road">巷道</param>
    /// <param name="lie">列</param>
    /// <param name="pai">排</param>
    /// <param name="ceng">层</param>
    /// <param name="dept">深度</param>
    /// <returns></returns>
    public static PlcTaskInfo GetEndPai(string road,string lie, string pai,string ceng, string dept) 
    {
        var roadNum = int.Parse(road);
        var lieNum = int.Parse(lie);
        var paiNum = int.Parse(pai);
        var cengNum = int.Parse(ceng);
        var deptNum = int.Parse(dept);

        var paiVal = 0;
        // 判断巷道奇偶数
        if (roadNum % 2 == 0)// 偶数
        {
            // 判断排奇偶数
            if (paiNum % 2 == 0)
            {
                if (deptNum == 1)
                {
                    paiVal = 2;
                }
                else
                {
                    paiVal = 1;
                }
            }
            else
            {
                if (deptNum == 1)
                {
                    paiVal = 3;
                }
                else
                {
                    paiVal = 4;
                }
            }

        }
        else   // 奇数
        {
            // 判断排奇偶数
            if (paiNum % 2 == 0)
            {
                if (deptNum == 1)
                {
                    paiVal = 2;
                }
                else
                {
                    paiVal = 1;
                }
            }
            else
            {
                if (deptNum == 1)
                {
                    paiVal = 3;

                }
                else
                {
                    paiVal = 4;

                }
            }
        }

        PlcTaskInfo taskInfo = new PlcTaskInfo();
        taskInfo.EndPai = paiVal.ToString();
        taskInfo.EndCeng = cengNum.ToString();
        taskInfo.EndLie = lieNum.ToString() ;
        if (taskInfo.EndPai == "0" || taskInfo.EndCeng == "0" || taskInfo.EndLie == "0")
        {
            throw new Exception("排列层转换失败");
        }
        return taskInfo;
    }

    /// <summary>
    /// 根据巷道和层数确定巷道口入库工位
    /// </summary>
    /// <param name="endRoadway"></param>
    /// <param name="ceng"></param>
    /// <param name="startStation">起始工位</param>
    /// <returns></returns>
    public static string RoadwayToStationNum(string endRoadway, string ceng,string startStation="")
    {
        string stationNum = "";
        switch (endRoadway)
        {
            case "R01":
                if (ceng == "1")
                {
                    stationNum = "003";
                }
                if (ceng == "2")
                {
                    stationNum = "";
                }
                break;
            case "R02":
                if (ceng == "1")
                {
                    stationNum = "097";
                }
                if (ceng == "2")
                {
                    stationNum = "";
                }
                break;
            case "R03":
                if (ceng == "1")
                {
                    stationNum = "105";
                }
                if (ceng == "2")
                {
                    stationNum = "";
                }
                break;
            case "R04":
                if (ceng == "1")
                {
                    stationNum = "113";
                }
                if (ceng == "2")
                {
                    stationNum = "";
                }
                break;
            case "R05":
                if (ceng == "1")
                {
                    stationNum = "123";
                }
                if (ceng == "2")
                {
                    if (startStation == "265")
                    {
                        stationNum = "253";
                    }
                    if (startStation == "266")
                    {
                        stationNum = "277";
                    }
                }
                break;
            case "R06":
                if (ceng == "1")
                {
                    stationNum = "131";
                }
                if (ceng == "2")
                {
                    stationNum = "250";
                }
                break;
            case "R07":
                if (ceng == "1")
                {
                    stationNum = "139";
                }
                if (ceng == "2")
                {
                    stationNum = "";
                }
                break;
        }

        return stationNum;
    }

    /// <summary>
    /// 根据巷道号和层数获取出库工位
    /// </summary>
    /// <param name="endRoadway">巷道:R0X</param>
    /// <param name="ceng">层数</param>
    /// <returns>出库工位号</returns>
    public static string RoadwayToOutStationNum(string endRoadway, string ceng)
    {
        string stationNum = "";
        switch (endRoadway)
        {
            case "R01":
                if (ceng == "1")
                {
                    stationNum = "004";
                }
                break;
            case "R02":
                if (ceng == "1")
                {
                    stationNum = "099";
                }
                break;
            case "R03":
                if (ceng == "1")
                {
                    stationNum = "107";
                }
                break;
            case "R04":
                if (ceng == "1")
                {
                    stationNum = "115";
                }
                break;
            case "R05":
                if (ceng == "1")
                {
                    stationNum = "125";
                }
                if (ceng == "4")
                {
                    stationNum = "277,253";
                }
                break;
            case "R06":
                if (ceng == "1")
                {
                    stationNum = "133";
                }
                if (ceng == "4")
                {
                    stationNum = "250";
                }
                break;
            case "R07":
                if (ceng == "1")
                {
                    stationNum = "141";
                }
                break;
        }

        return stationNum;
    }

    /// <summary>
    /// 根据工位号获取对应巷道 
    /// </summary>
    /// <param name="StationNum">入出工位号</param>
    /// <returns>跺机联机</returns>
    public static string GetRoadwayByStation(string StationNum)
    {
        if (!StationNum.IsNullOrEmpty())
        {
            StationNum = StationNum.PadLeft(3, '0');
        }
        string value = "";
        var conveyList1 = new List<string>() { "003", "004", };
        var conveyList2 = new List<string>() { "097", "099", };
        var conveyList3 = new List<string>() { "105", "107", };
        var conveyList4 = new List<string>() { "113", "115", };
        var conveyList5 = new List<string>() { "123", "125", "277", "253", };
        var conveyList6 = new List<string>() { "131", "133", "250" };
        var conveyList7 = new List<string>() { "139", "141", };

        if (conveyList1.Contains(StationNum))
        {
            value = "R01";
        }
        else if (conveyList2.Contains(StationNum))
        {
            value = "R02";
        }
        else if (conveyList3.Contains(StationNum))
        {
            value = "R03";
        }
        else if (conveyList4.Contains(StationNum))
        {
            value = "R04";
        }
        else if (conveyList5.Contains(StationNum))
        {
            value = "R05";
        }
        else if (conveyList6.Contains(StationNum))
        {
            value = "R06";
        }
        else if (conveyList7.Contains(StationNum))
        {
            value = "R07";
        }

        return value;
    }

    /// <summary>
    /// 根据巷道口出入库工位号获取对应楼层 
    /// </summary>
    /// <param name="StationNum">入出工位号</param>
    /// <returns>跺机联机</returns>
    public static string GetRoadwayByStationNew(string StationNum)
    {
        string value = "";
        //var conveyList1 = new List<string>() { "147", "145", "139", "137", "129", "127", "121", "119", "111", "109", "103", "101", "093", "091", "085", "083", "075", "073", "067", "065" };
        //var conveyList2 = new List<string>() { "252", "254", "260", "262", "272", "270", "278", "280", "288", "290", "294", "301", "307", "309", "315", "317", "325", "327", "331", "337" };
        //var conveyList3 = new List<string>() { "401", "402", "405", "406", "409", "410", "413", "414", "417", "418", "421", "422", "425", "426", "429", "430", "433", "434", "437", "438" };
        var ipInfo = _db.Queryable<WcsPlc>().Where(s =>  s.Type == PLCTypeEnum.ConveyorLine && s.IsDelete == false).ToList();  //s.Type == PLCTypeEnum.StackingMachine ||
        var ip1 = ipInfo.First(m => m.Text == "1层托盘输送线");
        var ip4 = ipInfo.First(m => m.Text == "4层托盘输送线");

        if (ip1 != null) 
        {
            var dev1 = PLCTaskAction.plcDevices.Where(m => m.IsDelete == false && m.PlcId == ip1.Id).Select(m => m.StationNum).ToList();
            if (dev1.Contains(StationNum))
            {
                value = "1";
                return value;
            }
        }

        if (ip4 != null)
        {
            var dev2 = PLCTaskAction.plcDevices.Where(m => m.IsDelete == false && m.PlcId == ip4.Id).Select(m => m.StationNum).ToList();
            if (dev2.Contains(StationNum))
            {
                value = "2";
                return value;
            }
        }

        return "";
    }

    /// <summary>
    /// 根据巷道号、层数 获取对应的跺机IP及入库工位排列层信息
    /// </summary>
    /// <param name="roadway">巷道号</param>
    /// <param name="ceng">连接集合</param>
    /// <returns></returns>
    public static StokInfo GetStokePlc(string roadway, string ceng,string startStation="")
    {

        StokInfo sInfo = new StokInfo();
        sInfo.Pai = "2";

        switch (roadway)
        {
            case "R01":
                sInfo.Ip = "192.168.120.110";
                if (ceng == "1")
                {
                    sInfo.Pai = "3";
                }
                break;
            case "R02":
                sInfo.Ip = "192.168.120.120";
                if (ceng == "1")
                {
                    sInfo.Pai = "3";
                }
                break;
            case "R03":
                sInfo.Ip = "192.168.120.130";
                if (ceng == "1")
                {
                    sInfo.Pai = "3";
                }
                break;
            case "R04":
                sInfo.Ip = "192.168.120.140";
                if (ceng == "1")
                {
                    sInfo.Pai = "3";
                }
                break;
            case "R05":
                sInfo.Ip = "192.168.120.150";
                if (ceng == "1" || ceng == "2")
                {
                    sInfo.Pai = "3";
                }

                if (ceng == "1")
                {
                    sInfo.Pai = "3";
                } 
                else if (ceng == "2") 
                {
                    if (startStation == "253") 
                    {
                        sInfo.Pai = "2";
                    }

                    if (startStation == "277") 
                    {
                        sInfo.Pai = "3";
                    }
                }
                break;
            case "R06":
                sInfo.Ip = "192.168.120.160";
                if (ceng == "2" || ceng == "1")
                {
                    sInfo.Pai = "3";
                }
                break;
            case "R07":
                sInfo.Ip = "192.168.120.170";
                if (ceng == "1")
                {
                    sInfo.Pai = "3";
                }
                break;
        }

        sInfo.Lie = "60";
        sInfo.Ceng = "1";

        if (ceng == "2")
        {
            sInfo.Ceng = "2";
        }
        return sInfo;
    }

    /// <summary>
    /// 根据巷道号、层数 获取对应的跺机IP及出库工位排列层信息   程序成功提出来
    /// </summary>
    /// <param name="roadway">巷道号</param>
    /// <param name="ceng">连接集合</param>
    /// <returns></returns>
    public static StokInfo GetOutStokePlc(string roadway, string ceng)
    {
        // 2排 60列 1层
        StokInfo sInfo = new StokInfo();
        sInfo.Pai = "2";

        switch (roadway)
        {
            case "R01":
                sInfo.Ip = "192.168.120.110";
                if (ceng == "1")
                {
                    sInfo.Pai = "3";
                }
                break;
            case "R02":
                sInfo.Ip = "192.168.120.120";
                if (ceng == "1")
                {
                    sInfo.Pai = "3";
                }
                break;
            case "R03":
                sInfo.Ip = "192.168.120.130";
                if (ceng == "1")
                {
                    sInfo.Pai = "3";
                }
                break;
            case "R04":
                sInfo.Ip = "192.168.120.140";
                if (ceng == "1")
                {
                    sInfo.Pai = "3";
                }
                break;
            case "R05":
                sInfo.Ip = "192.168.120.150";
                if (ceng == "1")
                {
                    sInfo.Pai = "2";
                }
                break;
            case "R06":
                sInfo.Ip = "192.168.120.160";
                if (ceng == "2" || ceng == "1")
                {
                    sInfo.Pai = "3";
                }
                break;
            case "R07":
                sInfo.Ip = "192.168.120.170";
                if (ceng == "1")
                {
                    sInfo.Pai = "3";
                }
                break;
        }

        sInfo.Lie = "60";
        sInfo.Ceng = "1";

        if (ceng == "4")
        {
            sInfo.Ceng = "4";
        }
        return sInfo;
    }


    /// <summary>
    /// 根据储位排获取跺机对应的地址排03010302
    /// </summary>
    /// <param name="road">排02</param>
    /// <param name="pai">排03</param>
    /// <param name="dept">深度02</param>
    /// <returns></returns>
    public static int GetDjAdress(string road, string pai, string dept)
    {
        var roadNum = int.Parse(road);
        var paiNum = int.Parse(pai);
        var deptNum = int.Parse(dept);

        var paiVal = 0;
        // 判断巷道奇偶数
        if (roadNum % 2 == 0)// 偶数
        {
            // 判断排奇偶数
            if (paiNum % 2 == 0)
            {
                if (deptNum == 1)
                {
                    paiVal = 2;
                }
                else
                {
                    paiVal = 1;
                }
            }
            else
            {
                if (deptNum == 1)
                {
                    paiVal = 3;
                }
                else
                {
                    paiVal = 4;
                }
            }

        }
        else   // 奇数
        {
            // 判断排奇偶数
            if (paiNum % 2 == 0)
            {
                if (deptNum == 1)
                {
                    paiVal = 2;
                }
                else
                {
                    paiVal = 1;
                }
            }
            else
            {
                if (deptNum == 1)
                {
                    paiVal = 3;

                }
                else
                {
                    paiVal = 4;

                }
            }
        }
        if (paiVal == 0)
        {
            Log.Error("排转换失败!");
            throw new Exception("排转换失败");
        }
        return paiVal;

    }


}