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

namespace NexusShell.Views;

public partial class LauncherOverlay : UserControl
{
    private const double RiseOffset = 36;
    private const double ClosedScaleY = 0.88;
    private const double ClosedScaleX = 0.96;
    private const int RiseDurationMs = 340;

    public event EventHandler? DismissRequested;

    public LauncherOverlay()
    {
        InitializeComponent();
        Loaded += OnLoaded;
    }

    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        if (DataContext is ViewModels.LauncherViewModel vm)
        {
            vm.RefreshLists();
        }
    }

    private TransformGroup? PanelTransform =>
        LauncherPanel.RenderTransform as TransformGroup;

    private ScaleTransform? PanelScale =>
        PanelTransform?.Children[0] as ScaleTransform;

    private TranslateTransform? PanelTranslate =>
        PanelTransform?.Children[1] as TranslateTransform;

    public void PlayOpenAnimation()
    {
        Opacity = 0;

        if (PanelScale is not null)
        {
            PanelScale.ScaleX = ClosedScaleX;
            PanelScale.ScaleY = ClosedScaleY;
        }

        if (PanelTranslate is not null)
        {
            PanelTranslate.Y = RiseOffset;
        }

        var easeOut = new CubicEase { EasingMode = EasingMode.EaseOut };
        var duration = TimeSpan.FromMilliseconds(RiseDurationMs);

        if (PanelTranslate is not null)
        {
            var rise = new DoubleAnimation(RiseOffset, 0, duration) { EasingFunction = easeOut };
            PanelTranslate.BeginAnimation(TranslateTransform.YProperty, rise);
        }

        if (PanelScale is not null)
        {
            var scaleX = new DoubleAnimation(ClosedScaleX, 1, duration) { EasingFunction = easeOut };
            var scaleY = new DoubleAnimation(ClosedScaleY, 1, duration) { EasingFunction = easeOut };
            PanelScale.BeginAnimation(ScaleTransform.ScaleXProperty, scaleX);
            PanelScale.BeginAnimation(ScaleTransform.ScaleYProperty, scaleY);
        }

        BeginAnimation(OpacityProperty, new DoubleAnimation(0, 1, duration) { EasingFunction = easeOut });
        SearchBox.Focus();
        Dispatcher.BeginInvoke(() => SearchBox.Focus(), System.Windows.Threading.DispatcherPriority.Input);
    }

    public void PlayCloseAnimation(Action? onComplete = null)
    {
        var easeIn = new CubicEase { EasingMode = EasingMode.EaseIn };
        var duration = TimeSpan.FromMilliseconds(RiseDurationMs - 40);

        var fadeOut = new DoubleAnimation(1, 0, duration) { EasingFunction = easeIn };
        fadeOut.Completed += (_, _) => onComplete?.Invoke();

        if (PanelTranslate is not null)
        {
            var sink = new DoubleAnimation(0, RiseOffset, duration) { EasingFunction = easeIn };
            PanelTranslate.BeginAnimation(TranslateTransform.YProperty, sink);
        }

        if (PanelScale is not null)
        {
            var scaleX = new DoubleAnimation(1, ClosedScaleX, duration) { EasingFunction = easeIn };
            var scaleY = new DoubleAnimation(1, ClosedScaleY, duration) { EasingFunction = easeIn };
            PanelScale.BeginAnimation(ScaleTransform.ScaleXProperty, scaleX);
            PanelScale.BeginAnimation(ScaleTransform.ScaleYProperty, scaleY);
        }

        BeginAnimation(OpacityProperty, fadeOut);
    }

    private void Overlay_OnMouseDown(object sender, MouseButtonEventArgs e)
    {
        DismissRequested?.Invoke(this, EventArgs.Empty);
    }

    private void Panel_OnMouseDown(object sender, MouseButtonEventArgs e)
    {
        e.Handled = true;
    }
}
