using Aitex.Core.Common;
using Aitex.Core.RT.Log;
using Aitex.Core.UI.Control;
using Caliburn.Micro;
using DocumentFormat.OpenXml.VariantTypes;
using MECF.Framework.Common.DataCenter;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.OperationCenter;
using MECF.Framework.Common.SubstrateTrackings;
using MECF.Framework.UI.Client.CenterViews.Editors;
using MECF.Framework.UI.Client.TrayThickness;
using OpenSEMI.Ctrlib.Controls;
using SciChart.Core.Extensions;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using OpenSEMI.ClientBase;
using RTDefine = Aitex.Core.Common;

namespace MECF.Framework.UI.Client.ClientBase
{
    public class MenuElement
    {
        public string Name { get; set; }
        public string Invoke { get; set; }
        public bool IsSeparator { get; set; }
    }

    public class ContextMenuManager
    {
        public bool ShowAligner { get; set; }
        public bool ShowCooling { get; set; }

        public ContextMenuManager()
        {
            _slotMenus = InitMenus(_SlotMenuElements);
            _carrierMenus = InitMenus(_carrierMenuElements);

            ShowAligner = true;
            ShowCooling = true;
        }

        #region single Instance
        private static ContextMenuManager m_Instance = null;
        public static ContextMenuManager Instance
        {
            get
            {
                if (m_Instance == null)
                {
                    m_Instance = new ContextMenuManager();
                }
                return m_Instance;
            }
        }
        #endregion

        public ContextMenu GetSlotMenus(Slot slot)
        {
            if (slot != null)
            {
                if(slot.ModuleID == ModuleName.CassAL.ToString() || slot.ModuleID == ModuleName.CassAR.ToString())
                {
                    return GetWaferMenus(slot);
                }
                else if (slot.ModuleID == ModuleName.CassBL.ToString())
                {
                    return GetTrayMenus(slot);
                }
                else if (slot.ModuleID == ModuleName.PM1.ToString() || slot.ModuleID == ModuleName.PM2.ToString())
                {
                    return GetPMMenus(slot);
                }
                else
                {
                    return GetDeleteMenus(slot);
                }
            }
            return null;
        }
        public void OnContextMenuClick(object sender, RoutedEventArgs args)
        {
            try
            {
                MenuItem m_menu = sender as MenuItem;
                Slot CurrentSlot = ContextMenuService.GetPlacementTarget(LogicalTreeHelper.GetParent(m_menu)) as Slot;
                if (CurrentSlot == null)
                    return;

                MenuElement ele = m_menu.Tag as MenuElement;

                //if (ele.Invoke == "ReturnWafer")
                //{
                //    ReturnWafer(ele.Invoke, CurrentSlot);
                //}
                //else
                //{
                //    InvokeClient.Instance.Service.DoOperation(ele.Invoke, CurrentSlot.ModuleID, CurrentSlot.SlotID);
                //}

                //var param = new object[] { ModuleName.LP1, 5, WaferStatus.Normal };


                if (ele.Invoke == "AlterInfo")
                {
                    SlotEditorDialogBox slotDialog = new SlotEditorDialogBox();
                    slotDialog.Title = "Wafer Editor";

                    slotDialog.RecipeName = CurrentSlot.RecipeName;
                    slotDialog.TrayProcessCount = CurrentSlot.TrayProcessCount;
                    slotDialog.ModuleID = CurrentSlot.ModuleID;
                    slotDialog.SlotID = CurrentSlot.SlotID;
                    slotDialog.TrayBelongTo = CurrentSlot.TrayBelongTo;

                    slotDialog.ShowDialog();
                }
                else if (ele.Invoke == "TrayInfo" || ele.Invoke == "PMInfo")
                {
                    ShowCoatingWin(CurrentSlot, ele.Invoke);

                }
                else
                {
                    InvokeClient.Instance.Service.DoOperation(ele.Invoke, CurrentSlot.ModuleID, CurrentSlot.SlotID);
                }
            }
            catch (Exception ex)
            {
                LOG.Write(ex);
            }
        }

