using Aitex.Core.RT.Log;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using CyberX8_Core;
using CyberX8_RT.Modules;
using CyberX8_RT.Modules.Dryer;
using CyberX8_RT.Modules.Metal;
using CyberX8_RT.Modules.Prewet;
using CyberX8_RT.Modules.Transporter;
using CyberX8_RT.Schedulers;
using MECF.Framework.Common.CommonData;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.ToolLayout;
using MECF.Framework.Common.WaferHolder;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.TMs;
using SecsGem.Core.ItemModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CyberX8_RT.Dispatch
{
    public class WaferHolderTaskDispatcher : Singleton<WaferHolderTaskDispatcher>
    {
        /// <summary>
        /// 分析
        /// </summary>
        public void Analyse()
        {
            List <WaferHolderTask> waferHolderTasks = WaferHolderTaskManager.Instance.LoaderWaferHolderTaskList().ToList();
            bool exsitTransport2FromBuffer = false;
            List<WaferHolderTask> canceledWaferHolderTask = new List<WaferHolderTask>();
            foreach (var item in waferHolderTasks)
            {
                SchedulerSequence currentSequence = item.GetCurrentSchedulerSequence();
                if (currentSequence == null)
                {
                    item.Run();
                    continue;
                }
                //处理ProcessTransporter逻辑
                if (currentSequence.ModuleName == ModuleName.Transporter1)
                {
                    DealProcessTransporterScheduler(currentSequence, item, waferHolderTasks);
                }
                //处理LoaderTransporter逻辑 
                else if(currentSequence.ModuleName==ModuleName.Transporter2)
                {
                    DealLoaderTransporterScheduler(currentSequence, item, waferHolderTasks,canceledWaferHolderTask,ref exsitTransport2FromBuffer);                    
                }
                else
                {
                    item.Run();
                }
            }

            RemoveCanceledTask(canceledWaferHolderTask);
        }
        /// <summary>
        /// 处理ProcessTransporter
        /// </summary>
        /// <param name="sequence"></param>
        private void DealProcessTransporterScheduler(SchedulerSequence currentSequence,WaferHolderTask item,List<WaferHolderTask> waferHolderTasks)
        {
            int transporterTransferSeconds = SC.GetValue<int>("Transporter.TransporterTransferSeconds");
            if (currentSequence.State == RState.End)
            {
                item.Run();
                return;
            }
            if (currentSequence.State == RState.Running)
            {
                item.Run();
                return;
            }
            if (CheckOtherTransporterIsRunning(waferHolderTasks, item,ModuleName.Transporter1))
            {
                return;
            }
            //存在其他任务当前source为prewet同时prewet状态为WaitForPick
            if (CheckPrewetIsWaitForPick(waferHolderTasks, item) && currentSequence.State == RState.Init)
            {
                return;
            }
            if (currentSequence.State == RState.Init)
            {
                AnalyseProcessTransporterSchedulerSequence(currentSequence, item, transporterTransferSeconds);
            }
        }
        /// <summary>
        /// 处理LoaderTransPorter
        /// </summary>
        /// <param name="currentSequence"></param>
        /// <param name="item"></param>
        /// <param name="waferHolderTasks"></param>
        private void DealLoaderTransporterScheduler(SchedulerSequence currentSequence,WaferHolderTask item, List<WaferHolderTask> waferHolderTasks, 
            List<WaferHolderTask> canceledWaferHolderTask, ref bool exsitTransport2FromBuffer)
        {
            if (currentSequence.State == RState.End)
            {
                item.Run();
                return;
            }
            if (currentSequence.State == RState.Running)
            {
                item.Run();
                return;
            }
            if (CheckOtherTransporterIsRunning(waferHolderTasks, item, ModuleName.Transporter2))
            {
                return;
            }
            if (!(currentSequence.Parameters is WaferHolderMoveItem))
            {
                return;
            }
            WaferHolderMoveItem waferHolderMoveItem = currentSequence.Parameters as WaferHolderMoveItem;
            if (waferHolderMoveItem.SourceModuleType == ModuleType.Buffer && waferHolderMoveItem.DestModuleType == ModuleType.Prewet)
            {
                if (item.State == WaferHolderTaskState.Canceled)
                {
                    canceledWaferHolderTask.Add(item);
                    return;
                }
                if (!exsitTransport2FromBuffer)
                {
                    exsitTransport2FromBuffer = true;
                    item.Run();
                }
            }
            else if (waferHolderMoveItem.SourceModuleType == ModuleType.Dryer)
            {
                if (waferHolderMoveItem.DestModuleType == ModuleType.Buffer)
                {
                    if (WaferHolderManager.Instance.HasWaferHolder("Loader"))
                    {
                        item.Run();
                        return;
                    }
                    if (CheckExistWaferHolderTaskIsCreateState(waferHolderTasks, item))
                    { 
                        item.Run();
                        return;
                    }
                    if (CheckDryerWaferHolderIdle(waferHolderTasks, item))
                    {
                        item.Run();
                        return;
                    }
                    else
                    {
                        item.UpdateDryerLastSchedulerComplete();
                    }
                }
                else
                {
                    item.Run();
                }
            }
            else
            {
                item.Run();
            }
        }
        /// <summary>
        /// 是否存在未启动的WaferHolderTask
        /// </summary>
        /// <param name="waferHolderTasks"></param>
        /// <param name="waferHolderTask"></param>
        /// <returns></returns>
        private bool CheckExistWaferHolderTaskIsCreateState(List<WaferHolderTask> waferHolderTasks, WaferHolderTask waferHolderTask)
        {
            foreach(WaferHolderTask item in waferHolderTasks)
            {
                if (item.ID == waferHolderTask.ID)
                {
                    continue;
                }
                if (item.State == WaferHolderTaskState.Created)
                {
                    return true;
                }
            }
            return false;
        }
        /// <summary>
        /// 检验是否存在Dryer WaferHolder空闲(WaferHolder不存在WaferHolderTask中)
        /// </summary>
        /// <param name="waferHolderTasks"></param>
        /// <param name="module"></param>
        /// <returns></returns>
        private bool CheckDryerWaferHolderIdle(List<WaferHolderTask> waferHolderTasks,WaferHolderTask waferHolderTask)
        {
            List<string> dryerModules = DryerItemManager.Instance.InstalledModules;
            foreach (string item in dryerModules)
            {
                if (WaferHolderManager.Instance.HasWaferHolder(item))
                {
                    DryerEntity dryerEntity = Singleton<RouteManager>.Instance.GetModule<DryerEntity>(item);
                    if (dryerEntity == null)
                    {
                        continue;
                    }
                    if (!dryerEntity.IsIdle)
                    {
                        continue;
                    }
                    WaferHolderInfo waferHolderInfo=WaferHolderManager.Instance.GetWaferHolder(item);
                    if(waferHolderInfo == null)
                    {
                        continue;
                    }
                    if (waferHolderInfo.Id == waferHolderTask.WaferHolderInfo.Id)
                    {
                        continue;
                    }
                    int index = waferHolderTasks.FindIndex(O => O.WaferHolderInfo.Id == waferHolderInfo.Id);
                    if (index == -1)
                    {
                        return true;
                    }
                    else
                    {
                        WaferHolderTask task = waferHolderTasks[index];
                        if (task.State == WaferHolderTaskState.Created)
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }
        /// <summary>
        /// 移除状态为取消的WaferHolderTask
        /// </summary>
        /// <param name="waferHolderTasks"></param>
        private void RemoveCanceledTask(List<WaferHolderTask> waferHolderTasks)
        {
            foreach(WaferHolderTask item in waferHolderTasks)
            {
                WaferHolderTaskManager.Instance.RemoveById(item.ID);
                LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"remove wafer shuttle {item.WaferHolderInfo.Id} task");
                //List<string> mathedWaferIds = WaferTaskManager.Instance.GetWaferHolderMathWaferId(item.WaferHolderInfo.Id);
                //foreach(string waferId in mathedWaferIds)
                //{
                //    WaferTaskManager.Instance.RemoveWaferTask(waferId);
                //    WaferTaskManager.Instance.RemoveWaferIdMatchWaferHolderTaskDic(waferId);
                //}
            }
        }
        /// <summary>
        /// 检验其他任务是否也是Transporter并且正在执行
        /// </summary>
        /// <param name="waferHolderTasks"></param>
        /// <param name="waferHolderTask"></param>
        /// <returns></returns>
        private bool CheckOtherTransporterIsRunning(List<WaferHolderTask> waferHolderTasks,WaferHolderTask waferHolderTask,ModuleName moduleName)
        {
            foreach(WaferHolderTask item in waferHolderTasks)
            {
                if (item.ID == waferHolderTask.ID)
                {
                    continue;
                }
                SchedulerSequence schedulerSequence = item.GetCurrentSchedulerSequence();
                if (schedulerSequence == null)
                {
                    continue;
                }
                if (schedulerSequence.ModuleName == moduleName)
                {
                    if(schedulerSequence.State==RState.Running)
                    {
                        return true;
                    }
                }
            }
            return false;
        }
        /// <summary>
        /// 检验其他任务是否也是Transporter1并且正在执行
        /// </summary>
        /// <param name="waferHolderTasks"></param>
        /// <param name="waferHolderTask"></param>
        /// <returns></returns>
        private bool CheckPrewetIsWaitForPick(List<WaferHolderTask> waferHolderTasks, WaferHolderTask waferHolderTask)
        {
            foreach (WaferHolderTask item in waferHolderTasks)
            {
                if (item.ID == waferHolderTask.ID)
                {
                    continue;
                }
                SchedulerSequence schedulerSequence = item.GetCurrentSchedulerSequence();
                if (schedulerSequence == null)
                {
                    continue;
                }
                if (schedulerSequence.ModuleName == ModuleName.Transporter1)
                {
                    WaferHolderMoveItem waferHolderMoveItem = schedulerSequence.Parameters as WaferHolderMoveItem;
                    if (waferHolderMoveItem != null && waferHolderMoveItem.SourceModule == ModuleName.Prewet1)
                    {
                        PrewetEntity prewetEntity = Singleton<RouteManager>.Instance.GetModule<PrewetEntity>(ModuleName.Prewet1.ToString());
                        if(prewetEntity != null &&(prewetEntity.State==(int)PrewetState.PreparingToPick||
                            prewetEntity.State==(int)PrewetState.WaitForPick))
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }
        /// <summary>
        /// 解析Transporter1调度逻辑
        /// </summary>
        /// <param name="sequence"></param>
        private void AnalyseProcessTransporterSchedulerSequence(SchedulerSequence sequence,WaferHolderTask waferHolderTask,int transporterTransferSeconds)
        {
            SchedulerSequence preSequence = waferHolderTask.GetPreSchedulerSequence();
            if (preSequence == null)
            {
                waferHolderTask.Run();
                return;
            }
            if (preSequence.ModuleType == ModuleType.Metal)
            {
                //Metal处于Error
                if (preSequence.SchedulerModule.IsError)
                {
                    waferHolderTask.Run();
                    return;
                }
            }
            if(CheckExistMetalRemainTime(transporterTransferSeconds))
            {
                return;
            }
            else
            {
                waferHolderTask.Run();
            }
        }
        /// <summary>
        /// 是否存在当前阶段为Metal,剩余时间比Transporter搬运时间更小时
        /// </summary>
        /// <param name="transporterTransferSeconds"></param>
        /// <returns></returns>
        private bool CheckExistMetalRemainTime(int transporterTransferSeconds)
        {
            List<WaferHolderTask> waferHolderTasks = WaferHolderTaskManager.Instance.LoaderWaferHolderTaskList().ToList();
            foreach (var item in waferHolderTasks)
            {
                SchedulerSequence currentSequence = item.GetCurrentSchedulerSequence();
                if (currentSequence == null)
                {
                    continue;
                }
                if(currentSequence.ModuleType==ModuleType.Metal&&ModuleHelper.IsMetal(currentSequence.ModuleName))
                {
                    MetalEntity metalEntity = Singleton<RouteManager>.Instance.GetModule<MetalEntity>(currentSequence.ModuleName.ToString());
                    if (metalEntity == null)
                    {
                        continue;
                    }
                    if (metalEntity.IsIdle && metalEntity.WaferHolderInfo != null)
                    {
                        return true;
                    }
                    if(metalEntity.TimeToReady<=transporterTransferSeconds&&metalEntity.IsBusy)
                    {
                        return true;
                    }
                }
                if (currentSequence.ModuleName == ModuleName.Transporter1)
                {
                    SchedulerSequence preSequence = item.GetPreSchedulerSequence();
                    if (preSequence.ModuleType==ModuleType.Metal&&WaferHolderManager.Instance.HasWaferHolder(preSequence.ModuleName.ToString()))
                    {
                        WaferHolderInfo waferHolderInfo = WaferHolderManager.Instance.GetWaferHolder(preSequence.ModuleName.ToString());
                        if (DateTime.Now.Subtract(waferHolderInfo.LastMetalRecipeCompleteTime).TotalMilliseconds <= 1000)
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }
    }
}