using Microsoft.UI.Text;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media.Animation;
using Microsoft.UI.Xaml.Media;

namespace YMhut.Box.WinUI.Services;

public enum ToastKind
{
    Success,
    Info,
    Warning,
    Error
}

public static class ToastService
{
    private static StackPanel? _host;
    private static XamlRoot? _xamlRoot;

    public static void Attach(StackPanel host)
    {
        _host = host;
        _xamlRoot = host.XamlRoot;
    }

    public static void Show(string message, ToastKind kind = ToastKind.Success, TimeSpan? duration = null)
    {
        if (_host is null)
        {
            return;
        }

        _host.DispatcherQueue.TryEnqueue(async () =>
        {
            var toast = BuildToast(message, kind);
            _host.Children.Add(toast);
            Animate(toast, show: true);

            await Task.Delay(duration ?? TimeSpan.FromSeconds(2));
            Animate(toast, show: false);
            await Task.Delay(180);
            _host.Children.Remove(toast);
        });
    }

    public static XamlRoot? CurrentXamlRoot => _xamlRoot;

    private static Border BuildToast(string message, ToastKind kind)
    {
        var (glyph, color) = kind switch
        {
            ToastKind.Warning => ("\uE7BA", ModernUi.Bronze),
            ToastKind.Error => ("\uEA39", ModernUi.Danger),
            ToastKind.Info => ("\uE946", ModernUi.Info),
            _ => ("\uE73E", ModernUi.Success)
        };

        var transform = new TranslateTransform { X = 24 };
        var panel = new StackPanel
        {
            Orientation = Orientation.Horizontal,
            Spacing = 10,
            VerticalAlignment = VerticalAlignment.Center,
            Children =
            {
                new FontIcon { Glyph = glyph, FontSize = 16, Foreground = color, VerticalAlignment = VerticalAlignment.Center },
                ModernUi.Text(message, 14, FontWeights.SemiBold, ModernUi.TextPrimary, maxLines: 2)
            }
        };

        return new Border
        {
            MinWidth = 220,
            MaxWidth = 380,
            Padding = new Thickness(14, 10, 16, 11),
            CornerRadius = new CornerRadius(8),
            Background = ModernUi.Surface,
            BorderBrush = ModernUi.StrokeStrong,
            BorderThickness = new Thickness(1),
            Opacity = 0,
            RenderTransform = transform,
            Shadow = new ThemeShadow(),
            Child = panel
        };
    }

    private static void Animate(Border toast, bool show)
    {
        var storyboard = new Storyboard();

        var opacity = new DoubleAnimation
        {
            To = show ? 1 : 0,
            Duration = TimeSpan.FromMilliseconds(160),
            EnableDependentAnimation = true
        };
        Storyboard.SetTarget(opacity, toast);
        Storyboard.SetTargetProperty(opacity, "Opacity");
        storyboard.Children.Add(opacity);

        if (toast.RenderTransform is TranslateTransform transform)
        {
            var slide = new DoubleAnimation
            {
                To = show ? 0 : 24,
                Duration = TimeSpan.FromMilliseconds(180),
                EnableDependentAnimation = true,
                EasingFunction = new CubicEase { EasingMode = show ? EasingMode.EaseOut : EasingMode.EaseIn }
            };
            Storyboard.SetTarget(slide, transform);
            Storyboard.SetTargetProperty(slide, "X");
            storyboard.Children.Add(slide);
        }

        storyboard.Begin();
    }
}
