using InABox.Wpf;
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace InABox.WPF
{
    /// <summary>
    ///     Interaction logic for ProgressForm.xaml
    /// </summary>
    public partial class ProgressForm : ThemableWindow, INotifyPropertyChanged
    {
        private ImageSource? _image = null;

        private DoubleAnimation _fader = new DoubleAnimation(1d, 0.3d, new Duration(TimeSpan.FromMilliseconds(3000))) { AutoReverse = true };

        public string CancelText { get; init; }
        public bool HasCancelButton { get; init; }

        public delegate void CancelledEvent();

        public event CancelledEvent? OnCancelled;

        public Visibility CancelButtonVisibility => HasCancelButton ? Visibility.Visible : Visibility.Collapsed;

        private string _message;
        public string Message
        {
            get => _message;
            set
            {
                _message = value;
                Progress.Content = _message;
            }
        }

        private ProgressForm(string cancelText, bool hasCancelButton)
        {
            CancelText = cancelText;
            HasCancelButton = hasCancelButton;

            InitializeComponent();
            Topmost = true;
            Loaded += (sender, args) =>
            {
                _fader.Completed += (o, e) => Splash.BeginAnimation(Image.OpacityProperty, _fader);
                Splash.BeginAnimation(Image.OpacityProperty, _fader);
            };
        }

        public ProgressForm(): this("", false) { }

        public ProgressForm(string cancelText): this(cancelText, true) { }
        
        public ImageSource? DisplayImage
        {
            get => Splash.Source;
            set => Splash.Source = value;
        }
        
        public void UpdateWindow(string message)
        {
            if (Progress.Dispatcher.CheckAccess())
                Message = message;
            else
                Progress.Dispatcher.Invoke(() => { Message = message; });
        }

        public void CloseWindow()
        {
            if (Progress.Dispatcher.CheckAccess())
                Close();
            else
                Progress.Dispatcher.Invoke(() => { Close(); });
        }

        public string GetMessage()
        {
            return Message;
        }

        private void Window_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if(e.ChangedButton == System.Windows.Input.MouseButton.Left)
            {
                DragMove();
            }
        }

        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            OnCancelled?.Invoke();
        }

        public event PropertyChangedEventHandler? PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}