using System;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Animation;

namespace WandEnhancer.View.Controls
{
    public partial class PopupHost : Grid
    {
        internal Action Closed;

        public static readonly DependencyProperty PopupContentProperty =
            DependencyProperty.Register("PopupContent", typeof(object), typeof(PopupHost), new PropertyMetadata(null));
        
        internal readonly SemaphoreSlim OpenedSemaphore = new SemaphoreSlim(1, 1);
        
        private DoubleAnimation OpeningAnimation;
        private DoubleAnimation ClosingAnimation;
        
        
        public bool IsOpen
        {
            get => this.Visibility == Visibility.Visible;
            set
            {
                if (value)
                {
                    if(OpenedSemaphore.CurrentCount == 0)
                        return;
                    

                    Visibility            = Visibility.Visible;
                    cancel.Focus();
                    PopupPresenter.BeginAnimation(OpacityProperty, OpeningAnimation);
                    OpenedSemaphore.Wait();
                }
                else
                {
                    PopupPresenter.BeginAnimation(OpacityProperty, ClosingAnimation);
                }

            }
        }
        
        public object PopupContent
        {
            get => GetValue(PopupContentProperty);
            set => SetValue(PopupContentProperty, value);
        }
        
        private void HidePopup(object sender, EventArgs e)
        {
            if (OpenedSemaphore.CurrentCount == 1)
                return;

            IsOpen = false;
        }
        
        private void OnClosing(object sender, EventArgs e)
        {
            if (PopupContent == null)
                return;

            Visibility   = Visibility.Collapsed;
            Closed?.Invoke();
            if (PopupContent is IDisposable disposable)
            {
                disposable.Dispose();
            }
            PopupContent = null;
            Closed       = null;
            OpenedSemaphore.Release();
        }
        
        public PopupHost()
        {
            InitializeComponent();

            PreviewKeyDown += (sender, e) =>
            {
                if (e.Key != Key.Escape) 
                    return;
                
                HidePopup(null, null);
                e.Handled = true;
            };
            
            OpeningAnimation = new DoubleAnimation(0, 1, new Duration(TimeSpan.FromSeconds(0.4)))
            {
                EasingFunction = App.Current.FindResource("BaseAnimationFunction") as IEasingFunction
            };
            OpeningAnimation.Freeze();

            ClosingAnimation = new DoubleAnimation(1, 0, new Duration(TimeSpan.FromSeconds(0.2)));
            ClosingAnimation.Completed += OnClosing;
            ClosingAnimation.Freeze();

            this.Splash.DataContext         = this;
            this.PopupPresenter.DataContext = this;
        }
    }
}