using Aitex.Core.Common;
using Aitex.Core.RT.Event;
using Aitex.Core.Util;
using MECF.Framework.Common.CommonData;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.SubstrateTrackings;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Venus_RT.HostWrapper;
using Venus_RT.FAs;

namespace Venus_RT.Modules.PMs
{
    public interface IRecipeFACallback
    {
        void RecipeStart(string module,string recipeName);
        void RecipeComplete(string module,string recipeName);
        void RecipeFailed(string module, string recipeName);
        void RecipeStepStart(string module, string recipeName, int stepNumber);
        void RecipeStepEnd(string module, string recipeName, int stepNumber, List<FdcDataItem> fdc);
    }
    public class RecipeFACallback : IRecipeFACallback
    {
        private const string PMARecipeStart = "PMARecipeStart";
        private const string PMARecipeComplete = "PMARecipeComplete";
        private const string PMARecipeStepStart = "PMARecipeStepStart";
        private const string PMARecipeStepEnd = "PMARecipeStepEnd";
        private const string PMARecipeFailed = "PMARecipeFailed";

        private const string PMBRecipeStart = "PMBRecipeStart";
        private const string PMBRecipeComplete = "PMBRecipeComplete";
        private const string PMBRecipeStepStart = "PMBRecipeStepStart";
        private const string PMBRecipeStepEnd = "PMBRecipeStepEnd";
        private const string PMBRecipeFailed = "PMBRecipeFailed";

        private const string PMCRecipeStart = "PMCRecipeStart";
        private const string PMCRecipeComplete = "PMCRecipeComplete";
        private const string PMCRecipeStepStart = "PMCRecipeStepStart";
        private const string PMCRecipeStepEnd = "PMCRecipeStepEnd";
        private const string PMCRecipeFailed = "PMCRecipeFailed";

        private const string PMDRecipeStart = "PMDRecipeStart";
        private const string PMDRecipeComplete = "PMDRecipeComplete";
        private const string PMDRecipeStepStart = "PMDRecipeStepStart";
        private const string PMDRecipeStepEnd = "PMDRecipeStepEnd";
        private const string PMDRecipeFailed = "PMDRecipeFailed";
        private Dictionary<ModuleName, string> PMRecipeStart = new Dictionary<ModuleName, string>()
        {
            {ModuleName.PMA, PMARecipeStart},
            {ModuleName.PMB, PMBRecipeStart},
            {ModuleName.PMC, PMCRecipeStart},
            {ModuleName.PMD, PMDRecipeStart}
        };

