using System.Collections.Generic;
using System.Threading.Tasks;

namespace MuzikaGromche.Via;

interface ILightshow
{
    /// <summary>
    /// Override or reset brightness (value) for flickering animation.
    /// </summary>
    void SetBrightnessOverride(byte? brightness);
    void SetColor(byte hue, byte saturation, byte value);
}

class Animations
{
    public static void Flicker(ILightshow lightshow)
    {
        _ = Task.Run(() => FlickerAsync(lightshow));
    }

    static async ValueTask FlickerAsync(ILightshow lightshow)
    {
        await foreach (var on in FlickerAnimationAsync())
        {
            byte brightness = on ? (byte)0xFF : (byte)0x00;
            lightshow.SetBrightnessOverride(brightness);
        }
        lightshow.SetBrightnessOverride(null);
    }

    // Timestamps (in frames of 60 fps) of state switches, starting with 0 => OFF.
    private static readonly int[] MansionWallLampFlicker = [
        0, 4, 8, 26, 28, 32, 37, 41, 42, 58, 60, 71,
    ];

    public static async IAsyncEnumerable<bool> FlickerAnimationAsync()
    {
        bool lastState = true;
        int lastFrame = 0;

        const int initialMillisecondsDelay = 100;
        await Task.Delay(initialMillisecondsDelay);

        foreach (int frame in MansionWallLampFlicker)
        {
            // convert difference in frames into milliseconds
            int millisecondsDelay = (int)((frame - lastFrame) / 60f * 1000f);
            lastState = !lastState;
            lastFrame = frame;

            await Task.Delay(millisecondsDelay);
            yield return lastState;
        }
    }
}