        private static void ShowCoatingWin(Slot CurrentSlot,string module)
        {
            //复杂获取TrayID，不是最优用法
            ModuleName chamber = ModuleHelper.Converter(CurrentSlot.ModuleID);
            Dictionary<string, object> data = QueryDataClient.Instance.Service.PollData(new List<string> { chamber.ToString() + ".ModuleWaferList" });
            WaferInfoRt[] _waferInfo = data[chamber.ToString() + ".ModuleWaferList"] as WaferInfoRt[];
            int slot = _waferInfo[CurrentSlot.SlotID].Slot; //(位置获取Tray的ID)
            string guid = _waferInfo[CurrentSlot.SlotID].TrayInnerID.ToString(); //(位置获取Tray的ID)

            //var wins = Application.Current.Windows.OfType<WinTrayThicknessDataView>().ToArray();
            //if (wins.Any())
            //{
            //    foreach (WinTrayThicknessDataView w in wins)
            //    {
            //        if (w.WindowState == WindowState.Minimized)
            //            w.WindowState = WindowState.Normal;
            //        w.Show();
            //        w.Activate();
            //    }
            //}
            //else
            //{

            var wm = new WindowManager();
            UiViewModelBase model;

            if (module.Contains("PM"))
                model = new WinPMThicknessDataViewModel(chamber.ToString());
            else if (!_waferInfo[CurrentSlot.SlotID].IsTrayEmpty)
                model = new WinTrayThicknessDataViewModel(guid, chamber, slot);
            else
                return;
            

            dynamic settings = new ExpandoObject();
            settings.WindowStartupLocation = WindowStartupLocation.CenterOwner;
            settings.Title = "Edit Tray Info.";
            settings.ResizeMode = ResizeMode.NoResize;
            settings.ShowInTaskbar = false;
            wm.ShowDialog(model, null, settings);
            
            
            //}
            //正确方法获取TrayID
            //ModuleInfo moduleInfo = ModuleManager.ModuleInfos[CurrentSlot.ModuleID];
            //var wi = ModuleManager.ModuleInfos[CurrentSlot.ModuleID].WaferManager.Wafers[CurrentSlot.SlotID];
            //int _trayOriginSlot = wi.TrayOriginSlot;
        }

        private ContextMenu InitMenus(List<MenuElement> menus)
        {
            ContextMenu cm = new ContextMenu();

            foreach (MenuElement element in menus)
            {
                if (element.IsSeparator)
                {
                    cm.Items.Add(new Separator());
                }
                else
                {
                    MenuItem m_item = new MenuItem();
                    m_item.Header = element.Name;
                    m_item.Tag = element;
                    m_item.Click += new RoutedEventHandler(OnContextMenuClick);
                    m_item.IsEnabled = true;
                    cm.Items.Add(m_item);
                }
            }
            return cm;
        }


        #region Wafer Menus

        private ContextMenu _slotMenus;
        public ContextMenu SlotMenus
        {
            get { return _slotMenus; }
        }

        private readonly List<MenuElement> _SlotMenuElements = new List<MenuElement>()
        {
            new MenuElement(){ Name="Create Wafer", Invoke="CreateWafer"},
            new MenuElement(){ Name="Create Tray", Invoke="CreateTray"},
            new MenuElement(){ Name="Delete Wafer", Invoke="DeleteWafer"},
            new MenuElement(){ Name="Delete Tray", Invoke="DeleteTray"},
            new MenuElement(){ Name="-", IsSeparator = true},
            new MenuElement(){ Name="Return Wafer", Invoke="ReturnWafer"},
            new MenuElement(){ Name="Alter Info", Invoke="AlterInfo"},
            new MenuElement(){ Name="Tray Info", Invoke="TrayInfo"},
            new MenuElement(){ Name="PM Info", Invoke="PMInfo"} 
        };
        
        public ContextMenu GetWaferMenus(Slot slot)
        {
            MenuItem createWafer = _slotMenus.Items.GetItemAt(0) as MenuItem;
            MenuItem createTray = _slotMenus.Items.GetItemAt(1) as MenuItem;
            MenuItem deleteWafer = _slotMenus.Items.GetItemAt(2) as MenuItem;
            MenuItem deleteTray = _slotMenus.Items.GetItemAt(3) as MenuItem;
            MenuItem returnWafer = _slotMenus.Items.GetItemAt(5) as MenuItem;
            Separator separator = _slotMenus.Items.GetItemAt(4) as Separator;
            MenuItem pmInfer = _slotMenus.Items.GetItemAt(8) as MenuItem;

            createWafer.IsEnabled = (WaferStatus)slot.WaferStatus == WaferStatus.Empty ;
            deleteWafer.IsEnabled = (WaferStatus)slot.WaferStatus != WaferStatus.Empty ;
            returnWafer.IsEnabled = (WaferStatus)slot.WaferStatus != WaferStatus.Empty && !slot.ModuleID.StartsWith("Cass");

            createWafer.Visibility = Visibility.Visible;
            deleteWafer.Visibility = Visibility.Visible;
            createTray.Visibility = Visibility.Collapsed;
            deleteTray.Visibility = Visibility.Collapsed;
            separator.Visibility = Visibility.Visible;
            returnWafer.Visibility = Visibility.Collapsed;
            pmInfer.Visibility = Visibility.Collapsed;
            return _slotMenus;
        }