        private Dictionary<ModuleName, string> PMRecipeComplete = new Dictionary<ModuleName, string>()
        {
            {ModuleName.PMA, PMARecipeComplete},
            {ModuleName.PMB, PMBRecipeComplete},
            {ModuleName.PMC, PMCRecipeComplete},
            {ModuleName.PMD, PMDRecipeComplete},
        };
        private Dictionary<ModuleName, string> PMRecipeStepStart = new Dictionary<ModuleName, string>()
        {
            {ModuleName.PMA, PMARecipeStepStart},
            {ModuleName.PMB, PMBRecipeStepStart},
            {ModuleName.PMC, PMCRecipeStepStart},
            {ModuleName.PMD, PMDRecipeStepStart},
        };
        private Dictionary<ModuleName, string> PMRecipeStepEnd = new Dictionary<ModuleName, string>()
        {
            {ModuleName.PMA, PMARecipeStepEnd},
            {ModuleName.PMB, PMBRecipeStepEnd},
            {ModuleName.PMC, PMCRecipeStepEnd},
            {ModuleName.PMD, PMDRecipeStepEnd},
        };
        private Dictionary<ModuleName, string> PMRecipeFailed = new Dictionary<ModuleName, string>()
        {
            {ModuleName.PMA, PMARecipeFailed},
            {ModuleName.PMB, PMBRecipeFailed},
            {ModuleName.PMC, PMCRecipeFailed},
            {ModuleName.PMD, PMDRecipeFailed},
        };
        private Dictionary<int, string> PortId = new Dictionary<int, string>()
        {
            {(int)ModuleName.LP1, "1"},
            {(int)ModuleName.LP2, "2"},
        };
        public RecipeFACallback()
        {
            FaEvent.AddFaEvent(new PostFAItem("Event", PMARecipeStart, PMARecipeStart));
            FaEvent.AddFaEvent(new PostFAItem("Event", PMARecipeComplete, PMARecipeComplete));
            FaEvent.AddFaEvent(new PostFAItem("Event", PMARecipeStepStart, PMARecipeStepStart));
            FaEvent.AddFaEvent(new PostFAItem("Event", PMARecipeStepEnd, PMARecipeStepEnd));
            FaEvent.AddFaEvent(new PostFAItem("Event", PMARecipeFailed, PMARecipeFailed));

            FaEvent.AddFaEvent(new PostFAItem("Event", PMBRecipeStart, PMBRecipeStart));
            FaEvent.AddFaEvent(new PostFAItem("Event", PMBRecipeComplete, PMBRecipeComplete));
            FaEvent.AddFaEvent(new PostFAItem("Event", PMBRecipeStepStart, PMBRecipeStepStart));
            FaEvent.AddFaEvent(new PostFAItem("Event", PMBRecipeStepEnd, PMBRecipeStepEnd));
            FaEvent.AddFaEvent(new PostFAItem("Event", PMBRecipeFailed, PMBRecipeFailed));

            FaEvent.AddFaEvent(new PostFAItem("Event", PMCRecipeStart, PMCRecipeStart));
            FaEvent.AddFaEvent(new PostFAItem("Event", PMCRecipeComplete, PMCRecipeComplete));
            FaEvent.AddFaEvent(new PostFAItem("Event", PMCRecipeStepStart, PMCRecipeStepStart));
            FaEvent.AddFaEvent(new PostFAItem("Event", PMCRecipeStepEnd, PMCRecipeStepEnd));
            FaEvent.AddFaEvent(new PostFAItem("Event", PMCRecipeFailed, PMCRecipeFailed));

            FaEvent.AddFaEvent(new PostFAItem("Event", PMDRecipeStart, PMDRecipeStart));
            FaEvent.AddFaEvent(new PostFAItem("Event", PMDRecipeComplete, PMDRecipeComplete));
            FaEvent.AddFaEvent(new PostFAItem("Event", PMDRecipeStepStart, PMDRecipeStepStart));
            FaEvent.AddFaEvent(new PostFAItem("Event", PMDRecipeStepEnd, PMDRecipeStepEnd));
            FaEvent.AddFaEvent(new PostFAItem("Event", PMDRecipeFailed, PMDRecipeFailed));
        }
        public void RecipeComplete(string module, string recipeName)
        {
            WaferInfo wafer = WaferManager.Instance.GetWafer(ModuleHelper.Converter(module), 0);

            if (wafer.IsEmpty)
                return;

            ModuleName moduleName = ModuleHelper.Converter(module);

            if (PortId.ContainsKey(wafer.OriginStation))
            {
                FaEvent.FaNotify(PMRecipeComplete[moduleName], new SerializableDictionary<string, string>()
                {
                    {DVIDName.RecipeID,  recipeName},
                    {DVIDName.StationName,  module},
                    {DVIDName.PortID, PortId[wafer.OriginStation]},
                    {DVIDName.SlotID, (wafer.OriginSlot+1).ToString()},
                    {DVIDName.LotID, wafer.LotId},
                    {DVIDName.CarrierID,wafer.OriginCarrierID.ToString() }
                });
            }
            else
            {
                FaEvent.FaNotify(PMRecipeComplete[moduleName], new SerializableDictionary<string, string>()
                {
                    {DVIDName.RecipeID,  recipeName},
                    {DVIDName.StationName,  module},
                    {DVIDName.SlotID, (wafer.OriginSlot+1).ToString()},
                    {DVIDName.LotID, wafer.LotId},
                    {DVIDName.CarrierID,wafer.OriginCarrierID.ToString() }
                });
            }
        }
        public void RecipeFailed(string module, string recipeName)
        {
            WaferInfo wafer = WaferManager.Instance.GetWafer(ModuleHelper.Converter(module), 0);

            if (wafer.IsEmpty)
                return;

            ModuleName moduleName = ModuleHelper.Converter(module);

            if (PortId.ContainsKey(wafer.OriginStation))
            {
                FaEvent.FaNotify(PMRecipeFailed[moduleName], new SerializableDictionary<string, string>()
                {
                    {DVIDName.RecipeID, recipeName},
                    {DVIDName.StationName, module},
                    {DVIDName.PortID, PortId[wafer.OriginStation]},
                    {DVIDName.SlotID, (wafer.OriginSlot + 1).ToString()},
                    {DVIDName.LotID, wafer.LotId}
                });
            }
            else
            {
                FaEvent.FaNotify(PMRecipeFailed[moduleName], new SerializableDictionary<string, string>()
                {
                    {DVIDName.RecipeID, recipeName},
                    {DVIDName.StationName, module},
                    {DVIDName.SlotID, (wafer.OriginSlot + 1).ToString()},
                    {DVIDName.LotID, wafer.LotId}
                });
            }
        }
        public void RecipeStart(string module, string recipeName)
        {
            WaferInfo wafer = WaferManager.Instance.GetWafer(ModuleHelper.Converter(module), 0);

            if (wafer.IsEmpty)
                return;

            ModuleName moduleName = ModuleHelper.Converter(module);

            if (PortId.ContainsKey(wafer.OriginStation))
            {
                FaEvent.FaNotify(PMRecipeStart[moduleName], new SerializableDictionary<string, string>()
                {
                    {DVIDName.RecipeID, recipeName},
                    {DVIDName.StationName, module},
                    {DVIDName.PortID, PortId[wafer.OriginStation]},
                    {DVIDName.SlotID, (wafer.OriginSlot + 1).ToString()},
                    {DVIDName.LotID, wafer.LotId},
                    //{DVIDName.CarrierID,wafer.OriginCarrierID.ToString() }
                    {DVIDName.CarrierID,"" }
                });
            }
            else
            {
                FaEvent.FaNotify(PMRecipeStart[moduleName], new SerializableDictionary<string, string>()
                {
                    {DVIDName.RecipeID, recipeName},
                    {DVIDName.StationName, module},
                    {DVIDName.SlotID, (wafer.OriginSlot + 1).ToString()},
                    {DVIDName.LotID, wafer.LotId},
                    //{DVIDName.CarrierID,wafer.OriginCarrierID.ToString() }
                });
            }
        }
        public void RecipeStepEnd(string module, string recipeName, int stepNumber, List<FdcDataItem> fdc)
        {
            WaferInfo wafer = WaferManager.Instance.GetWafer(ModuleHelper.Converter(module), 0);

            if (wafer.IsEmpty)
                return;

            ModuleName moduleName = ModuleHelper.Converter(module);

            if (PortId.ContainsKey(wafer.OriginStation))
            {
                FaEvent.FaNotify(PMRecipeStepEnd[moduleName], new SerializableDictionary<string, object>()
                {
                    {DVIDName.RecipeID, recipeName},
                    {DVIDName.StationName, module},
                    {DVIDName.RecipeStepNumber, (stepNumber + 1).ToString()},
                    {DVIDName.PortID, PortId[wafer.OriginStation]},
                    {DVIDName.SlotID, (wafer.OriginSlot + 1).ToString()},
                    {DVIDName.RecipeStepEndDataSummary, fdc},
                    {DVIDName.LotID, wafer.LotId},
                    {DVIDName.CarrierID,wafer.OriginCarrierID.ToString() }
                });
            }
            else
            {
                FaEvent.FaNotify(PMRecipeStepEnd[moduleName], new SerializableDictionary<string, object>()
                {
                    {DVIDName.RecipeID, recipeName},
                    {DVIDName.StationName, module},
                    {DVIDName.RecipeStepNumber, (stepNumber + 1).ToString()},
                    {DVIDName.SlotID, (wafer.OriginSlot + 1).ToString()},
                    {DVIDName.RecipeStepEndDataSummary, fdc},
                    {DVIDName.LotID, wafer.LotId},
                    {DVIDName.CarrierID,wafer.OriginCarrierID.ToString() }

                });
            }
        }
        public void RecipeStepStart(string module, string recipeName, int stepNumber)
        {
            WaferInfo wafer = WaferManager.Instance.GetWafer(ModuleHelper.Converter(module), 0);

            if (wafer.IsEmpty)
                return;

            ModuleName moduleName = ModuleHelper.Converter(module);
            if (PortId.ContainsKey(wafer.OriginStation))
            {
                FaEvent.FaNotify(PMRecipeStepStart[moduleName], new SerializableDictionary<string, string>()
                {
                    {DVIDName.RecipeID, recipeName},
                    {DVIDName.StationName, module},
                    {DVIDName.RecipeStepNumber, (stepNumber + 1).ToString()},
                    {DVIDName.PortID, PortId[wafer.OriginStation]},
                    {DVIDName.SlotID, (wafer.OriginSlot + 1).ToString()},
                    {DVIDName.LotID, wafer.LotId},
                    {DVIDName.CarrierID,wafer.OriginCarrierID.ToString() }
                });
            }
            else
            {
                FaEvent.FaNotify(PMRecipeStepStart[moduleName], new SerializableDictionary<string, string>()
                {
                    {DVIDName.RecipeID, recipeName},
                    {DVIDName.StationName, module},
                    {DVIDName.RecipeStepNumber, (stepNumber + 1).ToString()},
                    {DVIDName.SlotID, (wafer.OriginSlot + 1).ToString()},
                    {DVIDName.LotID, wafer.LotId},
                    {DVIDName.CarrierID,wafer.OriginCarrierID.ToString() }
                });
            }
        }
    }
}