using Aitex.Core.RT.Log;
using Aitex.Core.UI.Dialog;
using Aitex.Core.UI.MVVM;
using Aitex.Core.Utilities;
using Caliburn.Micro.Core;
using MECF.Framework.Common.DataCenter;
using MECF.Framework.Common.RecipeCenter;
using CyberX8_Core;
using CyberX8_MainPages.PMs;
using CyberX8_Themes.UserControls;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Input;

namespace CyberX8_MainPages.ViewModels
{
    public class ResRecipeViewModel: BindableBase
    {
        private const string ENGINEERING = "Engineering";

        #region 内部变量
        private Dictionary<string, RecipeNode> _recipeNodeDic = new Dictionary<string, RecipeNode>();
        private ObservableCollection<RecipeNode> _recipeNodes;
        private UiRecipeManager _uiRecipeManager = new UiRecipeManager();
        private Dictionary<string, bool> _propertyValidResultDic = new Dictionary<string, bool>();
        private ResRecipe _recipe;
        private bool _editEnable;
        private bool _createEnable;
        private RecipeNode _currentNode;
        private bool _enable = false;
        private bool _isEdit = false;
        /// <summary>
        /// 化学液集合
        /// </summary>
        private List<string> _chemistryLst = new List<string>();
        #endregion

        #region 属性
        /// <summary>
        /// Recipe Nodes
        /// </summary>
        public ObservableCollection<RecipeNode> RecipeNodes
        {
            get { return _recipeNodes; }
            set { SetProperty(ref _recipeNodes, value); }
        }
        /// <summary>
        /// PropertyValidResultDic
        /// </summary>
        public Dictionary<string, bool> PropertyValidResultDic
        {
            get { return _propertyValidResultDic; }
            set { SetProperty(ref _propertyValidResultDic, value); }
        }
        /// <summary>
        /// 当前Recipe节点
        /// </summary>
        public RecipeNode CurrentNode
        {
            get { return _currentNode; }
            set { SetProperty(ref _currentNode, value); }
        }
        public bool Enable
        {
            get { return _enable; }
            set { SetProperty(ref _enable, value); }
        }
        public bool EditEnable
        {
            get { return _editEnable; }
            set { SetProperty(ref _editEnable, value); }
        }
        public bool CreateEnable
        {
            get { return _createEnable; }
            set { SetProperty(ref _createEnable, value); }
        }

        public ResRecipe Recipe
        {
            get { return _recipe; }
            set { SetProperty(ref _recipe, value); }
        }

        /// <summary>
        /// 化学液集合
        /// </summary>
        public List<string> ChemistryLst
        {
            get { return _chemistryLst; }
            set { SetProperty(ref _chemistryLst, value); }
        }
        #endregion
        #region 指令

        public ICommand OperationCommand
        {
            get;
            private set;
        }
        #endregion
        [IgnorePropertyChange]
        public ICommand CreateCommand { get; private set; }

        [IgnorePropertyChange]
        public ICommand EditCommand { get; private set; }
        [IgnorePropertyChange]
        public ICommand SaveRecipeCommand { get; private set; }
        [IgnorePropertyChange]
        public ICommand DIReplenEnableTrueCommand { get; private set; }
        [IgnorePropertyChange]
        public ICommand DIReplenEnableFalseCommand { get; private set; }
        [IgnorePropertyChange]
        public ICommand ANDIReplenEnableTrueCommand { get; private set; }
        [IgnorePropertyChange]
        public ICommand ANDIReplenEnableFalseCommand { get; private set; }
        public ICommand IdleFlowEnableTrueCommand { get; private set; }
        [IgnorePropertyChange]
        public ICommand IdleFlowEnableFalseCommand { get; private set; }
        [IgnorePropertyChange]
        public ICommand TimeBasedTrueCommand { get; private set; }
        [IgnorePropertyChange]
        public ICommand TimeBasedFalseCommand { get; private set; }
        [IgnorePropertyChange]
        public ICommand CurrentBasedTrueCommand { get; private set; }
        [IgnorePropertyChange]
        public ICommand CurrentBasedFalseCommand { get; private set; }

