using Aitex.Core.RT.Device;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using MECF.Framework.Common.Beckhoff.Station;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Layout;
using MECF.Framework.Common.Routine;
using MECF.Framework.Common.Utilities;
using MECF.Framework.Common.WaferHolder;
using CyberX8_Core;
using CyberX8_RT.Devices.AXIS;
using CyberX8_RT.Devices.AXIS.CANOpen;
using CyberX8_RT.Devices.Facilities;
using CyberX8_RT.Devices.TransPorter;
using CyberX8_RT.Modules.Loader;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CyberX8_RT.Modules.Transporter
{
   
    public class TransporterMoveToRoutine : RoutineBase, IRoutine
    {
        private enum MoveToStep
        {
            CheckStatus,
            ElevatorPosition,
            ElevatorPositionWait,
            SafeMoveTo,
            CheckMoveToStatus,
            GantryPosition,
            GantryPositionWait,
            End
        }
        #region 内部变量
        private string _cellName;
        private string _otherModule;
        private JetAxisBase _gantryAxis;
        private JetAxisBase _elevatorAxis;
        private JetAxisBase _otherElevatorAxis;
        private LoaderEntity _loaderEntity;
        private JetAxisBase _loaderRotationAxis;
        private TransporterCommon _transporterCommon;
        private SystemFacilities _facilities;
        private TransporterConflictRoutine _conflictRoutine;
        ProcessLayoutCellItem _cellItem;
        private bool _waferHolderPresent = false;
        #endregion
        #region 属性
        public string TargetCell { get { return _cellName; } }
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public TransporterMoveToRoutine(string module) : base(module)
        {
        }
        /// 
        /// 中止
        /// 
        public void Abort()
        {
            Runner.Stop("Manual Abort");
        }
        /// 
        /// 监控
        /// 
        /// 
        public RState Monitor()
        {
            Runner.Run(MoveToStep.CheckStatus, CheckStartPreConfition, NullFun,_delay_1ms)
                //1. Elevator
                .Run(MoveToStep.ElevatorPosition, ElevatorPosition, _delay_1ms)
                .WaitWithStopCondition(MoveToStep.ElevatorPositionWait, CheckElevatorPositionStatus, CheckElevatorPositionRunStop)
                //2. other Transporter Safe Move
                .Run(MoveToStep.SafeMoveTo, SafeMoveTo, _delay_1ms)
                .WaitWithStopCondition(MoveToStep.CheckMoveToStatus, () => CommonFunction.CheckRoutineEndState(_conflictRoutine),
                    CheckSafeMoveToStopStatus)
                //3. this Gantry Move To Target Cell
                .Run(MoveToStep.GantryPosition, GantryPositionToCell, _delay_1ms)
                .WaitWithStopCondition(MoveToStep.GantryPositionWait, CheckGantryPositionStatus, CheckGantryPositionRunStop)
                .End(MoveToStep.End,NullFun,100);
            return Runner.Status;
        }
        /// 
        /// Elevator Position
        /// 
        /// 
        private bool ElevatorPosition()
        {
            bool result= false;
            //运动至UP
            double elevatorPosition = _elevatorAxis.MotionData.MotorPosition;
            if (!_elevatorAxis.CheckPositionIsInStation(elevatorPosition, "UP"))
            {
                result= _elevatorAxis.PositionStation("UP");
                if(!result)
                {
                    NotifyError(eEvent.ERR_TRANSPORTER, "elevator goto up failed", 0);
                }
            }
            else
            {
                result = true;
            }          
            return result;
        }
        
        /// 
        /// 安全避障移动
        /// 
        /// 
        private bool SafeMoveTo()
        {
            _cellItem = ProcessLayoutManager.Instance.GetProcessLayoutCellItemByModuleName(_cellName);
            string stationName = _cellName;
            if (_cellItem != null)
            {
                if (_cellName.ToLower() != "loader" && _cellName.ToLower() != "park")
                {
                    stationName = $"Cell{_cellItem.CellId}";
                }
            }
            else
            {
                NotifyError(eEvent.ERR_TRANSPORTER, $"{_cellName} not in layout",0);
                return false;
            }
            var result = _gantryAxis.GetPositionByStation(stationName);
            if (result.success)
            {
                bool isPositive = false;
                if (_gantryAxis.MotionData.MotorPosition < result.position)
                {
                    isPositive = true;
                }
                return _conflictRoutine.Start(result.position, isPositive) == RState.Running;
            }
            else
            {
                NotifyError(eEvent.ERR_TRANSPORTER, $"{_cellName} not in station list",0);
                return false;
            }
        }
        /// 
        /// 检验安全避让异常结束状态
        /// 
        /// 
        private bool CheckSafeMoveToStopStatus()
        {
            bool result = CommonFunction.CheckRoutineStopState(_conflictRoutine);
            if (result)
            {
                NotifyError(eEvent.ERR_TRANSPORTER, "Safe Move failed", 0);
            }
            return result;
        }
        /// 
        /// Gantry Position To cell
        /// 
        /// 
        private bool GantryPositionToCell()
        {
            _cellItem= ProcessLayoutManager.Instance.GetProcessLayoutCellItemByModuleName(_cellName);
            bool result = false;
            if (_cellItem != null)
            {
                if (_cellName.ToLower() != "loader"&&_cellName.ToLower()!="park")
                {
                    result= _gantryAxis.PositionStation($"Cell{_cellItem.CellId}", false);
                }
                else
                {
                    result= _gantryAxis.PositionStation(_cellName,false);
                }
                if (!result)
                {
                    NotifyError(eEvent.ERR_TRANSPORTER, "gantry axis motion failed", 0);
                }
                return result;
            }
            else
            {
                NotifyError(eEvent.ERR_TRANSPORTER, $"{_cellName} not in layout",0);
                return false;
            }
        }
        /// 
        /// 检验Elevator移动状态
        /// 
        /// 
        private bool CheckElevatorPositionStatus()
        {
            return _elevatorAxis.Status == RState.End;
        }
        /// 
        /// 检验Elevator是否还在运动
        /// 
        /// 
        private bool CheckElevatorPositionRunStop()
        {
            bool result= _elevatorAxis.Status == RState.Failed||_elevatorAxis.Status==RState.Timeout;
            if (result)
            {
                NotifyError(eEvent.ERR_TRANSPORTER, "elevator motion failed",0);
            }
            return result;
        }
        /// 
        /// 检验Gantry移动状态
        /// 
        /// 
        private bool CheckGantryPositionStatus()
        {
            return _gantryAxis.Status == RState.End;
        }
        /// 
        /// 检验Gantry是否还在运动
        /// 
        /// 
        private bool CheckGantryPositionRunStop()
        {
            bool result= _gantryAxis.Status == RState.Failed||_gantryAxis.Status==RState.Timeout;
            if(result)
            {
                NotifyError(eEvent.ERR_TRANSPORTER, "gantry motion failed", 0);
            }
            return result;
        }
        /// 
        /// 启动
        /// 
        /// 
        /// 
        public RState Start(params object[] objs)
        {
            _cellName = objs[0].ToString();
            InitializeParameters();
            return Runner.Start(Module,$"MoveTo {_cellName}");
        }
        /// 
        /// 初始化参数
        /// 
        private void InitializeParameters()
        {
            _elevatorAxis = DEVICE.GetDevice($"{Module}.Elevator");
            _otherModule = Module == "Transporter2" ? "Transporter1" : "Transporter2";
            _otherElevatorAxis = DEVICE.GetDevice($"{_otherModule}.Elevator");
            _gantryAxis = DEVICE.GetDevice($"{Module}.Gantry");
            _loaderEntity = Singleton.Instance.GetModule(ModuleName.Loader1.ToString());
            _loaderRotationAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.Rotation");
            _conflictRoutine = new TransporterConflictRoutine(Module);
            _transporterCommon = DEVICE.GetDevice($"{Module}.Common");
        }
        /// 
        /// 启动校验条件
        /// 
        /// 
        private bool CheckStartPreConfition()
        {
            //所有轴上电并Homed
            if(!CheckPreCondition())
            {
                return false;
            }            
            //若目标Cell为Loader, 则Loader应在TRNPA或TRNPB位
            if (_cellName == "Loader")
            {
                double loaderRotationPosition = _loaderRotationAxis.MotionData.MotorPosition;
                if (!_loaderRotationAxis.CheckPositionIsInStation(loaderRotationPosition, "TRNPA") && 
                    !_loaderRotationAxis.CheckPositionIsInStation(loaderRotationPosition, "TRNPB"))
                {
                    NotifyError(eEvent.ERR_TRANSPORTER, $"{ModuleName.Loader1} rotation axis {loaderRotationPosition} is not int TRNPA or TRNPB station",-1);
                    return false;
                }
            }
            //检验Facilities
            //var faciltiesResult = _facilities.CheckCDA();
            //if (!faciltiesResult.result)
            //{
            //    NotifyError(eEvent.ERR_TRANSPORTER, faciltiesResult.reason, -1);
            //    return false;
            //}
            return true;
        }
        /// 
        /// 检验前置条件
        /// 
        /// 
        private bool CheckPreCondition()
        {
            if (!_gantryAxis.IsSwitchOn)
            {
                NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} gantry axis is not switch on ",-1);
                return false;
            }
            if (!_gantryAxis.IsHomed)
            {
                NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} gantry axis is not homed ",-1);
                return false;
            }
            if (!_elevatorAxis.IsSwitchOn)
            {
                NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} elevator axis is not switch on ",-1);
                return false;
            }
            if (!_elevatorAxis.IsHomed)
            {
                NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} elevator axis is not homed ",-1);
                return false;
            }
            return true;
        }
        /// 
        /// 重试
        /// 
        /// 
        public RState Retry(int step)
        {
            InitializeParameters();
            List preStepIds = new List();
            return Runner.Retry(MoveToStep.CheckStatus, preStepIds, Module, "Moveto Retry");
        }
        /// 
        /// 检验前面Unload完成状态
        /// 
        /// 
        public bool CheckCompleteCondition(int index)
        {
            TransporterEntity transporterEntity = Singleton.Instance.GetModule(Module);
            if (!_gantryAxis.CheckPositionIsInStation(_gantryAxis.MotionData.MotorPosition,_cellName))
            {
                NotifyError(eEvent.ERR_TRANSPORTER, $"gantry is not in {_cellName}", index);
                return false;
            }
            return true;
        }
    }
}