using Theriapolis.Core;
using Theriapolis.Core.Rules.Dialogue;
using Theriapolis.Core.Rules.Reputation;
using Xunit;

namespace Theriapolis.Tests.Dialogue;

/// <summary>
/// Phase 6 M3 — disposition-driven shop pricing per the design doc.
/// </summary>
public sealed class ShopPricingTests
{
    [Fact]
    public void ServiceAvailable_RefusesAtNemesisAndHostile()
    {
        Assert.False(ShopPricing.ServiceAvailable(-100));
        Assert.False(ShopPricing.ServiceAvailable( -90));
        Assert.False(ShopPricing.ServiceAvailable( -76));
        Assert.False(ShopPricing.ServiceAvailable( -75));
        Assert.False(ShopPricing.ServiceAvailable( -60));
        Assert.False(ShopPricing.ServiceAvailable( -51));
        Assert.True(ShopPricing.ServiceAvailable(  -50));
        Assert.True(ShopPricing.ServiceAvailable(    0));
        Assert.True(ShopPricing.ServiceAvailable(  100));
    }

    [Fact]
    public void BuyMultiplier_HitsKeyTiers()
    {
        Assert.Equal(1.25f, ShopPricing.BuyMultiplier(-30));   // Antagonistic
        Assert.Equal(1.25f, ShopPricing.BuyMultiplier(-10));   // Unfriendly
        Assert.Equal(1.00f, ShopPricing.BuyMultiplier(  0));   // Neutral
        Assert.Equal(0.90f, ShopPricing.BuyMultiplier( 10));   // Favorable
        Assert.Equal(0.80f, ShopPricing.BuyMultiplier( 30));   // Friendly
        Assert.Equal(0.70f, ShopPricing.BuyMultiplier( 60));   // Allied
        Assert.Equal(0.60f, ShopPricing.BuyMultiplier( 90));   // Champion
    }

    [Fact]
    public void BuyPriceFor_RoundsUp_NeverBelowOne()
    {
        // Item base cost 10 fang, friendly disposition (×0.80) = 8 fang.
        Assert.Equal(8, ShopPricing.BuyPriceFor(10, 30));
        // Champion (×0.60) = 6.
        Assert.Equal(6, ShopPricing.BuyPriceFor(10, 90));
        // Tiny item, large discount, but minimum 1.
        Assert.Equal(1, ShopPricing.BuyPriceFor(1, 90));
    }

    [Fact]
    public void SellPriceFor_FloorsToZero_AtRefusedTiers()
    {
        Assert.Equal(0, ShopPricing.SellPriceFor(20, -90));   // Nemesis
        Assert.Equal(0, ShopPricing.SellPriceFor(20, -60));   // Hostile
    }

    [Fact]
    public void SellPriceFor_BetterAtHigherTrust()
    {
        int neutral  = ShopPricing.SellPriceFor(40, 0);
        int champion = ShopPricing.SellPriceFor(40, 90);
        Assert.True(champion > neutral, $"Champion sell ({champion}) should beat neutral ({neutral}).");
    }
}
