namespace Voile.UI;

public class StyleAnimator
{
    public bool IsComplete => _elapsed >= _duration;

    public StyleAnimator(Style from, Style to, float duration)
    {
        _from = from;
        _to = to;

        _duration = duration;
        _elapsed = 0f;
    }

    public static float Ease(float t, Style.TransitionType type)
    {
        return type switch
        {
            Style.TransitionType.Linear => t,
            Style.TransitionType.EaseIn => t * t,
            Style.TransitionType.EaseOut => t * (2 - t),
            Style.TransitionType.EaseInOut => t < 0.5f
                ? 2 * t * t
                : -1 + (4 - 2 * t) * t,
            _ => t
        };
    }

    public Style Update(float deltaTime)
    {
        _elapsed = MathF.Min(_elapsed + deltaTime, _duration);
        float t = _duration == 0 ? 1 : _elapsed / _duration;
        float easedT = Ease(t, _to.Transition);

        return LerpStyle(_from, _to, easedT);
    }

    private static Style LerpStyle(Style from, Style to, float t)
    {
        var result = new Style()
        {
            BackgroundColor = MathUtils.LerpColor(from.BackgroundColor ?? Color.Transparent, to.BackgroundColor ?? Color.Transparent, t),
            TextColor = MathUtils.LerpColor(from.TextColor ?? Color.Black, to.TextColor ?? Color.Black, t),
            Padding = MathUtils.LerpSize(from.Padding ?? Size.Zero, to.Padding ?? Size.Zero, t),
            BorderColor = MathUtils.LerpColor(from.BorderColor ?? Color.Transparent, to.BorderColor ?? Color.Transparent, t),
            BorderSize = MathUtils.LerpSize(from.BorderSize ?? Size.Zero, to.BorderSize ?? Size.Zero, t),
            Transition = to.Transition
        };

        return result;
    }

    private Style _from, _to;
    private float _duration, _elapsed;
}