using Aitex.Core.RT.Device;
using Aitex.Core.RT.Fsm;
using Aitex.Core.RT.Log;
using Aitex.Core.Util;
using CyberX8_Core;
using CyberX8_RT.Devices.AXIS;
using CyberX8_RT.Modules;
using CyberX8_RT.Modules.Loader;
using CyberX8_RT.Modules.Metal;
using CyberX8_RT.Modules.Prewet;
using CyberX8_RT.Modules.Transporter;
using CyberX8_RT.Schedulers.EfemRobot;
using MECF.Framework.Common.CommonData;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.RecipeCenter;
using MECF.Framework.Common.Schedulers;
using MECF.Framework.Common.WaferHolder;
using MECF.Framework.RT.Core.Equipments;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Markup;
namespace CyberX8_RT.Schedulers.Transporter
{
    public class SchedulerProcessTransporter : SchedulerModule
    {
        #region 内部变量
        /// 
        /// Process Transporter
        /// 
        private TransporterEntity _processTransporterEntity;
        /// 
        /// Loader transporterEntity
        /// 
        private TransporterEntity _loaderTransporterEntity;
        /// 
        /// 调度发送消息
        /// 
        private SchedulerPostMsg _schedulerPostMsg=new SchedulerPostMsg();
        /// 
        /// 推送消息结果
        /// 
        private bool _postMsgResult = false;
        #endregion
        #region 属性
        /// 
        /// 是否空闲
        /// 
        public override bool IsIdle
        {
            get { return _state == RState.End; }
        }
        /// 
        /// 是否错误
        /// 
        public override bool IsError
        {
            get { return _state == RState.Failed || _state == RState.Timeout; }
        }
        public bool IsBusy
        {
            get { return _state == RState.Running; }
        }
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public SchedulerProcessTransporter(ModuleName module) : base(module.ToString())
        {
            _processTransporterEntity = Singleton.Instance.GetModule(module.ToString());
            _loaderTransporterEntity = Singleton.Instance.GetModule(ModuleName.Transporter2.ToString());
        }
        /// 
        /// 执行
        /// 
        /// 
        /// 
        public override bool RunProcess(object recipe, object parameter, List syncMessages)
        {
            if (parameter == null || !(parameter is TransporterAction))
            {
                return false;
            }
            TransporterAction action = (TransporterAction)parameter;
            WaferHolderMoveItem waferHolderMoveItem = (WaferHolderMoveItem)action.Parameter;
            if (waferHolderMoveItem.SourceModule != ModuleName.Unknown && waferHolderMoveItem.DestModule != ModuleName.Unknown)
            {
                SchedulerLoaderTransporter schedulerLoaderTransporter = (SchedulerLoaderTransporter)SchedulerManager.Instance.GetScheduler(ModuleName.Transporter2);
                if (schedulerLoaderTransporter.IsBusy && _loaderTransporterEntity.IsIdle)
                {
                    return false;
                }
                if (!_processTransporterEntity.CheckOtherEntityStatus(waferHolderMoveItem.SourceModule.ToString()))
                {
                    return false;
                }
                if (!_processTransporterEntity.CheckOtherEntityStatus(waferHolderMoveItem.DestModule.ToString()))
                {
                    return false;
                }
                if (!WaferHolderManager.Instance.HasWaferHolder(waferHolderMoveItem.SourceModule.ToString()))
                {
                    return false;
                }
                if (WaferHolderManager.Instance.HasWaferHolder(waferHolderMoveItem.DestModule.ToString()))
                {
                    return false;
                }
                return TransferWaferHolderNonLoader(waferHolderMoveItem);
            }
            return true;
        }
        /// 
        /// 传输WaferHolder(无WaferHolder)
        /// 
        /// 
        private bool TransferWaferHolderNonLoader(WaferHolderMoveItem waferHolderMoveItem)
        {
            IModuleEntity moduleEntity = Singleton.Instance.GetModule(waferHolderMoveItem.DestModule.ToString());
            if (moduleEntity != null)
            {
                if (waferHolderMoveItem.SourceModule == ModuleName.Unknown || waferHolderMoveItem.DestModule == ModuleName.Unknown)
                {
                    return false;
                }
                bool result = false;
                if (waferHolderMoveItem.DestModuleType != ModuleType.Metal)
                {
                    result = _processTransporterEntity.CheckToPostMessage(eEvent.WARN_TRANSPORTER,
                        Module.ToString(), (int)TransporterMSG.Transfer, waferHolderMoveItem.SourceModule.ToString(), waferHolderMoveItem.DestModule.ToString());                    
                }
                else
                {
                    result = _processTransporterEntity.CheckToPostMessage(eEvent.WARN_TRANSPORTER,
                        Module.ToString(), (int)TransporterMSG.PickUpMoveTo, waferHolderMoveItem.SourceModule.ToString(), waferHolderMoveItem.DestModule.ToString());
                }
                if (result)
                {
                    _state = RState.Running;
                    _postMsgResult = false;
                    _schedulerPostMsg.Reset();
                }
                return result;
            }
            return false;
        }
        /// 
        /// 监控执行
        /// 
        /// 
        public override bool MonitorProcess(SchedulerSequence schedulerSequence,bool hasMatchWafer)
        {
            TransporterAction transporterAction = (TransporterAction)schedulerSequence.Parameters;
            WaferHolderMoveItem waferHolderMoveItem = (WaferHolderMoveItem)transporterAction.Parameter;
            //检验PostMsg的结果
            if (!_postMsgResult)
            {
                if (_processTransporterEntity.IsError)
                {
                    return false;
                }
                _postMsgResult = CheckPostMsg(waferHolderMoveItem);
                if (!_postMsgResult)
                {
                    return false;
                }
            }
            if (waferHolderMoveItem.DestModuleType != ModuleType.Metal)
            {
                if (_processTransporterEntity.IsIdle)
                {
                    if (_processTransporterEntity.WaferHolderInfo != null)
                    {
                        return false;
                    }
                    if (waferHolderMoveItem.SourceModuleType == ModuleType.Prewet)
                    {
                        PrewetPickComplete();
                    }
                    _state = RState.End;
                }
            }
            else
            {
                if (waferHolderMoveItem.SourceModuleType == ModuleType.Prewet)
                {
                    if (_processTransporterEntity.WaferHolderInfo != null)
                    {
                        PrewetPickComplete();
                    }
                }
                //ProcessTransporter完成PickUp和MoveTo
                if (_processTransporterEntity.State == (int)TransporterState.PickUpMoveToComplete)
                {
                    MetalEntity metalEntity = Singleton.Instance.GetModule(waferHolderMoveItem.DestModule.ToString());
                    if (metalEntity != null)
                    {
                        //关闭FlowValve
                        if (metalEntity.State == (int)MetalState.WaitCloseFlow)
                        {
                            metalEntity.CheckToPostMessage(eEvent.WARN_METAL, waferHolderMoveItem.DestModule.ToString(),
                                (int)MetalMsg.CloseFlowValve);
                        }
                        //完成FlowValve关闭后状态变更为等待打开FlowValve,执行Place
                        else if (metalEntity.State == (int)MetalState.WaitOpenFlow)
                        {                            
                            _processTransporterEntity.CheckToPostMessage(eEvent.WARN_TRANSPORTER, Module.ToString(),
                                (int)TransporterMSG.Place, waferHolderMoveItem.DestModule.ToString());
                        }
                    }
                }
                //Transporter完成Place后
                else if (_processTransporterEntity.IsIdle)
                {
                    if(_processTransporterEntity.WaferHolderInfo!=null)
                    {
                        return false;
                    }
                    MetalEntity metalEntity = Singleton.Instance.GetModule(waferHolderMoveItem.DestModule.ToString());
                    if (metalEntity != null)
                    {
                        //打开FlowValve,完成传输任务
                        if (metalEntity.State == (int)MetalState.WaitOpenFlow)
                        {
                            bool result= metalEntity.CheckToPostMessage(eEvent.WARN_METAL, waferHolderMoveItem.DestModule.ToString(),
                                (int)MetalMsg.OpenFlowValve);
                            if(result)
                            {
                                _state = RState.End;
                            }
                        }
                        
                    }
                }
            }
            return true;
        }
        /// 
        /// 检验PostMsg的结果
        /// 
        /// 
        /// 
        private bool CheckPostMsg(WaferHolderMoveItem waferHolderMoveItem)
        {
            if (waferHolderMoveItem.DestModuleType == ModuleType.Metal)
            {
                return _schedulerPostMsg.PostMsg(_processTransporterEntity, _processTransporterEntity.State,
                    eEvent.WARN_TRANSPORTER, Module.ToString(), (int)TransporterMSG.PickUpMoveTo,
                    (int)TransporterState.PickUpMoveToing, waferHolderMoveItem.SourceModule.ToString(), waferHolderMoveItem.DestModule.ToString());
            }
            else
            {
                return _schedulerPostMsg.PostMsg(_processTransporterEntity, _processTransporterEntity.State,
                    eEvent.WARN_TRANSPORTER, Module.ToString(), (int)TransporterMSG.Transfer,
                    (int)TransporterState.Transfering, waferHolderMoveItem.SourceModule.ToString(), waferHolderMoveItem.DestModule.ToString());
            }
        }
        /// 
        /// PrewetPick完成事件
        /// 
        private void PrewetPickComplete()
        {
            PrewetEntity prewetEntity = Singleton.Instance.GetModule(ModuleName.Prewet1.ToString());
            if (prewetEntity.State == (int)PrewetState.WaitForPick)
            {
                prewetEntity.CheckToPostMessage(eEvent.WARN_PREWET, ModuleName.Prewet1.ToString(),
                    (int)PrewetMsg.PickComplete);
            }
        }
        /// 
        /// 检验前置条件
        /// 
        /// 
        /// 
        /// 
        public override bool CheckPrecondition(List schedulerSequences, int sequenceIndex, object parameter, string materialId,ref string reason)
        {
            if (!(parameter is TransporterAction))
            {
                reason = "parameter is not TransporterAction";
                return false;
            }
            TransporterAction transporterAction= (TransporterAction)parameter;
            if (_state == RState.Running)
            {
                reason = "scheduler module is already running";
                return false;
            }
            if (_processTransporterEntity.WaferHolderInfo != null)
            {
                reason = "process transporter has wafer shuttle";
                return false;
            }
            //电机是否还在执行动作
            JetAxisBase gantryAxis = DEVICE.GetDevice($"{ModuleName.Transporter1}.Gantry");
            if(gantryAxis==null)
            {
                reason = "process transporter gantry is null";
                return false;
            }
            if (gantryAxis.Status == RState.Running)
            {
                reason = "process transporter gantry is running";
                return false;
            }
            JetAxisBase elevatorAxis = DEVICE.GetDevice($"{ModuleName.Transporter1}.Elevator");
            if (elevatorAxis == null)
            {
                reason = "process transporter elevator is null";
                return false;
            }
            if (elevatorAxis.Status == RState.Running)
            {
                reason = "process transporter elevator is running";
                return false;
            }
            if (_processTransporterEntity.IsBusy)
            {
                reason = "process transporter entity is busy";
                return false;
            }
            WaferHolderMoveItem waferHolderMoveItem = (WaferHolderMoveItem)transporterAction.Parameter;
            bool result = false;
            //更新未知源模块
            UpdateUnkownSourceModule(schedulerSequences, waferHolderMoveItem, sequenceIndex);
            //源为Prewet
            if (waferHolderMoveItem.SourceModule == ModuleName.Prewet1)
            {
                result= CheckSourcePrewetCondition();
                if(!result)
                {
                    reason = "process transporter sourcemodule prewet condition is not avaible";
                    return false;
                }
            }
            bool existEnableCell = false;
            //更新未知目标模块
            result = UpdateUnkownTargetModule(schedulerSequences, waferHolderMoveItem, sequenceIndex,materialId,ref existEnableCell);
            if (!result)
            {
                reason = "process transporter moveitem target module is unknown";
                return false;
            }
            if (waferHolderMoveItem.DestModuleType==ModuleType.Metal)
            {
                if(!ModuleHelper.IsMetal(waferHolderMoveItem.DestModule))
                {
                    reason = "process transporter target module is not metal";
                    return false;
                }
                UpdateNextMetalScheduler(schedulerSequences, sequenceIndex, waferHolderMoveItem.DestModule);
                
                result= CheckTargetMetalCondition(waferHolderMoveItem.DestModule.ToString(),waferHolderMoveItem, schedulerSequences, sequenceIndex);
                if(!result)
                {
                    reason = $"process transporter target module {waferHolderMoveItem.DestModule} condition is false";
                    return false;
                }
            }
            return true;
        }
        /// 
        /// 更新下一块Metal
        /// 
        /// 
        /// 
        private void UpdateNextMetalScheduler(List schedulerSequences,int sequenceIndex,ModuleName metalName)
        {
            if(sequenceIndex+1
        /// 更新未知目标模块
        /// 
        private bool UpdateUnkownTargetModule(List schedulerSequences, WaferHolderMoveItem waferHolderMoveItem, int sequenceIndex,string materialId,ref bool existEnableCell)
        {
            if (waferHolderMoveItem.DestModule == ModuleName.Unknown)
            {
                if (sequenceIndex + 1 < schedulerSequences.Count)
                {
                    SchedulerSequence sequence = schedulerSequences[sequenceIndex + 1];
                    ModuleName moduleName = ModuleName.Unknown;
                    if (waferHolderMoveItem.DestModuleType == ModuleType.Metal)
                    {
                        if (sequence.Recipe != null && sequence.Recipe is DepRecipe)
                        {
                            //获取可用的Metal以及Rinse
                            DepRecipe depRecipe = (DepRecipe)sequence.Recipe;
                            ModuleName tmpName = SchedulerSequenceManager.Instance.CalculateAvaibleMetalCellByChemistry(depRecipe.Chemistry, 
                                waferHolderMoveItem.SourceModule.ToString(),sequence.SequenceType,sequence.WaferSize,ref existEnableCell);
                            if (tmpName != ModuleName.Unknown)
                            {
                                IModuleEntity moduleEntity = Singleton.Instance.GetModule(tmpName.ToString());
                                if (SchedulerSequenceManager.Instance.CheckMetalCellRecipeTimeAvaible(moduleEntity, depRecipe))
                                {
                                    moduleName = tmpName;
                                }
                            }
                        }
                    }
                    else if(waferHolderMoveItem.DestModuleType==ModuleType.Rinse)
                    {
                        if (waferHolderMoveItem.SourceModuleType == ModuleType.Metal)
                        {
                            moduleName = SchedulerSequenceManager.Instance.GetAvaibleEmptyModuleCell(waferHolderMoveItem.DestModuleType,sequence.SequenceType,waferHolderMoveItem.SourceModule);
                        }
                        else
                        {
                            for(int i = sequenceIndex - 1; i >= 0; i--)
                            {
                                SchedulerSequence tmp=schedulerSequences[i];
                                if (tmp.ModuleType == ModuleType.Metal&&ModuleHelper.IsMetal(tmp.ModuleName))
                                {
                                    moduleName = SchedulerSequenceManager.Instance.GetAvaibleEmptyModuleCell(waferHolderMoveItem.DestModuleType,tmp.SequenceType, tmp.ModuleName);
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        moduleName = SchedulerSequenceManager.Instance.GetAvaibleEmptyModuleCell(waferHolderMoveItem.DestModuleType,sequence.SequenceType,waferHolderMoveItem.SourceModule);
                    }
                    if (moduleName == ModuleName.Unknown)
                    {
                        return false;
                    }
                    else
                    {
                        LOG.WriteLog(eEvent.EV_SCHEDULER, Module.ToString(), $"{materialId} ProcessTransporter Confirm Next Cell {moduleName}");
                        waferHolderMoveItem.DestModule = moduleName;
                        if (sequence.SchedulerModule == null)
                        {
                            sequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(moduleName);
                            sequence.ModuleName = moduleName;
                        }
                    }
                }
            }
            return true;
        }
        /// 
        /// 更新未知源模块
        /// 
        private void UpdateUnkownSourceModule(List schedulerSequences, WaferHolderMoveItem waferHolderMoveItem, int sequenceIndex)
        {
            if (waferHolderMoveItem.SourceModule != ModuleName.Unknown)
            {
                return;
            }
            for (int i = sequenceIndex - 1; i >= 0; i--)
            {
                SchedulerSequence preSchedulerSequence = schedulerSequences[i];
                if (preSchedulerSequence.State != RState.End)
                {
                    continue;
                }
                if (i == sequenceIndex - 1)
                {
                    if (preSchedulerSequence != null && preSchedulerSequence.SchedulerModule != null)
                    {
                        waferHolderMoveItem.SourceModule = preSchedulerSequence.SchedulerModule.Module;
                        break;
                    }
                }
                else
                {
                    //用于Metal出错后跳过了几个步骤,transporter源模块取至前面跳过的transporter1的目标模块
                    if(preSchedulerSequence.ModuleName==ModuleName.Transporter1)
                    {
                        TransporterAction transporterAction = preSchedulerSequence.Parameters as TransporterAction;
                        if (transporterAction.ActionMsg != TransporterMSG.Transfer)
                        {
                            continue;
                        }
                        WaferHolderMoveItem preWaferHolderMoveItem = transporterAction.Parameter as WaferHolderMoveItem;
                        if (preSchedulerSequence != null && preWaferHolderMoveItem.DestModule != ModuleName.Unknown)
                        {
                            waferHolderMoveItem.SourceModule = preWaferHolderMoveItem.DestModule;
                            break;
                        }
                    }
                }
            }
        }
        /// 
        /// 检验源Prewet前置条件
        /// 
        /// 
        private bool CheckSourcePrewetCondition()
        {
            PrewetEntity prewetEntity = Singleton.Instance.GetModule(ModuleName.Prewet1.ToString());
            if (prewetEntity.State == (int)PrewetState.WaitForPick)
            {
                return true;
            }
            return false;
        }
        /// 
        /// 检验目标Metal前置条件
        /// 
        /// 
        private bool CheckTargetMetalCondition(string metalName,WaferHolderMoveItem waferHolderMoveItem,List schedulerSequences,int sequenceIndex)
        {
            MetalEntity metalEntity = Singleton.Instance.GetModule(metalName);
            if (metalEntity.IsIdle)
            {
                metalEntity.CheckToPostMessage(eEvent.WARN_METAL, metalName,
                    (int)MetalMsg.CurrentShortTest);
            }
            else if (metalEntity.State == (int)MetalState.WaitCloseFlow)
            {
                return true;
            }
            else if (metalEntity.IsError)
            {
                waferHolderMoveItem.DestModule = ModuleName.Unknown;
                SchedulerSequence nextSequence = schedulerSequences[sequenceIndex + 1];
                if (nextSequence != null)
                {
                    nextSequence.SchedulerModule = null;
                    nextSequence.ModuleName = ModuleName.Unknown;
                }
            }
            return false;
        }
        public override void ResetTask()
        {
            base.ResetTask();
            _schedulerPostMsg.Reset();
            _postMsgResult = false;
        }
    }
}