using CartWise.Domain.Entities;
using CartWise.Domain.Enums;

namespace CartWise.Domain.Tests;

public class ProductTests
{
    private static readonly DateTime Now = new(2026, 8, 10, 12, 0, 0, DateTimeKind.Utc);

    [Fact]
    public void Constructor_SetsNormalizedName()
    {
        var product = new Product("Jif Creamy Peanut Butter", ProductSourceType.Manual, Now);

        Assert.Equal("JIF CREAMY PEANUT BUTTER", product.NormalizedName);
    }

    [Theory]
    [InlineData("")]
    [InlineData("   ")]
    [InlineData(null)]
    public void Constructor_ThrowsWhenNameIsMissing(string? name)
    {
        Assert.Throws<ArgumentException>(() => new Product(name!, ProductSourceType.Manual, Now));
    }

    [Fact]
    public void AddIdentifier_AddsNormalizedIdentifier()
    {
        var product = new Product("Jif Creamy 16 oz", ProductSourceType.Manual, Now);

        var identifier = product.AddIdentifier(ProductIdentifierType.UpcA, " 051500255516 ");

        Assert.Single(product.Identifiers);
        Assert.Equal("051500255516", identifier.NormalizedValue);
        Assert.Equal(product.ProductId, identifier.ProductId);
    }

    [Fact]
    public void AddIdentifier_ThrowsForDuplicateIdentifier()
    {
        var product = new Product("Jif Creamy 16 oz", ProductSourceType.Manual, Now);
        product.AddIdentifier(ProductIdentifierType.UpcA, "051500255516");

        Assert.Throws<InvalidOperationException>(() => product.AddIdentifier(ProductIdentifierType.UpcA, "051500255516"));
    }

    [Fact]
    public void AddIdentifier_AllowsSameValueUnderDifferentType()
    {
        var product = new Product("Jif Creamy 16 oz", ProductSourceType.Manual, Now);
        product.AddIdentifier(ProductIdentifierType.UpcA, "051500255516");

        var identifier = product.AddIdentifier(ProductIdentifierType.Gtin, "051500255516");

        Assert.Equal(2, product.Identifiers.Count);
        Assert.Equal(ProductIdentifierType.Gtin, identifier.IdentifierType);
    }
}