        public ResRecipeViewModel()
        {
            OperationCommand = new DelegateCommand<object>(SelectionChangedAction);
            CreateCommand = new DelegateCommand<object>(CreateAction);
            EditCommand = new DelegateCommand<object>(EditAction);
            SaveRecipeCommand = new DelegateCommand<object>(SaveAction);
            DIReplenEnableTrueCommand = new DelegateCommand<object>(EnableTrueAction);
            DIReplenEnableFalseCommand = new DelegateCommand<object>(EnableFalseAction);
            ANDIReplenEnableTrueCommand = new DelegateCommand<object>(ANEnableTrueAction);
            ANDIReplenEnableFalseCommand = new DelegateCommand<object>(ANEnableFalseAction);
            IdleFlowEnableTrueCommand = new DelegateCommand<object>(IdleFlowEnableTrueAction);
            IdleFlowEnableFalseCommand = new DelegateCommand<object>(IdleFlowEnableFalseAction);
            TimeBasedTrueCommand = new DelegateCommand<object>(TimeBasedTrueAction);
            TimeBasedFalseCommand = new DelegateCommand<object>(TimeBasedFalseAction);
            CurrentBasedTrueCommand = new DelegateCommand<object>(CurrentBasedTrueAction);
            CurrentBasedFalseCommand = new DelegateCommand<object>(CurrentBasedFalseAction);

            InitializeProprtyValidResultDictionary();

            string chemistryContent = QueryDataClient.Instance.Service.GetConfig($"System.ChemistryList").ToString();
            if (!string.IsNullOrEmpty(chemistryContent))
            {
                ChemistryLst = chemistryContent.Split(',').ToList();
            }
        }
        private void InitializeProprtyValidResultDictionary()
        {
            PropertyValidResultDic["DIReplenTimeRate"] = false;
            PropertyValidResultDic["DIReplenCurrentRate"] = false;
            PropertyValidResultDic["PHErrorLow"] = false;
            PropertyValidResultDic["PHErrorHigh"] = false;
            PropertyValidResultDic["CALevelErrorHigh"] = false;
            PropertyValidResultDic["CALevelErrorLow"] = false;
            PropertyValidResultDic["ReservoirCALevel"] = false;
            PropertyValidResultDic["CAFlowSetPoint"] = false;
            PropertyValidResultDic["CAFlowRateWarningLow"] = false;
            PropertyValidResultDic["CAFlowRateErrorLow"] = false;
            PropertyValidResultDic["TemperatureErrorHigh"] = false;
            PropertyValidResultDic["TemperatureErrorLow"] = false;
            PropertyValidResultDic["TemperatureSetPoint"] = false;
            PropertyValidResultDic["TemperatureWarningHigh"] = false;
            PropertyValidResultDic["TemperatureWarningLow"] = false;
            PropertyValidResultDic["ANDIReplenCurrentRate"] = false;
            PropertyValidResultDic["ANDIReplenTimeRate"] = false;
            PropertyValidResultDic["ANFlowRateErrorLow"] = false;
            PropertyValidResultDic["ANFlowRateWarningLow"] = false;
            PropertyValidResultDic["ANFlowSetPoint"] = false;
            PropertyValidResultDic["ANLevelErrorHigh"] = false;
            PropertyValidResultDic["ANLevelErrorLow"] = false;
            PropertyValidResultDic["ANLevelWarningLow"] = false;

            PropertyValidResultDic["ReservoirANLevel"] = false;
            PropertyValidResultDic["BurnInTime"] = false;
            PropertyValidResultDic["BurnInCurrent"] = false;
            PropertyValidResultDic["BurnInCycles"] = false;
            PropertyValidResultDic["BurnInMinCurrentLimit"] = false;
            PropertyValidResultDic["CMMCurrentSetPoint"] = false;
            PropertyValidResultDic["CMMCurrentFaultPercent"] = false;
            PropertyValidResultDic["CMMCurrentWarningPercent"] = false;
            PropertyValidResultDic["CMMMinVoltage"] = false;



        }
        public void LoadRecipeData()
        {
            RecipeNodes = _uiRecipeManager.GetRecipesByType("res");
            _recipeNodeDic.Clear();
            InitializeDictionary(RecipeNodes);
        }
        private void InitializeDictionary(ObservableCollection<RecipeNode> nodes)
        {
            if (nodes != null)
            {
                foreach (var node in nodes)
                {
                    if (node.NodeType == RecipeNodeType.File)
                    {
                        _recipeNodeDic[node.Name] = node;
                    }
                    InitializeDictionary(node.Children);
                }
            }
        }
        private void SelectionChangedAction(object param)
        {
            if (_recipeNodeDic.ContainsKey(param.ToString()))
            {
                CurrentNode = _recipeNodeDic[param.ToString()];
                if (CurrentNode.NodeType == RecipeNodeType.File)
                {
                    if (CurrentNode.RecipeLocation == ENGINEERING)
                    {
                        EditEnable = true;
                        CreateEnable = true;
                    }
                    else
                    {
                        EditEnable = false;
                        CreateEnable = false;
                    }
                }
                Recipe = _uiRecipeManager.LoadRecipe<ResRecipe>(CurrentNode.RecipeFullFileName);
                if (Recipe == null)
                {
                    MessageBox.Show("Invalid Recipe", "Load Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
                    EditEnable = false;
                    CreateEnable = false;
                }
                Enable = false;
            }
            else
            {
                if (param.ToString() == ENGINEERING)
                {
                    CreateEnable = true;
                }
                else
                {
                    CreateEnable = false;
                }
                CurrentNode = null;
                Recipe = null;
                EditEnable = false;
                Enable = false;
            }
        }
        private void CreateAction(object param)
        {
            RecipeNameDialog recipeNameDialog = new RecipeNameDialog();
            if (recipeNameDialog.ShowDialog().Value)
            {
                if (!CheckNameExist(recipeNameDialog.RecipeName))
                {
                    Recipe = new ResRecipe();
                    Recipe.CreateDate = DateTime.Now;
                    Recipe.Ppid = recipeNameDialog.RecipeName;
                    Recipe.Description = recipeNameDialog.RecipeDescription;
                    Enable = true;
                    _isEdit = false;
                }
            }
        }
        private void EditAction(object param)
        {
            Enable = true;
            _isEdit = false;
        }
        private void SaveAction(object param)
        {
            if (CheckValid(_isEdit))
            {
                Recipe.SaveDate = DateTime.Now;
                try
                {
                    _uiRecipeManager.SaveRecipe<ResRecipe>(ENGINEERING, Recipe.Ppid,"res", Recipe);
                    LoadRecipeData();
                    MessageBox.Show("Save Recipe Success", "Save Recipe", MessageBoxButton.OK, MessageBoxImage.Information);
                    Enable = false;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Save Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }

        private void EnableTrueAction(object param)
        {
            Recipe.DIReplenEnable = true;
        }

        private void EnableFalseAction(object param)
        {
            Recipe.DIReplenEnable = false;
        }
        private void ANEnableTrueAction(object param)
        {
            Recipe.ANDIReplenEnable = true;
        }

        private void ANEnableFalseAction(object param)
        {
            Recipe.ANDIReplenEnable = false;
        }
        private void IdleFlowEnableTrueAction(object param)
        {
            Recipe.IdleFlowEnable = true;
        }
        private void IdleFlowEnableFalseAction(object param)
        {
            Recipe.IdleFlowEnable = false;
        }
        private bool CheckValid(bool editType)
        {
            foreach (string key in _propertyValidResultDic.Keys)
            {
                //在DIReplenEnable时跳过检验项
                if(Recipe.ANDIReplenEnable == false)
                {
                    bool result = false;
                    switch (key)
                    { 
                        case "ANLevelErrorHigh":
                            result = true; break;
                        case "ANLevelErrorLow":
                            result = true; break;
                        case "ANLevelWarningLow":
                            result = true; break;
                        case "ReservoirANLevel":
                            result = true; break;
                        case "ANDIReplenTimeRate":
                            result = true; break;
                        case "ANDIReplenCurrentRate":
                            result = true; break;
                    }
                    if (result)
                    {
                        continue;
                    }  
                }
                //在ReplenEnable时跳过检验项
                if (Recipe.DIReplenEnable == false)
                {
                    bool result = false;
                    switch (key)
                    {
                        case "CALevelErrorHigh":
                            result = true; break;
                        case "CALevelErrorLow":
                            result = true; break;
                        case "ReservoirCALevel":
                            result = true; break;
                        case "DIReplenTimeRate":
                            result = true; break;
                        case "DIReplenCurrentRate":
                            result = true; break;
                    }
                    if (result)
                    {
                        continue;
                    }
                }

                bool valid = _propertyValidResultDic[key];
                if (!valid)
                {
                    MessageBox.Show($"{key} data invalid", "Save Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
                    return false;
                }
            }
            return true;
        }
        private bool CheckNameExist(string name)
        {
            foreach (string item in _recipeNodeDic.Keys)
            {
                if (item == name)
                {
                    MessageBox.Show($"{name} is exsit", "Save Recipe", MessageBoxButton.OK, MessageBoxImage.Error);
                    return true;
                }
            }
            return false;
        }
        private void CurrentBasedTrueAction(object param)
        {
            //基于时间和基于电流只能二选一
            Recipe.CurrentBased = true;
            if (Recipe.TimeBased)
            {
                Recipe.TimeBased = false;
            }
        }
        private void CurrentBasedFalseAction(object param)
        {
            Recipe.CurrentBased = false;
        }
        private void TimeBasedTrueAction(object param)
        {
            Recipe.TimeBased = true;
            //基于时间和基于电流只能二选一
            if (Recipe.CurrentBased)
            {
                Recipe.CurrentBased = false;
            }
        }
        private void TimeBasedFalseAction(object param)
        {
            Recipe.TimeBased = false;
        }
    }
}