using Baya.Domain.Entities.Booking;

namespace Baya.Test.Foundation.Bookings;

public class BookingAmountsTests
{
    [Theory]
    [InlineData(10_000_000, 0.15, 1_500_000, 8_500_000)]
    [InlineData(5_000_000, 0.15, 750_000, 4_250_000)]
    // Rounding half away from zero: 3 × 0.15 = 0.45 → 0 (commission), payout 3.
    [InlineData(3, 0.15, 0, 3)]
    public void Split_reconciles_gross_equals_commission_plus_payout(long gross, decimal rate, long expectedCommission, long expectedPayout)
    {
        var (commission, payout) = BookingAmounts.Split(gross, rate);

        Assert.Equal(expectedCommission, commission);
        Assert.Equal(expectedPayout, payout);
        Assert.Equal(gross, commission + payout);
        Assert.True(commission >= 0 && payout >= 0);
    }

    [Theory]
    [InlineData(8_500_000, 1)]
    [InlineData(8_500_000, 3)]
    [InlineData(8_500_001, 3)]
    [InlineData(10, 3)]
    [InlineData(2, 3)]
    public void SplitPayout_sums_exactly_to_payout_with_remainder_on_last(long payout, int sessions)
    {
        var parts = BookingAmounts.SplitPayout(payout, sessions);

        Assert.Equal(sessions, parts.Length);
        Assert.Equal(payout, parts.Sum());
        Assert.All(parts, p => Assert.True(p >= 0));

        // Equal shares except the last, which carries the remainder.
        var per = payout / sessions;
        for (var i = 0; i < sessions - 1; i++)
            Assert.Equal(per, parts[i]);
        Assert.Equal(payout - per * (sessions - 1), parts[^1]);
    }

    [Fact]
    public void SplitPayout_single_visit_returns_whole_amount()
    {
        var parts = BookingAmounts.SplitPayout(4_250_000, 1);
        Assert.Single(parts);
        Assert.Equal(4_250_000, parts[0]);
    }
}
