namespace ytLive.Services.Audio;

/// <summary>
/// Auto-duck (TASK 9): while the mic is hot the loopback (game + music) rides
/// its volume down ~12 dB so the voice stays on top of the mix, then recovers
/// when the creator stops talking. Smooth attack/release, always-on, no knobs.
/// Pure — unit-tested.
/// </summary>
public sealed class AutoDucker
{
    public const float Threshold = 0.02f;

    /// <summary>-12 dB: the loopback's volume while the mic is active.</summary>
    public const float DuckGain = 0.25f;

    private const float Attack = 0.05f;
    private const float Release = 0.005f;

    private float _gain = 1f;

    /// <summary>The current loopback gain to apply (1 = no duck).</summary>
    public float CurrentGain => _gain;

    /// <summary>Feeds one mic level sample (0..1, post-filter RMS) and returns
    /// the gain to apply to the loopback for that tick.</summary>
    public float Update(float micLevel)
    {
        var target = micLevel > Threshold ? DuckGain : 1f;
        _gain += (target - _gain) * (target < _gain ? Attack : Release);
        if (MathF.Abs(_gain - target) < 0.001f)
            _gain = target;
        return _gain;
    }

    public void Reset() => _gain = 1f;
}
