using DansoriEQ.Core.Eq;
using Xunit;

namespace DansoriEQ.Core.Tests;

public class FilterMathTests
{
    private const double Fs = 48000;

    [Fact]
    public void Peaking_AtCenter_EqualsGain()
    {
        var f = new Filter { Type = FilterType.Peaking, Fc = 1000, GainDb = 6, Q = 1 };
        Assert.InRange(f.GainDbAt(1000, Fs), 5.8, 6.2);
    }

    [Fact]
    public void Peaking_FarFromCenter_IsFlat()
    {
        var f = new Filter { Type = FilterType.Peaking, Fc = 1000, GainDb = 6, Q = 2 };
        Assert.InRange(f.GainDbAt(60, Fs), -0.5, 0.5);
    }

    [Fact]
    public void LowShelf_BelowCorner_ApproachesGain_AboveIsFlat()
    {
        var f = new Filter { Type = FilterType.LowShelf, Fc = 1000, GainDb = 6, Q = 0.707 };
        Assert.InRange(f.GainDbAt(40, Fs), 5.5, 6.5);
        Assert.InRange(f.GainDbAt(16000, Fs), -0.5, 0.5);
    }

    [Fact]
    public void HighShelf_AboveCorner_ApproachesGain_BelowIsFlat()
    {
        var f = new Filter { Type = FilterType.HighShelf, Fc = 3000, GainDb = 6, Q = 0.707 };
        Assert.InRange(f.GainDbAt(18000, Fs), 5.0, 6.5);
        Assert.InRange(f.GainDbAt(80, Fs), -0.5, 0.5);
    }

    [Fact]
    public void Disabled_ReturnsZero()
    {
        var f = new Filter { Type = FilterType.Peaking, Fc = 1000, GainDb = 6, Q = 1, Enabled = false };
        Assert.Equal(0, f.GainDbAt(1000, Fs), 3);
    }

    [Fact]
    public void EqState_SumsBandsPlusPreamp()
    {
        var s = new EqState { PreampDb = -3 };
        s.Filters.Add(new Filter { Type = FilterType.Peaking, Fc = 1000, GainDb = 6, Q = 1 });
        Assert.InRange(s.GainDbAt(1000, Fs), 2.5, 3.5);   // ~6 + (-3)
    }
}
