using OnlineStore;
using OnlineStore.Common;
using OnlineStore.LoadCSVLibrary;
using Robot.UR;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DeviceLibrary
{
    public class MI : DeviceBase, IDevice
    {
        public static Dictionary<string, MI> DeviceList = new Dictionary<string, MI>();

        public static void Init(Robot_Config config, Dictionary<string, DeviceGroup> devices,out string msg) {
            msg = "";
            MI sideMove = new MI(devices["AMH-MI1"], out string m);
            DeviceList.Add(devices["AMH-MI1"].GroupName, sideMove);
            msg += m;
            
        }
        DeviceGroup DeviceGroup;
        MoveInfo MoveInfo;
        MoveInfo RoboMoveInfo;
        CylinderManger Location;
        public AxisBean Comp;
        public AxisBean Rotate;
        URRobotControl Robot;
        string POS_Start = "MI1";
        public MI(DeviceGroup device,out string msg) {
            msg = "";
            Name = device.Name+"("+ device.GroupName + ")";
            DeviceGroup = device;
            GroupName = DeviceGroup.GroupName;
            Msg = new MsgService(GroupName+"-T");
            MoveInfo = new MoveInfo(GroupName + "-T");
            RoboMoveInfo = new MoveInfo(GroupName + "-Robo");
            if (device.GroupName == "AMH-MI1")
                Robot = RobotManage.Robot_MI1;
            else
            {
                Robot = RobotManage.Robot_MI2;
                POS_Start = "MI2";
            }
            Comp = AxisBean.List[DeviceGroup.GroupName][0];
            Rotate = AxisBean.List[DeviceGroup.GroupName][1];
            Location = new CylinderManger($"物料顶升", GroupName, IO_Type.MI_Reel_Location_Up, IO_Type.MI_Reel_Location_Down);
        }
        public DeviceStateE DeviceState { get; set; }
        public void Start()
        {
            OpenAllServo();
            Robot.StartRobot();
            Robot.PlayProgram();
            DeviceState = DeviceStateE.HomeReset;
            MoveInfo.NewMove(MoveStep.H01_HomeReset);
            MoveInfo.log("开始回原");
        }

        public void Stop()
        {
            DeviceState = DeviceStateE.Stop;
            MoveInfo.log("停止运行");
        }
        public void Process()
        {
            LogUtil.OutputDebugString("DeviceState:" + DeviceState.ToString());
            if (DeviceState == DeviceStateE.HomeReset)
                ResetProcess();
            else if (DeviceState == DeviceStateE.Run)
            {
                OneWayProcess();
                RobotMoveProcess();
            }
        }
        int isalivetrytimes = 0;
        int StopBufDelayMS = 500;
        int StopDelayMS = 1500;

        RobotPosition FromPos;
        RobotPosition ToPos;
        public void OneWayProcess()
        {
            if (CheckWait(MoveInfo))
                return;

            switch (MoveInfo.MoveStep)
            {
                case MoveStep.Wait:
                    LogUtil.OutputDebugString("InStoreJobList:" + InStoreJobList.Count.ToString());
                    if (InStoreJobList.Dequeue(out JobInfo job)) {
                        MoveInfo.log("收到物料入库任务:" + job.ToStr());
                        MoveInfo.MoveParam.WareCode = job.WareNum;
                        MoveInfo.MoveParam.PosID = job.PosId;
                        MoveInfo.MoveParam.PlateW = job.plateW;
                        MoveInfo.MoveParam.PlateH = job.plateH;
                        MoveInfo.NextMoveStep(MoveStep.MI_01);
                        FromPos = RobotManage.MI1Postion[POS_Start + "_MT"];
                        ToPos = RobotManage.MI1Postion[POS_Start + "_SCAN"];

                        MoveInfo.log($"开始转移物料:{FromPos.PositionNum}=>{ToPos.PositionNum}");
                    }
                    break;
                case MoveStep.MI_01:
                    MoveInfo.NextMoveStep(MoveStep.MI_02);
                    Location.ToLow(MoveInfo);
                    RoboMoveInfo.MoveParam = MoveInfo.MoveParam.clone();
                    RoboMoveInfo.NextMoveStep(MoveStep.MI_01);
                    MoveInfo.log("机器人开始取料");
                    break;
                case MoveStep.MI_02:                    
                    if (RoboMoveInfo.MoveStep==MoveStep.Wait)
                    {
                        MoveInfo.NextMoveStep(MoveStep.MI_10);
                        Location.ToHigh(MoveInfo);
                    }
                    break;
                case MoveStep.MI_10:
                    MoveInfo.NextMoveStep(MoveStep.MI_11);
                    Rotate.RelMove(RobotManage.Config.AMH_Route_PoToMM * 90, RobotManage.Config.AMH_Route_PoToMM_speed);
                    break;
                case MoveStep.MI_11:
                    if (!Rotate.IsBusy)
                    {
                        MoveInfo.NextMoveStep(MoveStep.MI_20);
                        Location.ToLow(MoveInfo);
                    }
                    break;
                case MoveStep.MI_20:
                    MoveInfo.NextMoveStep(MoveStep.MI_21);
                    FromPos = RobotManage.MI1Postion[POS_Start + "_SCAN"];
                    ToPos = RobotManage.MI1Postion[GetNextBufferStore()];
                    RoboMoveInfo.NextMoveStep(MoveStep.MI_01);
                    break;
                case MoveStep.MI_21:
                    if (RoboMoveInfo.MoveStep == MoveStep.Wait)
                    {
                        InStoreJobList.ClearLastPosid();
                        MoveInfo.NextMoveStep(MoveStep.Wait);
                    }
                    break;
            }
        }


        public void RobotMoveProcess()
        {
            if (CheckWait(RoboMoveInfo))
                return;

            switch (RoboMoveInfo.MoveStep)
            {
                case MoveStep.Wait:
                    break;
                //从流水线取料
                case MoveStep.MI_01:
                    RoboMoveInfo.NextMoveStep(MoveStep.MI_02);
                    Comp.AbsMove(RoboMoveInfo, RobotManage.Config.AMH_RoboMI1_Comp_P1, RobotManage.Config.AMH_RoboMI1_Comp_P1_speed);
                    break;
                case MoveStep.MI_02:
                    if (!Robot.IsMoving())
                    {
                        RoboMoveInfo.NextMoveStep(MoveStep.MI_03);
                        Robot.SendMoveCmd(FromPos.Take_P5, Setting_Init.URRobot_MI1_Speed_Rate);
                        RoboMoveInfo.WaitList.Add(WaitResultInfo.WaitTime(500));
                    }
                    break;
                case MoveStep.MI_03:
                    if (!Robot.IsMoving())
                    {
                        RoboMoveInfo.NextMoveStep(MoveStep.MI_04);
                        Comp.AbsMove(null, DeviceGroup.p3, RobotManage.Config.AMH_RoboMI1_Comp_P2_speed);
                        Comp.BatchAxisStartCheck(IO_Type.MI_Robot_Clamp_Check, IO_VALUE.HIGH);
                        Robot.SendMoveCmd(FromPos.Take_P6, Setting_Init.URRobot_MI1_Speed_Rate);
                        RoboMoveInfo.WaitList.Add(WaitResultInfo.WaitTime(500));
                    }
                    break;
                case MoveStep.MI_04:
                    if (!Robot.IsMoving() && !Comp.IsBusy)
                    {
                        RoboMoveInfo.NextMoveStep(MoveStep.MI_05);
                        Robot.SendMoveCmd(FromPos.Take_P7, Setting_Init.URRobot_MI1_Speed_Rate);
                        RoboMoveInfo.WaitList.Add(WaitResultInfo.WaitTime(500));
                    }
                    break;
                case MoveStep.MI_05:
                    if (!Robot.IsMoving())
                    {
                        RoboMoveInfo.NextMoveStep(MoveStep.MI_06);
                        Robot.SendMoveCmd(FromPos.P1, Setting_Init.URRobot_MI1_Speed_Rate);
                        RoboMoveInfo.WaitList.Add(WaitResultInfo.WaitTime(500));
                    }
                    break;
                case MoveStep.MI_06:
                    if (!Robot.IsMoving())
                    {
                        RoboMoveInfo.NextMoveStep(MoveStep.MI_40);
                        if (FromPos.PositionNum.EndsWith("MT"))
                        {
                            RemoteLoad remoteLoad = new RemoteLoad();
                            remoteLoad.Action = "";
                            remoteLoad.GroupName = GroupName;
                            remoteLoad.RequestLoadInfo = new RequestLoadInfo();
                            remoteLoad.RequestLoadInfo.DeviceGroupName = GroupName;
                            remoteLoad.RequestLoadInfo.IsEmpty = true;
                            remoteLoad.RequestLoadInfo.LoadParam = RoboMoveInfo.MoveParam.clone();
                            TrayManager.TrayRelease(remoteLoad);
                            TrayStop.DeviceList[GroupName].TrayRelease();
                            RoboMoveInfo.log("取料完成托盘放行");
                        }else
                            RoboMoveInfo.log("取料完成");
                    }
                    break;               
                //放料到缓存位置
                case MoveStep.MI_40:
                    if (!Robot.IsMoving())
                    {
                        RoboMoveInfo.NextMoveStep(MoveStep.MI_41);
                        Robot.SendMoveCmd(ToPos.Put_P2, Setting_Init.URRobot_MI1_Speed_Rate);
                        RoboMoveInfo.WaitList.Add(WaitResultInfo.WaitTime(500));
                    }
                    break;
                case MoveStep.MI_41:
                    if (!Robot.IsMoving())
                    {
                        RoboMoveInfo.NextMoveStep(MoveStep.MI_42);
                        Comp.AbsMove(RoboMoveInfo, RobotManage.Config.AMH_RoboMI1_Comp_P1, RobotManage.Config.AMH_RoboMI1_Comp_P1_speed);

                        Robot.SendMoveCmd(ToPos.Put_P3, Setting_Init.URRobot_MI1_Speed_Rate);
                        RoboMoveInfo.WaitList.Add(WaitResultInfo.WaitTime(500));
                    }
                    break;
                case MoveStep.MI_42:
                    if (!Robot.IsMoving())
                    {
                        RoboMoveInfo.NextMoveStep(MoveStep.MI_43);
                        Robot.SendMoveCmd(ToPos.Put_P4, Setting_Init.URRobot_MI1_Speed_Rate);
                        RoboMoveInfo.WaitList.Add(WaitResultInfo.WaitTime(500));
                    }
                    break;
                case MoveStep.MI_43:
                    if (!Robot.IsMoving())
                    {
                        RoboMoveInfo.NextMoveStep(MoveStep.MI_44);
                        Robot.SendMoveCmd(ToPos.P1, Setting_Init.URRobot_MI1_Speed_Rate);
                        RoboMoveInfo.WaitList.Add(WaitResultInfo.WaitTime(500));
                        
                    }
                    break;
                case MoveStep.MI_44:
                    if (!Robot.IsMoving())
                    {
                        RoboMoveInfo.NextMoveStep(MoveStep.Wait);     
                        RoboMoveInfo.log("放料完成");
                    }
                    break;
            }
        }

        StoreJobList InStoreJobList = new StoreJobList("入库");
        internal void StartInStore(ReelParam trayParam)
        {
            InStoreJobList.Enqueue(new JobInfo(trayParam.WareCode, trayParam.PosID, trayParam.PlateW, trayParam.PlateH));
            MoveInfo.log("写入入库队列:" + trayParam.ToStr());
        }

        /// <summary>
        /// 释放托盘
        /// </summary>
        public void TrayRelease() {
            //MoveInfo.log("释放托盘");
           // MoveInfo.NextMoveStep(MoveStep.TrayStop_LoadProcessed);
        }
        public void ResetProcess()
        {
            if (CheckWait(MoveInfo))
                return;

            switch (MoveInfo.MoveStep)
            {
                case MoveStep.Wait:
                    MoveInfo.NextMoveStep(MoveStep.H01_HomeReset);
                    Comp.HomeMove(MoveInfo);
                    break;
                case MoveStep.H01_HomeReset:
                    MoveInfo.NextMoveStep(MoveStep.H02_HomeReset);
                    Location.ToLow(MoveInfo);                
                    break;
                case MoveStep.H02_HomeReset:
                    MoveInfo.NextMoveStep(MoveStep.H03_HomeReset);
                    Robot.SendMoveCmd(1, Setting_Init.URRobot_MI1_Speed_Rate);
                    MoveInfo.WaitList.Add(WaitResultInfo.WaitTime(1500));
                    break;
                case MoveStep.H03_HomeReset:
                    if (!Robot.IsMoving())
                    {
                        MoveInfo.EndMove();
                        DeviceState = DeviceStateE.Run;
                    }
                    break;
            }
        }

        public bool IsFree()
        {
            return MoveInfo.MoveStep == MoveStep.Wait;
        }
        int bufferstoresindex = 0;
        string[] bufferstores = new string[] { "B01", "B02", "B03", "B04", "B05", "B06", "B07", "B08" };

        string GetNextBufferStore() {
            if (bufferstoresindex >= bufferstores.Length)
                bufferstoresindex = 0;

            var c = POS_Start + "_"+bufferstores[bufferstoresindex];
            bufferstoresindex++;

            return c;
        }
    
    }
}