using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Windows.Media;
using AIStudio.Wpf.DiagramDesigner.Models;
using AIStudio.Wpf.DiagramDesigner.ViewModels;
using AIStudio.Wpf.DiagramDesigner.ViewModels.BaseViewModel;
using Newtonsoft.Json;

namespace AIStudio.Wpf.DiagramDesigner
{
    public abstract class SelectableViewModelBase : BindableBase, ISelectable
    {
        protected IDiagramServiceProvider _service
        {
            get
            {
                return DiagramServicesProvider.Instance.Provider;
            }
        }

        public SelectableViewModelBase() : this(null)
        {

        }

        public SelectableViewModelBase(IDiagramViewModel root)
        {
            Init(root, true);
            (FontViewModel as FontViewModel).PropertyChanged += FontViewModel_PropertyChanged;
        }

        public SelectableViewModelBase(IDiagramViewModel root, SelectableItemBase designer)
        {
            Init(root, false);
            LoadDesignerItemViewModel(designer);
            (FontViewModel as FontViewModel).PropertyChanged += FontViewModel_PropertyChanged;
        }

        public SelectableViewModelBase(IDiagramViewModel root, SerializableItem serializableItem, string serializableType)
        {
            Init(root, false);
            SelectableItemBase obj = SerializeHelper.DeserializeObject(serializableItem.SerializableTypeName, serializableItem.SerializableString, serializableType);
            LoadDesignerItemViewModel(obj);
            (FontViewModel as FontViewModel).PropertyChanged += FontViewModel_PropertyChanged;
        }

        public virtual SerializableItem ToSerializableItem(string serializableType)
        {
            var obj = GetSerializableObject();
            if (obj != null)
            {
                return new SerializableItem() { ModelTypeName = this.GetType().FullName, SerializableTypeName = obj.GetType().FullName, SerializableString = SerializeHelper.SerializeObject(obj, serializableType) };
            }
            else
            {
                return null;
            }
        }

        public virtual SelectableItemBase GetSerializableObject()
        {
            return null;
        }

        protected virtual void Init(IDiagramViewModel root, bool initNew)
        {
            Root = root;

            if (Root?.ColorViewModel != null)
            {
                this.ColorViewModel = CopyHelper.Mapper(Root.ColorViewModel);
            }
            else
            {
                this.ColorViewModel = _service.CopyDefaultColorViewModel();
            }

            if (Root?.FontViewModel != null)
            {
                this.FontViewModel = CopyHelper.Mapper<FontViewModel, IFontViewModel>(Root.FontViewModel);
            }
            else
            {
                this.FontViewModel = _service.CopyDefaultFontViewModel();
            }

            if (Root?.ShapeViewModel != null)
            {
                this.ShapeViewModel = CopyHelper.Mapper(Root.ShapeViewModel);
            }
            else
            {
                this.ShapeViewModel = _service.CopyDefaultShapeViewModel();
            }

            LockObjectViewModel = new LockObjectViewModel();

            if (initNew)
            {
                InitNew();
            }
        }

        protected virtual void InitNew()
        {

        }

        protected virtual void LoadDesignerItemViewModel(SelectableItemBase designerbase)
        {
            this.Id = designerbase.Id;
            this.ParentId = designerbase.ParentId;
            this.IsGroup = designerbase.IsGroup;
            this.ZIndex = designerbase.ZIndex;
            this.Text = designerbase.Text;

            ColorViewModel = CopyHelper.Mapper(designerbase.ColorItem);
            FontViewModel = CopyHelper.Mapper<FontViewModel, FontItem>(designerbase.FontItem);
            ShapeViewModel = CopyHelper.Mapper(designerbase.SharpItem);
        }

        public IDiagramViewModel Root
        {
            get; set;
        }

        public SelectableViewModelBase Parent
        {
            get; set;
        }

        public Guid Id
        {
            get; set;
        }

