using Aitex.Core.RT.Fsm;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.Routine;
using Aitex.Core.Util;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Schedulers;
using PunkHPX8_Core;
using PunkHPX8_RT.Modules;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MECF.Framework.Common.SubstrateTrackings;
using PunkHPX8_RT.Modules.SRD;
using PunkHPX8_RT.Modules.VpwMain;
using PunkHPX8_RT.Modules.VpwCell;
namespace PunkHPX8_RT.Schedulers.EfemRobot
{
    public class SchedulerRobot : SchedulerModule
    {
        private enum SchedulerRobotOperation
        {
            None,
            Pick,
            PickWait,
            Place,
            PlaceWait
        }
        #region 内部变量
        private EfemEntity _efemEntity;
        #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 SchedulerRobot(ModuleName module) : base(module.ToString())
        {
            _efemEntity = Singleton.Instance.EFEM;
        }
        /// 
        /// 执行
        /// 
        /// 
        /// 
        public override bool RunProcess(object recipe, object parameter, List syncMessages)
        {
            if (_efemEntity.IsBusy)
            {
                return false;
            }
            MoveItem moveItem = (MoveItem)parameter;
            if (moveItem.SourceModule != ModuleName.Unknown&&moveItem.DestinationModule!=ModuleName.Unknown)
            {
                SynchorinzeModuleMessages(syncMessages);
                _state = RState.Running;
                if (RobotMoveHelper.Instance.IsIdle)
                {
                    RobotMoveHelper.Instance.Start(moveItem, Module.ToString());
                    return true;
                }
            }
            return false;
        }
        /// 
        /// 监控执行
        /// 
        /// 
        public override bool MonitorProcess(SchedulerSequence schedulerSequence, bool hasMatchWafer)
        {
            RobotMoveHelper.Instance.Monitor(Module.ToString());
            if (RobotMoveHelper.Instance.IsIdle)
            {
                _state = RState.End;
            }
            return true;
        }
        
        /// 
        /// 检验前置条件
        /// 
        /// 
        /// 
        /// 
        public override bool CheckPrecondition(List schedulerSequences, int sequenceIndex, object parameter,string materialId, ref string reason)
        {
            if (parameter == null)
            {
                reason = "parameter is null";
                return true;
            }
            if (_state == RState.Running)
            {
                reason = "scheduler module is already running";
                return false;
            }
            if(_efemEntity.IsBusy)
            {
                reason = "efem is busy";
                return false;
            }
            if(_efemEntity.IsError)
            {
                reason = "efem is error";
                return false;
            }
            MoveItem moveItem = (MoveItem)parameter;
            if(WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot,(int)moveItem.RobotHand))
            {
                reason = "robot has wafer";
                return false;
            }
            if (moveItem.SourceModule == ModuleName.Unknown)
            {
                UpdateUnkownSourceModule(schedulerSequences, moveItem, sequenceIndex);
            }
            if (moveItem.DestinationModule == ModuleName.Unknown)
            {
                bool result= UpdateUnkownTargetModule(schedulerSequences, moveItem, sequenceIndex);
                if (!result)
                {
                    reason = "efem robot confirm target module failed";
                    return false;
                }
            }
            if (!WaferManager.Instance.CheckHasWafer(moveItem.SourceModule, moveItem.SourceSlot))
            {
                reason = $"{moveItem.SourceModule} slot {moveItem.SourceSlot} has no wafer";
                return false;
            }
            if (WaferManager.Instance.CheckHasWafer(moveItem.DestinationModule, moveItem.DestinationSlot))
            {
                reason = $"{moveItem.DestinationSlot} slot {moveItem.SourceSlot} has wafer";
                return false;
            }
            if (ModuleHelper.IsVPWCell(moveItem.DestinationModule)||ModuleHelper.IsVPWCell(moveItem.SourceModule))
            {
                VpwCellEntity vpwEntity = Singleton.Instance.GetModule(moveItem.DestinationModule.ToString());
                if (vpwEntity != null)
                {
                    if (vpwEntity.State == (int)VPWCellState.WaitForRunRecipe)
                    {
                        return true;
                    }
                    else
                    {
                        if (vpwEntity.IsIdle)
                        {
                            if (sequenceIndex + 1 < schedulerSequences.Count)
                            {
                                SchedulerSequence nextSequence = schedulerSequences[sequenceIndex + 1];
                                vpwEntity.CheckToPostMessage(eEvent.INFO_VPW, Module.ToString(),
                                    (int)VPWCellMsg.Prepare, nextSequence.Recipe);
                            }
                        }
                        reason = $"{vpwEntity.Module} state is not WaitForRunRecipe";
                        return false;
                    }
                }
                else
                {
                    reason = $"{moveItem.DestinationModule} is null";
                }
            }
            return true;
        }
        /// 
        /// 更新未知源模块
        /// 
        private void UpdateUnkownSourceModule(List schedulerSequences, MoveItem moveItem, int sequenceIndex)
        {
            if (moveItem.SourceModule == ModuleName.Unknown)
            {
                if (sequenceIndex >= 1 && sequenceIndex - 1 < schedulerSequences.Count)
                {
                    SchedulerSequence preSchedulerSequence = schedulerSequences[sequenceIndex - 1];
                    if (preSchedulerSequence != null && preSchedulerSequence.SchedulerModule != null)
                    {
                        moveItem.SourceModule = preSchedulerSequence.SchedulerModule.Module;
                    }
                }
            }
        }
        /// 
        /// 更新未知目标模块
        /// 
        private bool UpdateUnkownTargetModule(List schedulerSequences, MoveItem moveItem, int sequenceIndex)
        {
            SchedulerSequence currentSchedulerSequence= schedulerSequences[sequenceIndex];
            ModuleName moduleName = ModuleName.Unknown;
            if (moveItem.DestinationType == ModuleType.SRD)
            {
                SRDEntity srd1Entity = Singleton.Instance.GetModule(ModuleName.SRD1.ToString());
                if (srd1Entity != null&&srd1Entity.IsIdle&&srd1Entity.IsAuto&&WaferManager.Instance.CheckNoWafer(ModuleName.SRD1.ToString(),0))
                {
                    moduleName = ModuleName.SRD1;
                }
                else
                {
                    SRDEntity srd2Entity= Singleton.Instance.GetModule(ModuleName.SRD2.ToString());
                    if (srd2Entity != null && srd2Entity.IsIdle&&srd2Entity.IsAuto && WaferManager.Instance.CheckNoWafer(ModuleName.SRD2.ToString(), 0))
                    {
                        moduleName=ModuleName.SRD2;
                    }
                }
            }
            else
            {
                return false;
            } 
            
            if (moduleName == ModuleName.Unknown)
            {
                return false;
            }
            else
            {
                if(WaferManager.Instance.CheckHasWafer(moduleName,0))
                {
                    return false;
                }
                IModuleEntity moduleEntity = Singleton.Instance.GetModule(moduleName.ToString());
                if (moduleEntity==null)
                {
                    return false;
                }
                if (moduleEntity.IsBusy)
                {
                    return false;
                }
                moveItem.DestinationModule = moduleName;
                if (sequenceIndex + 1 < schedulerSequences.Count)
                {
                    SchedulerSequence sequence = schedulerSequences[sequenceIndex + 1];
                    if (sequence.SchedulerModule == null)
                    {
                        sequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(moduleName);
                        sequence.ModuleName = moduleName;
                    }
                }
            }
            return true;
        }
        public override void ResetTask()
        {
            base.ResetTask();
            RobotMoveHelper.Instance.Reset();
        }
    }
}