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

namespace 自救器呼吸器综合检验仪
{
    public partial class LoadingOverlayWindow : Window
    {
        private static readonly TimeSpan MinimumDisplayDuration = TimeSpan.FromMilliseconds(700);
        private static readonly TimeSpan DismissAnimationDuration = TimeSpan.FromMilliseconds(240);

        private readonly DateTime _shownAtUtc;
        private bool _closeRequested;

        public LoadingOverlayWindow()
        {
            InitializeComponent();
            _shownAtUtc = DateTime.UtcNow;
        }

        public void AlignTo(Window referenceWindow)
        {
            if (referenceWindow == null)
            {
                return;
            }

            WindowState = WindowState.Normal;

            double width = referenceWindow.ActualWidth > 0 ? referenceWindow.ActualWidth : referenceWindow.Width;
            double height = referenceWindow.ActualHeight > 0 ? referenceWindow.ActualHeight : referenceWindow.Height;

            if (width <= 0 || height <= 0)
            {
                Rect restoreBounds = referenceWindow.RestoreBounds;
                width = restoreBounds.Width > 0 ? restoreBounds.Width : width;
                height = restoreBounds.Height > 0 ? restoreBounds.Height : height;
            }

            Left = referenceWindow.Left;
            Top = referenceWindow.Top;
            Width = width;
            Height = height;
        }

        public void MatchTopmost(Window referenceWindow)
        {
            if (referenceWindow == null)
            {
                return;
            }

            Topmost = referenceWindow.Topmost;
        }

        public void SetMessage(string title, string subtitle)
        {
            if (!string.IsNullOrWhiteSpace(title))
            {
                TitleText.Text = title;
            }

            if (!string.IsNullOrWhiteSpace(subtitle))
            {
                SubtitleText.Text = subtitle;
            }
        }

        public void CloseWhenReady()
        {
            if (_closeRequested)
            {
                return;
            }

            _closeRequested = true;
            TimeSpan remaining = MinimumDisplayDuration - (DateTime.UtcNow - _shownAtUtc);
            if (remaining <= TimeSpan.Zero)
            {
                CloseOverlay();
                return;
            }

            DispatcherTimer timer = new DispatcherTimer(
                remaining,
                DispatcherPriority.Background,
                OnCloseTimerTick,
                Dispatcher);
            timer.Start();
        }

        private void OnCloseTimerTick(object sender, EventArgs e)
        {
            DispatcherTimer timer = sender as DispatcherTimer;
            if (timer != null)
            {
                timer.Stop();
                timer.Tick -= OnCloseTimerTick;
            }

            CloseOverlay();
        }

        private void CloseOverlay()
        {
            if (Dispatcher.HasShutdownStarted || Dispatcher.HasShutdownFinished || !IsLoaded)
            {
                return;
            }

            DoubleAnimation fadeOutAnimation = new DoubleAnimation
            {
                From = Opacity,
                To = 0,
                Duration = new Duration(DismissAnimationDuration),
                FillBehavior = FillBehavior.Stop
            };

            fadeOutAnimation.Completed += (sender, args) =>
            {
                if (Dispatcher.HasShutdownStarted || Dispatcher.HasShutdownFinished || !IsLoaded)
                {
                    return;
                }

                Close();
            };

            BeginAnimation(OpacityProperty, fadeOutAnimation);
        }
    }
}
