using MainShell.Recipe.Models.SubstrateParameter;
using MaxwellFramework.Core.Common.Command;
using Stylet;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;

namespace MainShell.Recipe.ViewModel
{
    public class MarkCoordinatePreviewWindowModel : PropertyChangedBase
    {
        private readonly MarkTeachViewModel _markTeachViewModel;
        private ObservableCollection<MarkCoordinatePoint> _observedPoints;

        public ObservableCollection<MarkCoordinatePoint> Points => _markTeachViewModel?.CoordinatePreviewPoints;

        public int PointCount => Points?.Count ?? 0;

        public ICommand CloseCommand { get; }

        public MarkCoordinatePreviewWindowModel(MarkTeachViewModel markTeachViewModel)
        {
            _markTeachViewModel = markTeachViewModel;
            CloseCommand = new DelegateCommand(OnClose);
            AttachToMarkTeachViewModel();
        }

        private void OnClose(object obj)
        {
            if (obj is Window window)
            {
                window.Close();
            }
        }

        public void RefreshViewState()
        {
            NotifyOfPropertyChange(() => Points);
            NotifyOfPropertyChange(() => PointCount);
        }

        public void Cleanup()
        {
            if (_markTeachViewModel != null)
            {
                _markTeachViewModel.PropertyChanged -= OnMarkTeachViewModelPropertyChanged;
            }

            DetachPointCollection();
        }

        private void AttachToMarkTeachViewModel()
        {
            if (_markTeachViewModel == null)
            {
                return;
            }

            _markTeachViewModel.PropertyChanged += OnMarkTeachViewModelPropertyChanged;
            AttachPointCollection(_markTeachViewModel.CoordinatePreviewPoints);
        }

        private void OnMarkTeachViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (string.IsNullOrWhiteSpace(e.PropertyName)
                || e.PropertyName == nameof(MarkTeachViewModel.CoordinatePreviewPoints))
            {
                DetachPointCollection();
                AttachPointCollection(_markTeachViewModel.CoordinatePreviewPoints);
                RefreshViewState();
            }
        }

        private void AttachPointCollection(ObservableCollection<MarkCoordinatePoint> points)
        {
            _observedPoints = points;
            if (_observedPoints != null)
            {
                _observedPoints.CollectionChanged += OnPointsCollectionChanged;
            }
        }

        private void DetachPointCollection()
        {
            if (_observedPoints != null)
            {
                _observedPoints.CollectionChanged -= OnPointsCollectionChanged;
                _observedPoints = null;
            }
        }

        private void OnPointsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            NotifyOfPropertyChange(() => PointCount);
        }
    }
}
