using PolyTrader.Modules.ResolutionFarming.Logic;
using Xunit;
using static PolyTrader.Modules.ResolutionFarming.Logic.FarmingScanner;

namespace PolyTrader.Tests
{
    /// <summary>Sicherheitsnetz für die Scanner-Filter (Preisband, Kategorie, Blacklist, Cluster-Key, Score).</summary>
    public class FarmingScannerTests
    {
        [Theory]
        [InlineData(0.90, 0.90, 0.98, true)]   // untere Grenze inkl.
        [InlineData(0.98, 0.90, 0.98, true)]   // obere Grenze inkl.
        [InlineData(0.89, 0.90, 0.98, false)]
        [InlineData(0.99, 0.90, 0.98, false)]
        public void InPriceBand_is_inclusive(double ask, double min, double max, bool expected)
        {
            Assert.Equal(expected, InPriceBand((decimal)ask, (decimal)min, (decimal)max));
        }

        [Theory]
        [InlineData("Sports", "Sports,Politics", true)]
        [InlineData("sports", "Sports,Politics", true)]     // case-insensitiv
        [InlineData("Crypto", "Sports,Politics", false)]
        [InlineData("Sports", "", true)]                    // leere Whitelist = alles
        [InlineData("", "Sports,Politics", false)]          // leere Kategorie
        public void CategoryAllowed_matches_whitelist(string category, string whitelist, bool expected)
        {
            Assert.Equal(expected, CategoryAllowed(category, whitelist));
        }

        [Theory]
        [InlineData("us-election-dispute", null, "dispute,uma", true)]
        [InlineData("nfl-week1", "sports,nfl", "uma", false)]
        [InlineData("anything", null, "", false)]           // leere Blacklist
        public void IsBlacklisted_matches_slug_or_tags(string slug, string? tags, string blacklist, bool expected)
        {
            Assert.Equal(expected, IsBlacklisted(slug, tags, blacklist));
        }

        [Fact]
        public void ClusterKey_prefers_event_slug_then_market_slug()
        {
            Assert.Equal("epl-2026-03-14", ClusterKey("EPL-2026-03-14", "arsenal-win"));
            Assert.Equal("arsenal-win", ClusterKey(null, "Arsenal-Win"));
            Assert.Equal("arsenal-win", ClusterKey("  ", "arsenal-win"));
            Assert.Equal("", ClusterKey(null, null));
        }

        [Fact]
        public void Score_increases_with_edge_and_earlier_resolution()
        {
            // mehr Edge -> höherer Score
            Assert.True(Score(5m, 24) > Score(2m, 24));
            // frühere Auflösung -> höherer Score (Bindungsbonus)
            Assert.True(Score(3m, 1) > Score(3m, 40));
            // negativer Edge zählt als 0, aber Zeitbonus bleibt >= 0
            Assert.True(Score(-5m, 10) >= 0m);
        }
    }
}
