using Aitex.Core.RT.Fsm;
using Aitex.Core.RT.Routine;
using Aitex.Core.Util;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Schedulers;
using CyberX8_Core;
using CyberX8_RT.Modules.PUF;
using CyberX8_RT.Modules;
using CyberX8_RT.Schedulers.EfemRobot;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CyberX8_RT.Modules.Loader;
using Aitex.Core.RT.Log;
using MECF.Framework.Common.SubstrateTrackings;
using Aitex.Core.Common;
using MECF.Framework.Common.Utilities;
using CyberX8_RT.Devices.AXIS;
using Aitex.Core.RT.Device;
using CyberX8_RT.Dispatch;
using MECF.Framework.Common.RecipeCenter;
namespace CyberX8_RT.Schedulers.Puf
{
    public class SchedulerPuf : SchedulerModule
    {
        private enum OperationStep
        {
            None,
            ReadyForSwap,
            WaitForLoaderUnloadComplete,
            Swap,
            CheckSwapComplete,
            GotoRobotForPick,
            WaitForRobotPick,
            PufBackToPark,
            CheckParkComplete
        }
        #region 内部变量
        private PUFEntity _pufEntity;
        private LoaderEntity _loaderEntity;
        private OperationStep _currentOperation;
        private EfemEntity _efemEntity;
        private bool _forward = false;
        private bool _isProductionWafer = false;
        #endregion
        #region 属性
        /// 
        /// 是否空闲
        /// 
        public override bool IsIdle
        {
            get { return _state == RState.End; }
        }
        /// 
        /// 是否错误
        /// 
        public override bool IsError
        {
            get { return _state == RState.Failed || _state == RState.Timeout; }
        }
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public SchedulerPuf(ModuleName moduleName) : base(moduleName.ToString())
        {
            _efemEntity = Singleton.Instance.EFEM;
            _pufEntity = Singleton.Instance.GetModule(moduleName.ToString());
            _loaderEntity = Singleton.Instance.GetModule(ModuleName.Loader1.ToString());
        }
        /// 
        /// 执行
        /// 
        /// 
        /// 
        public override bool RunProcess(object recipe, object parameter, List syncMessages)
        {
            _isProductionWafer = false;
            _forward = (bool)parameter;
            if (_forward)
            {
                _currentOperation = OperationStep.ReadyForSwap;
                //B面是否有片
                if (WaferManager.Instance.CheckHasWafer(Module, 1))
                {
                    _state = RState.Running;
                    return _pufEntity.CheckToPostMessage(eEvent.ERR_PUF, Module.ToString(),
                        (int)PUFMSG.ReadyForSwap);
                }
                return false;
            }
            else
            {
                _currentOperation = OperationStep.None;
                return true;
            }
        }
        /// 
        /// 监控执行
        /// 
        /// 
        public override bool MonitorProcess(SchedulerSequence schedulerSequence, bool hasMatchWafer)
        {
            //当前状态为ReadyForSwap
            if (_currentOperation == OperationStep.ReadyForSwap)
            {
                //若Puf已经完成ReadyForSwap动作,状态变更为WaitForSwap
                if (_pufEntity.State == (int)PUFSTATE.WaitForSwap)
                {
                    //当前操作变量为WaitFor LoaderUnload Complete
                    _currentOperation = OperationStep.WaitForLoaderUnloadComplete;
                    LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is WaitForLoaderUnloadComplete");
                }
            }
            else if (_currentOperation == OperationStep.WaitForLoaderUnloadComplete)
            {
                //Loader Entity Unload all
                if (CheckDualPufStateCanExecuteLoaderUnloadAll(hasMatchWafer))
                {
                    PostLoaderEntityUnloadAllSide();
                }
            }
            //puf 进行Swap
            else if(_currentOperation==OperationStep.Swap)
            {
                bool result = _pufEntity.CheckToPostMessage(eEvent.ERR_PUF, Module.ToString(),
                    (int)PUFMSG.Swap);
                if(result)
                {
                    _currentOperation = OperationStep.CheckSwapComplete;
                    LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is CheckSwapComplete");
                }
            }
            else if(_currentOperation==OperationStep.CheckSwapComplete)
            {
                //puf完成Swap后运动至Robot让Robot取片
                PostPufEntityGotoRobotForPick();
            }
            else if(_currentOperation==OperationStep.GotoRobotForPick)
            {
                //Efem 将Dummy片运输至Dummy Casstete
                PostEfemRobotTransferToDummyCassete();
            }
            else if(_currentOperation==OperationStep.WaitForRobotPick)
            {
                //等待Efem Robot完成传片
                if (RobotMoveHelper.Instance.IsBusy)
                {
                    RobotMoveHelper.Instance.Monitor(Module.ToString());
                }
                if(RobotMoveHelper.Instance.IsPickCompleted)
                {                    
                    _currentOperation = OperationStep.PufBackToPark;
                    LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is PufBackToBack");
                }
            }
            else if(_currentOperation==OperationStep.PufBackToPark)
            {
                if (RobotMoveHelper.Instance.IsBusy)
                {
                    RobotMoveHelper.Instance.Monitor(Module.ToString());
                }
                //Puf运动至Park安全位置
                bool result = _pufEntity.CheckToPostMessage(eEvent.ERR_PUF, Module.ToString(),
                        (int)PUFMSG.RobotPickComplete);
                if (result)
                {
                    _currentOperation = OperationStep.CheckParkComplete;
                    LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is CheckParkComplete");
                }
            }
            else if(_currentOperation==OperationStep.CheckParkComplete)
            {
                if (RobotMoveHelper.Instance.IsBusy)
                {
                    RobotMoveHelper.Instance.Monitor(Module.ToString());
                }
                //判定Puf运动是否完成
                if (_pufEntity.IsIdle&&RobotMoveHelper.Instance.IsIdle)
                {
                    _state = RState.End;
                }
            }
            return false;
        }
        /// 
        /// 检验Dual puf 是不是都处于WaitForSwap 状态,保证Loader可以UnloadAll
        /// 
        /// 
        private bool CheckDualPufStateCanExecuteLoaderUnloadAll(bool hasMatchWafer)
        {
            bool puf1ready = true;
            if(ModuleHelper.IsInstalled(ModuleName.PUF1))
            {
                PUFEntity puf1Entity = Singleton.Instance.GetModule(ModuleName.PUF1.ToString());
                if(hasMatchWafer)
                {
                    //B面有Wafer
                    if (WaferManager.Instance.CheckHasWafer(ModuleName.PUF1,1))
                    {
                        puf1ready = puf1Entity.State == (int)PUFSTATE.WaitForSwap;
                    }
                    else
                    {
                        puf1ready = false;
                    }
                }                
                else
                {
                    //任务仅一片Wafer,同时模块为PUF2
                    if(Module==ModuleName.PUF2)
                    {
                        puf1ready = puf1Entity.IsIdle;
                    }
                }
            }
            if(!puf1ready)
            {
                return false;
            }
            bool puf2ready = true;
            if (ModuleHelper.IsInstalled(ModuleName.PUF2))
            {
                PUFEntity puf2Entity = Singleton.Instance.GetModule(ModuleName.PUF2.ToString());
                if(hasMatchWafer)
                {
                    //B面有Wafer
                    if (WaferManager.Instance.CheckHasWafer(ModuleName.PUF2, 1))
                    {
                        puf2ready = puf2Entity.State == (int)PUFSTATE.WaitForSwap;
                    }
                    else
                    {
                        puf2ready = false;
                    }
                }                
                else
                {
                    //任务仅一片Wafer,同时模块为PUF1
                    if (Module == ModuleName.PUF1)
                    {
                        puf2ready = puf2Entity.IsIdle;
                    }
                }
            }
            if(!puf2ready)
            {
                return false;
            }
            //Loader中没有WaferHolder
            if(_loaderEntity.WaferHolderInfo==null)
            {
                return false;
            }
            if (_loaderEntity.State == (int)LOADERSTATE.WaitForUnload)
            {
                JetAxisBase _loadTransporterGantryAxis = DEVICE.GetDevice($"{ModuleName.Transporter2}.Gantry");
                if (_loadTransporterGantryAxis != null && !_loadTransporterGantryAxis.JudgeCompareTargetStation("Loader", "Right"))
                {
                    return false;
                }
            }
            return true;
        }
        /// 
        /// LoaderEntity Unload All
        /// 
        private void PostLoaderEntityUnloadAllSide()
        {
            //当前loader状态机为WaitForUnload
            if (_loaderEntity.State == (int)LOADERSTATE.WaitForUnload&&_currentOperation==OperationStep.WaitForLoaderUnloadComplete)
            {
                //触发loaderEntity UnloadAll
                _loaderEntity.CheckToPostMessage(eEvent.WARN_LOADER, ModuleName.Loader1.ToString(),
                    (int)LoaderMSG.UnloadAll);
            }
            //若Loader Unload操作完成,状态变更为WaitForLoad,puf操作变更为Swap
            else if (_loaderEntity.State == (int)LOADERSTATE.WaitForLoad)
            {
                _currentOperation = OperationStep.Swap;
                LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is Swap");
            }
            else if (_loaderEntity.State == (int)LOADERSTATE.Unloading)
            {
                return;
            }
            //else
            //{
            //    LOG.WriteLog(eEvent.ERR_PUF, Module.ToString(), $"Loader1 Current State {(LOADERSTATE)_loaderEntity.State} is not avaible");
            //    _state = RState.Failed;
            //}
        }
        /// 
        /// PUF Entity运动至Robot准备让robot pick
        /// 
        private void PostPufEntityGotoRobotForPick()
        {
            if (_pufEntity.Module == ModuleName.PUF2)
            {
                if (_pufEntity.State == (int)PUFSTATE.AferSwapParkStation)
                {
                    bool result = _pufEntity.CheckToPostMessage(eEvent.ERR_PUF, Module.ToString(),
                        (int)PUFMSG.ReadyForRobotPick);
                    if (result)
                    {
                        NotifyWaferTaskSchedulerLoaderComplete();
                        _currentOperation = OperationStep.GotoRobotForPick;
                        LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is GotoRobotForPick");
                    }
                }
            }
            else
            {
                if (_pufEntity.State == (int)PUFSTATE.AferSwapParkStation)
                {
                    JetAxisBase loaderRotationAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.Rotation");
                    if (loaderRotationAxis != null && loaderRotationAxis.CheckPositionIsInStation(loaderRotationAxis.MotionData.MotorPosition, "TRNPA"))
                    {
                        if (_loaderEntity.State == (int)LOADERSTATE.Loading || _loaderEntity.IsIdle)
                        {
                            bool result = _pufEntity.CheckToPostMessage(eEvent.ERR_PUF, Module.ToString(),
                        (int)PUFMSG.ReadyForRobotPick);
                            if (result)
                            {
                                NotifyWaferTaskSchedulerLoaderComplete();
                                _currentOperation = OperationStep.GotoRobotForPick;
                                LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is GotoRobotForPick");
                            }
                        }
                    }
                }
            }
        }
        /// 
        /// 通知Wafer对应的SchedulerLoader工序已经完成
        /// 
        private void NotifyWaferTaskSchedulerLoaderComplete()
        {
            //puf A面是否存在Wafer
            if (WaferManager.Instance.CheckHasWafer(_pufEntity.Module, 0))
            {
                WaferInfo waferInfo = WaferManager.Instance.GetWafer(_pufEntity.Module, 0);
                if (waferInfo!=null&&waferInfo.WaferType==WaferType.Production)
                {
                    _isProductionWafer = true;
                    WaferTask waferTask = WaferTaskManager.Instance.GetWaferTask(waferInfo.WaferID);
                    if (waferTask!=null)
                    {
                        waferTask.UpdateLoaderSchedulerSequenceComplete();
                    }
                }
            }
        }
        /// 
        /// 将Dummy片移动至Dummy Cassete
        /// 
        private void PostEfemRobotTransferToDummyCassete()
        {
            if (_pufEntity.State == (int)PUFSTATE.WaitForRobotPick)
            {
                //生产片待EfemRobot取完片进行PufBackToPark状态
                if (_isProductionWafer)
                {
                    bool hasWafer = WaferManager.Instance.CheckHasWafer(_pufEntity.Module, 0);
                    if (!hasWafer)
                    {
                        _currentOperation = OperationStep.PufBackToPark;
                        LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is PufBackToPark");
                    }
                }
                else
                {
                    //A面Wafer
                    WaferInfo waferInfo = WaferManager.Instance.GetWafer(_pufEntity.Module, 0);
                    if (waferInfo == null)
                    {
                        return;
                    }
                    //Dummy片
                    if (waferInfo.WaferType == WaferType.Assit)
                    {
                        if (_efemEntity.IsIdle)
                        {
                            var result = SchedulerSequenceManager.Instance.GetAvaibleDummySlots();
                            if (result.moduleName != ModuleName.Unknown)
                            {
                                MoveItem moveItem = new MoveItem(_pufEntity.Module, 0, result.moduleName, result.slot, Aitex.Sorter.Common.Hand.Blade1);
                                if(RobotMoveHelper.Instance.IsIdle)
                                {
                                    RobotMoveHelper.Instance.Start(moveItem,Module.ToString());
                                    _currentOperation = OperationStep.WaitForRobotPick;
                                    LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is WaitForRobotPick");
                                }
                            }
                            else
                            {
                                LOG.WriteBackgroundLog(eEvent.WARN_PUF, Module.ToString(), "dummy slot is empty");
                            }
                        }
                        else
                        {
                            LOG.WriteBackgroundLog(eEvent.WARN_PUF, Module.ToString(), $"wafer {waferInfo.WaferID} efem is not idle");
                        }
                    }
                    else
                    {
                        LOG.WriteBackgroundLog(eEvent.WARN_PUF, Module.ToString(), $"wafer {waferInfo.WaferID} is not dummy wafer");
                    }
                }
            }
        }
        /// 
        /// 检验前置条件
        /// 
        /// 
        /// 
        /// 
        public override bool CheckPrecondition(List schedulerSequences, int sequenceIndex, object parameter, string materialId, ref string reason)
        {
            if (_state == RState.Running)
            {
                reason = "scheduler module is already running";
                return false;
            }
            if (_pufEntity==null)
            {
                reason = "Puf entity is null";
                return false;
            }
            bool forward=(bool)parameter;
            if(forward)
            {
                if (_pufEntity.State == (int)PUFSTATE.WaitForRobotPlace)
                {
                    return true;
                }
                else
                {
                    reason = $"{_pufEntity.Module} forward,but state is not WaitForRobotPlace";
                    return false;
                }
            }
            else
            {
                if (_pufEntity.State == (int)PUFSTATE.WaitForRobotPick)
                {
                    return true;
                }
                else
                {
                    reason = $"{_pufEntity.Module} backward,but state is not WaitForRobotPick";
                    return false;
                }
            }
        }
        /// 
        /// 获取可用资源
        /// 
        /// 
        /// 
        /// 
        public override bool GetAvaibleMaterial(int sequenceIndex, object parameter)
        {
            return true;
        }
    }
}