using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
using ExtendedGrid.Microsoft.Windows.Controls;
using MECF.Framework.Common.Account.Permissions;
using Sicentury.Core;

namespace MECF.Framework.UI.Client.RecipeEditorLib.RecipeModel.Params
{
    public abstract class Param : BindableBase, IParam
    {
        #region Variables

        protected string _controlName;
        protected string _displayName;
        protected string _unitName;
        protected MenuPermissionEnum _permStep;
        protected MenuPermissionEnum _permColumn;
        protected bool _isEnabled;
        protected bool _isHideValue;
        protected string _hiddenValueMasking;
        protected bool _isSaved;
        protected bool _isColumnSelected;
        protected Visibility _visibility;
        protected bool _isValid;
        protected string _validationError;
        protected bool _isEqualsToPrevious;
        protected bool _isHighlighted;
        protected bool _isCalculatorError;
        protected bool _isCompareDifferent;
        protected SolidColorBrush _stepColorBrush;

        #endregion

        #region Constructors

        protected Param()
        {
            _isSaved = true;
            IsEnabled = true;
            _isValid = true;
            _validationError = null;
            _isEqualsToPrevious = true;
            _visibility = Visibility.Visible;
            _isHighlighted = false;
            _hiddenValueMasking = "-";
            StepDoneCallback = (value) =>
            {
                IsEnabled = !value;
            };
        }
        
        #endregion

        #region Properties

        /// <summary>
        /// 设置或返回当前参数所在的列的访问权限变更时，执行的回调函数。
        /// </summary>
        public Action<Param> ColumnPermChangedCallback { get; set; }

        /// <summary>
        /// 当step的执行状态变更时，执行的回调函数。
        /// </summary>
        public Action<bool> StepDoneCallback { get; set; }

        public Func<Param, bool> Check { get; set; }

        /// <inheritdoc />
        public RecipeStep Parent { get; set; }

        /// <inheritdoc />
        public DataGridRow RowOwner { get; set; }

        /// <inheritdoc />
        public DataGridColumn ColumnOwner { get; set; }

        /// <inheritdoc />
        public virtual IParam Previous { get; set; }

        /// <inheritdoc />
        public virtual IParam Next { get; set; }

        /// <inheritdoc />
        public string ControlName
        {
            get => _controlName;
            set => Set(ref _controlName, value);
        }

        /// <inheritdoc />
        public string DisplayName
        {
            get => _displayName;
            set => Set(ref _displayName, value);
        }

        /// <summary>
        /// 设置或返回当前参数的单位。
        /// </summary>
        public string UnitName
        {
            get => _unitName;
            set => Set(ref _unitName, value);
        }

        /// <inheritdoc />
        public MenuPermissionEnum StepPermission
        {
            get => _permStep;
            set => Set(ref _permStep, value);
        }

        /// <inheritdoc />
        public MenuPermissionEnum ColumnPermission
        {
            get => _permColumn;
            set => Set(ref _permColumn, value);
        }
        
        /// <inheritdoc />
        public virtual MenuPermissionEnum Permission => (MenuPermissionEnum)Math.Min((int)StepPermission, (int)ColumnPermission);

        /// <inheritdoc />
        public bool IsHideValue
        {
            get => _isHideValue;
            set => Set(ref _isHideValue, value);
        }
        
        /// <inheritdoc />
        public string HiddenValueMasking
        {
            get => _hiddenValueMasking;
            set => Set(ref _hiddenValueMasking, value);
        }


        /// <inheritdoc />
        public bool IsEnabled
        {
            get => _isEnabled;
            set => Set(ref _isEnabled, value);
        }
        
        /// <inheritdoc />
        public virtual bool IsSaved
        {
            get => _isSaved;
            set => Set(ref _isSaved, value);
        }


        /// <inheritdoc />
        public bool IsEqualsToPrevious
        {
            get => _isEqualsToPrevious;
            set => Set(ref _isEqualsToPrevious, value);
        }

        /// <inheritdoc />
        public bool IsValid
        {
            get => _isValid;
            internal set => Set(ref _isValid, value);
        }

        /// <inheritdoc />
        public string ValidationError
        {
            get => _validationError;
            protected set => Set(ref _validationError, value);
        }

        /// <inheritdoc />
        public bool IsHighlighted
        {
            get => _isHighlighted;
            private set => Set(ref _isHighlighted, value);
        }

        /// <inheritdoc />
        public bool IsCalculatorError
        {
            get => _isCalculatorError;
            private set => Set(ref _isCalculatorError, value);
        }

        /// <summary>
        /// Recipe对比的不同参数部分属性标志,未添加到IParam接口中
        /// </summary>
        public bool IsCompareDifferent
        {
            get => _isCompareDifferent;
            private set
            {
                _isCompareDifferent = value;
                StepBackgroundColorBrush =
                    value ? new SolidColorBrush(Colors.LightSalmon) : new SolidColorBrush(Colors.Transparent);

                Set(ref _isCompareDifferent, value);
            }
        }

        public bool IsColumnSelected
        {
            get => _isColumnSelected;
            set => Set(ref _isColumnSelected, value);
        }

        public Visibility Visible
        {
            get => _visibility;
            set => Set(ref _visibility, value);
        }

        public bool EnableConfig { get; set; }

        public bool EnableTolerance { get; set; }

        public Visibility StepCheckVisibility { get; set; }

        /// <summary>
        /// 差异对比时单个参数栏的背景
        /// </summary>
        public SolidColorBrush StepBackgroundColorBrush
        {
            get => _stepColorBrush;
            set => Set(ref _stepColorBrush, value);
        }
        #region Methods

        /// <summary>
        /// 高亮显示当前参数。
        /// </summary>
        public void Highlight()
        {
            IsHighlighted = true;
        }

        public void SetCalculatorError()
        {
            StepBackgroundColorBrush = new SolidColorBrush(Colors.Red);
            IsCalculatorError = true;
        }

        public void ResetCalculatorError()
        {
            StepBackgroundColorBrush = new SolidColorBrush(Colors.Transparent);
            IsCalculatorError = false;
        }

        /// <summary>
        /// 高亮背景色显示，Recipe对比的不同参数部分。未添加到IParam接口中，IsCompareDifferent属性是参数对比标志位
        /// </summary>
        public void CompareDifferent()
        {
            IsCompareDifferent = true;
        }

        /// <summary>
        /// 取消高亮显示。
        /// </summary>
        public void ResetHighlight()
        {
            IsHighlighted = false;
        }
        
        /// <summary>
        /// 将当前参数所对应的前序、后续参数链表转换为数组。
        /// </summary>
        /// <returns></returns>
        public virtual List<IParam> Flatten()
        {
            if (Previous != null)
                return Previous.Flatten();

            var list = new List<IParam>();
            IParam p = this;
            while (p != null)
            {
                list.Add(p);
                p = p.Next;
            }

            return list;
        }

        /// <summary>
        /// 校验当前参数的数值。
        /// </summary>
        /// <returns></returns>
        public virtual void Validate()
        {
            IsValid = true;
            ValidationError = "";
        }

        /// <summary>
        /// 复位当前参数数值
        /// </summary>
        public virtual void Reset()
        {
            IsSaved = true;
        }

        /// <summary>
        /// 将当前参数标记为已保存状态。
        /// </summary>
        public virtual void Save()
        {
            IsSaved = true;
        }

        public override string ToString()
        {
            return $"{DisplayName}, ControlName={ControlName}";
        }
        
        #endregion

        #endregion
    }
}