        public ContextMenu GetTrayMenus(Slot slot)
        {
            MenuItem createWafer = _slotMenus.Items.GetItemAt(0) as MenuItem;
            MenuItem createTray = _slotMenus.Items.GetItemAt(1) as MenuItem;
            MenuItem deleteWafer = _slotMenus.Items.GetItemAt(2) as MenuItem;
            MenuItem deleteTray = _slotMenus.Items.GetItemAt(3) as MenuItem;
            MenuItem returnWafer = _slotMenus.Items.GetItemAt(5) as MenuItem;
            Separator separator = _slotMenus.Items.GetItemAt(4) as Separator;
            MenuItem pmInfer = _slotMenus.Items.GetItemAt(8) as MenuItem;

            createTray.IsEnabled = true; //slot.TrayStatus == 0;
            deleteTray.IsEnabled = true; //slot.TrayStatus != 0;

            createTray.Visibility = Visibility.Visible;
            deleteTray.Visibility = Visibility.Visible;
            separator.Visibility = Visibility.Collapsed;
            deleteWafer.Visibility = Visibility.Collapsed;
            createWafer.Visibility = Visibility.Collapsed;             
            returnWafer.Visibility = Visibility.Collapsed;
            pmInfer.Visibility = Visibility.Collapsed;
            return _slotMenus;
        }
        
        public ContextMenu GetPMMenus(Slot slot)
        {

            GetDeleteMenus(slot);

            MenuItem pmInfer = _slotMenus.Items.GetItemAt(8) as MenuItem;
            pmInfer.Visibility = Visibility.Visible;
            return _slotMenus;
        }

        public ContextMenu GetAllMenus(Slot slot)
        {
            MenuItem createWafer = _slotMenus.Items.GetItemAt(0) as MenuItem; 
            MenuItem createTray = _slotMenus.Items.GetItemAt(1) as MenuItem;
            MenuItem deleteWafer = _slotMenus.Items.GetItemAt(2) as MenuItem;
            MenuItem deleteTray = _slotMenus.Items.GetItemAt(3) as MenuItem;
            MenuItem returnWafer = _slotMenus.Items.GetItemAt(5) as MenuItem;
            Separator separator = _slotMenus.Items.GetItemAt(4) as Separator;
            

            createWafer.IsEnabled = (WaferStatus)slot.WaferStatus == WaferStatus.Empty ;
            createTray.IsEnabled = true;
            deleteWafer.IsEnabled = (WaferStatus)slot.WaferStatus != WaferStatus.Empty ;
            deleteTray.IsEnabled = true; // slot.TrayStatus != 0; 
            returnWafer.IsEnabled = (WaferStatus)slot.WaferStatus != WaferStatus.Empty && !slot.ModuleID.StartsWith("Cass");

            separator.Visibility = Visibility.Visible;
            createWafer.Visibility = Visibility.Visible;
            deleteWafer.Visibility = Visibility.Visible;
            createTray.Visibility = Visibility.Visible;
            deleteTray.Visibility = Visibility.Visible;
            returnWafer.Visibility = Visibility.Collapsed;
            
            return _slotMenus;
        }

        public ContextMenu GetDeleteMenus(Slot slot)
        {
            MenuItem createWafer = _slotMenus.Items.GetItemAt(0) as MenuItem;
            MenuItem createTray = _slotMenus.Items.GetItemAt(1) as MenuItem;
            MenuItem deleteWafer = _slotMenus.Items.GetItemAt(2) as MenuItem;
            MenuItem deleteTray = _slotMenus.Items.GetItemAt(3) as MenuItem;
            MenuItem returnWafer = _slotMenus.Items.GetItemAt(5) as MenuItem;
            Separator separator = _slotMenus.Items.GetItemAt(4) as Separator;
            MenuItem pmInfer = _slotMenus.Items.GetItemAt(8) as MenuItem;

            createWafer.IsEnabled = (WaferStatus)slot.WaferStatus == WaferStatus.Empty;
            createTray.IsEnabled = true;
            deleteWafer.IsEnabled = (WaferStatus)slot.WaferStatus != WaferStatus.Empty;
            deleteTray.IsEnabled = true; // slot.TrayStatus != 0; 
            returnWafer.IsEnabled = (WaferStatus)slot.WaferStatus != WaferStatus.Empty && !slot.ModuleID.StartsWith("Cass");

            if ((bool)QueryDataClient.Instance.Service.GetConfig($"System.SetUp.IsEFEMInstalled"))
            {
                createTray.Visibility = Visibility.Collapsed;
                createWafer.Visibility = Visibility.Collapsed;
            }
            else
            {
                createTray.Visibility = Visibility.Visible;
                createWafer.Visibility = Visibility.Visible;
            }

            separator.Visibility = Visibility.Visible;
            deleteWafer.Visibility = Visibility.Visible;
            deleteTray.Visibility = Visibility.Visible;
            returnWafer.Visibility = Visibility.Collapsed;
            pmInfer.Visibility = Visibility.Collapsed;
            return _slotMenus;
        }

