namespace BudgetApp.Tests.Domain;

using BudgetApp.Domain.Models;
using Xunit;

public class BaseBudgetTests
{
    [Fact]
    public void Constructor_WithValidParameters_CreatesBudget()
    {
        // Arrange & Act
        var budget = new BaseBudget("Grocery", new Money(100m, "USD"));

        // Assert
        Assert.Equal("Grocery", budget.Name);
        Assert.Equal(100m, budget.Balance.Amount);
        Assert.NotEqual(Guid.Empty, budget.Id);
    }

    [Fact]
    public void AddMoney_IncreasesBalance()
    {
        // Arrange
        var budget = new BaseBudget("Grocery", new Money(100m, "USD"));

        // Act
        budget.AddMoney(new Money(50m, "USD"));

        // Assert
        Assert.Equal(150m, budget.Balance.Amount);
    }

    [Fact]
    public void RemoveMoney_DecreasesBalance()
    {
        // Arrange
        var budget = new BaseBudget("Grocery", new Money(100m, "USD"));

        // Act
        budget.RemoveMoney(new Money(50m, "USD"));

        // Assert
        Assert.Equal(50m, budget.Balance.Amount);
    }

    [Fact]
    public void RemoveMoney_ResultingInNegative_ThrowsException()
    {
        // Arrange
        var budget = new BaseBudget("Grocery", new Money(100m, "USD"));

        // Act & Assert
        Assert.Throws<InvalidOperationException>(() => budget.RemoveMoney(new Money(150m, "USD")));
    }

    [Fact]
    public void RemoveMoney_WithDifferentCurrency_ThrowsException()
    {
        // Arrange
        var budget = new BaseBudget("Grocery", new Money(100m, "USD"));

        // Act & Assert
        Assert.Throws<InvalidOperationException>(() => budget.RemoveMoney(new Money(50m, "EUR")));
    }

    [Fact]
    public void AddMoney_WithDifferentCurrency_ThrowsException()
    {
        // Arrange
        var budget = new BaseBudget("Grocery", new Money(100m, "USD"));

        // Act & Assert
        Assert.Throws<InvalidOperationException>(() => budget.AddMoney(new Money(50m, "EUR")));
    }

    [Fact]
    public void Balance_NeverNegative()
    {
        // Arrange
        var budget = new BaseBudget("Grocery", new Money(100m, "USD"));

        // Act
        budget.RemoveMoney(new Money(100m, "USD"));

        // Assert
        Assert.Equal(0m, budget.Balance.Amount);
    }
}


