// PoC (Path B). Plays a Lottie animation via SkiaSharp.Skottie on an SKElement.
// Loop = elapsed % duration. Transparent background. Verify visually by running the app.
using System;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using SkiaSharp;
using SkiaSharp.Skottie;
using SkiaSharp.Views.Desktop;   // SKPaintSurfaceEventArgs
using SkiaSharp.Views.WPF;       // SKElement

namespace DansoriEQ.App.Controls;

public class LottieView : ContentControl
{
    private readonly SKElement _sk = new();
    private Animation? _anim;
    private TimeSpan _elapsed;
    private TimeSpan _last;
    private bool _running;

    /// <summary>True once a Lottie JSON has been parsed successfully.</summary>
    public bool HasAnimation => _anim is not null;

    public LottieView()
    {
        Content = _sk;
        _sk.PaintSurface += OnPaint;
        Loaded += (_, __) => Start();
        Unloaded += (_, __) => Stop();
    }

    /// <summary>Load a Lottie animation from a JSON string. Returns false on parse failure.</summary>
    public bool LoadJson(string json)
    {
        try
        {
            var bytes = Encoding.UTF8.GetBytes(json);
            using var stream = new SKMemoryStream(bytes);
            if (Animation.TryCreate(stream, out var a) && a is not null)
            {
                _anim?.Dispose();
                _anim = a;
                _elapsed = TimeSpan.Zero;
                _sk.InvalidateVisual();
                return true;
            }
        }
        catch { /* fall through */ }
        return false;
    }

    public void Start()
    {
        if (_running) return;
        _running = true;
        _last = TimeSpan.Zero;
        CompositionTarget.Rendering += OnRendering;
    }

    public void Stop()
    {
        _running = false;
        CompositionTarget.Rendering -= OnRendering;
    }

    private void OnRendering(object? sender, EventArgs e)
    {
        if (_anim is null) return;
        var now = ((RenderingEventArgs)e).RenderingTime;
        if (_last == TimeSpan.Zero) { _last = now; return; }
        _elapsed += now - _last;
        _last = now;

        var dur = _anim.Duration;
        if (dur > TimeSpan.Zero)
            while (_elapsed >= dur) _elapsed -= dur;

        _sk.InvalidateVisual();
    }

    private void OnPaint(object? sender, SKPaintSurfaceEventArgs e)
    {
        var canvas = e.Surface.Canvas;
        canvas.Clear(SKColors.Transparent);
        if (_anim is null) return;
        _anim.SeekFrameTime(_elapsed.TotalSeconds);
        _anim.Render(canvas, new SKRect(0, 0, e.Info.Width, e.Info.Height));
    }
}