        public void ReturnWafer(string menu, Slot p_from)
        {
            try
            {
                if (p_from == null || !p_from.IsValidSlot())
                    return;

                //DialogButton btns = DialogButton.Transfer | DialogButton.Cancel;       
                string info = " from " + p_from.ModuleID + " slot " + (p_from.SlotID + 1).ToString();
                string message = "Are you sure to return the wafer: \n" + info;
                //DialogButton m_dResult = DialogBox.ShowDialog(btns, DialogType.CONFIRM, message);

                bool displayAlignerCondition = p_from.ModuleID == "LP1" || p_from.ModuleID == "LP2" || p_from.ModuleID == "LP3" || p_from.ModuleID == "EfemRobot"
                    || p_from.ModuleID == "LLA" || p_from.ModuleID == "LLB" || p_from.ModuleID == "LLC" || p_from.ModuleID == "LLD" || p_from.ModuleID == "Buffer";

                displayAlignerCondition = displayAlignerCondition && (p_from.ModuleID != "Aligner");

                bool displayPassCoolingCondition = (p_from.ModuleID.Contains("PM") || p_from.ModuleID == "TMRobot");

                WindowManager wm = new WindowManager();
                WaferTransferDialogViewModel _transferVM = new WaferTransferDialogViewModel(message, displayAlignerCondition, displayPassCoolingCondition);
                _transferVM.AlignerVisibility = ShowAligner ? Visibility.Visible : Visibility.Hidden;
                _transferVM.CoolingVisibility = ShowCooling ? Visibility.Visible : Visibility.Hidden;
                bool? bret = wm.ShowDialogWithNoStyle(_transferVM);
                if ((bool)bret)
                {
                    //get and use transfer conditions
                    WaferTransferCondition conditions = _transferVM.DialogResult;

                    InvokeClient.Instance.Service.DoOperation(menu, p_from.ModuleID, p_from.SlotID,
                        conditions.IsPassCooling, conditions.CoolingTime);
                }

                p_from.ClearDragDropStatus();
            }
            catch (Exception ex)
            {
                LOG.Write(ex);
            }
        }

        #endregion

        #region Carrier menus

        private ContextMenu _carrierMenus;
        public ContextMenu CarrierMenus
        {
            get { return _carrierMenus; }
        }

        private readonly List<MenuElement> _carrierMenuElements = new List<MenuElement>() {
            new MenuElement(){ Name="Create Carrier", Invoke="System.CreateCarrier"},
            new MenuElement(){ Name="Delete Carrier", Invoke="System.DeleteCarrier"},

        };

        public void OnCarrierContextMenuClick(object sender, RoutedEventArgs args)
        {
            try
            {
                MenuItem menuItem = sender as MenuItem;
                CarrierContentControl locateCarrier = ContextMenuService.GetPlacementTarget(LogicalTreeHelper.GetParent(menuItem)) as CarrierContentControl;
                if (locateCarrier == null)
                    return;

                MenuElement ele = menuItem.Tag as MenuElement;
 
                InvokeClient.Instance.Service.DoOperation(ele.Invoke, locateCarrier.ModuleID, locateCarrier.CarrierID);
            }
            catch (Exception ex)
            {
                LOG.Write(ex);
            }
        }


        public ContextMenu GetCarrierMenus(CarrierContentControl carrier)
        {
            if (carrier != null)
            {
                MenuItem createCarrier = _carrierMenus.Items.GetItemAt(0) as MenuItem;
                MenuItem deleteWafer = _carrierMenus.Items.GetItemAt(1) as MenuItem;

                createCarrier.IsEnabled = (WaferStatus)carrier.WaferStatus == WaferStatus.Empty ? true : false;
                deleteWafer.IsEnabled = (WaferStatus)carrier.WaferStatus == WaferStatus.Empty ? false : true;
            }
            return _carrierMenus;
        }

        #endregion

    }
}
