using System;
using System.Collections.Generic;
using System.IO;
using DansoriEQ.Core.Eq;
using DansoriEQ.Core.Presets;
using Xunit;

namespace DansoriEQ.Core.Tests;

public class PresetSerializerTests
{
    [Fact]
    public void RoundTrip_PreservesEqAndTarget()
    {
        var eq = new EqState { PreampDb = -6 };
        eq.Filters.Add(new Filter { Type = FilterType.Peaking,  Fc = 3000, GainDb = 3, Q = 1.2 });
        eq.Filters.Add(new Filter { Type = FilterType.LowShelf, Fc = 90,   GainDb = 4, Q = 0.7 });

        var target = new PresetTarget { Name = "Test IEM", Brand = "Brand", Type = "iem" };
        var preset = PresetSerializer.FromEqState(eq, target, new List<HistoryItem>(), DateTimeOffset.UnixEpoch, "note");

        var json = PresetSerializer.Serialize(preset);
        var back = PresetSerializer.Deserialize(json);
        var eq2 = PresetSerializer.ToEqState(back);

        Assert.Equal(-6, eq2.PreampDb, 3);
        Assert.Equal(2, eq2.Filters.Count);
        Assert.Equal(3000, eq2.Filters[0].Fc, 3);
        Assert.Equal(3, eq2.Filters[0].GainDb, 3);
        Assert.Equal(FilterType.LowShelf, eq2.Filters[1].Type);
        Assert.Equal("Test IEM", back.Target.Name);
    }

    [Fact]
    public void Deserialize_RejectsUnknownFormat()
    {
        var bad = "{\"format\":\"nope\",\"version\":1}";
        Assert.Throws<InvalidDataException>(() => PresetSerializer.Deserialize(bad));
    }

    [Fact]
    public void Deserialize_ClampsOutOfRangeValues()
    {
        var json =
            "{\"format\":\"dansorieq.eq\",\"version\":1," +
            "\"eq\":{\"preamp_db\":-6,\"filters\":[{\"type\":\"PK\",\"fc\":999999,\"gain\":99,\"q\":0.001,\"enabled\":true}]}}";
        var back = PresetSerializer.Deserialize(json);
        Assert.InRange(back.Eq.Filters[0].Fc, 20, 20000);
        Assert.InRange(back.Eq.Filters[0].Gain, -24, 24);
        Assert.InRange(back.Eq.Filters[0].Q, 0.1, 10);
    }
}