        private Guid _parentId;
        public Guid ParentId
        {
            get
            {
                return _parentId;
            }
            set
            {
                SetProperty(ref _parentId, value);
            }
        }

        public bool IsGroup
        {
            get; set;
        }

        private bool _isSelected;
        [Browsable(false)]
        [CanDo]
        public bool IsSelected
        {
            get
            {
                return _isSelected;
            }
            set
            {
                if (SetProperty(ref _isSelected, value))
                {
                    //如果没有文字，失去焦点自动清除
                    if (_isSelected == false && string.IsNullOrEmpty(Text))
                    {
                        ClearText();
                    }
                }
            }
        }

        private bool _isEditing = false;
        public bool IsEditing
        {
            get
            {
                return _isEditing;
            }
            set
            {
                SetProperty(ref _isEditing, value);
            }
        }

        private bool _visible = true;
        public bool Visible
        {
            get
            {
                return _visible;
            }
            set
            {
                SetProperty(ref _visible, value);
            }
        }

        private int _zIndex;
        [Browsable(true)]
        [CanDo]
        public int ZIndex
        {
            get
            {
                return _zIndex;
            }
            set
            {
                SetProperty(ref _zIndex, value);
            }
        }

        private bool _isReadOnly;
        [Browsable(false)]
        public bool IsReadOnly
        {
            get
            {
                if (Root?.IsReadOnly == true && Root?.IsLoading == false)
                {
                    return true;
                }

                if (Parent?.IsReadOnly == true)
                {
                    return true;
                }

                if (LockObjectViewModel?.LockObject.FirstOrDefault(p => p.LockFlag == LockFlag.All)?.IsChecked == true)
                {
                    return true;
                }
                return _isReadOnly;
            }
            set
            {
                SetProperty(ref _isReadOnly, value);
            }
        }

        private bool _isHitTestVisible = true;
        [Browsable(false)]
        public bool IsHitTestVisible
        {
            get
            {
                if (Parent?.IsHitTestVisible == false)
                {
                    return false;
                }

                return _isHitTestVisible;
            }
            set
            {
                if (SetProperty(ref _isHitTestVisible, value))
                {
                    RaisePropertyChanged("IsReadOnly");
                }
            }
        }

        private IColorViewModel _colorViewModel;
        public IColorViewModel ColorViewModel
        {
            get
            {
                return _colorViewModel;
            }
            set
            {
                SetProperty(ref _colorViewModel, value);
            }
        }

        private IFontViewModel _fontViewModel;
        public IFontViewModel FontViewModel
        {
            get
            {
                return _fontViewModel;
            }
            set
            {
                SetProperty(ref _fontViewModel, value);
            }
        }

        private IShapeViewModel _shapeViewModel;
        public IShapeViewModel ShapeViewModel
        {
            get
            {
                return _shapeViewModel;
            }
            set
            {
                SetProperty(ref _shapeViewModel, value);
            }
        }

        public ILockObjectViewModel LockObjectViewModel
        {
            get; set;
        }

        private string _text;
        [Browsable(true)]
        [CanDo]
        public virtual string Text
        {
            get
            {
                var text = _text;
                if (FontViewModel.FontCase == FontCase.Upper)
                {
                    return text?.ToUpper();
                }
                else if (FontViewModel.FontCase == FontCase.Lower)
                {
                    return text?.ToLower();
                }
                else
                {
                    return text;
                }
            }
            set
            {
                if (SetProperty(ref _text, value))
                {

                }
            }
        }


        protected virtual void ClearText()
        {

        }

        public virtual void ClearSelected()
        {
            _isSelected = false;
        }

        public virtual void AddToSelection(bool selected)
        {

        }

        protected bool Command_Enable(object para)
        {
            return IsReadOnly == false;
        }

        private void FontViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "FontCase")
            {
                RaisePropertyChanged("Text");
            }
        }

        public override string ToString()
        {
            return $"{Id}-{Text}";
        }

        public virtual void Dispose()
        {
        }
    }
}
