using ColaFlow.Modules.Mcp.Domain.ValueObjects;
using Xunit;

namespace ColaFlow.Modules.Mcp.Tests.Domain;

public class DiffFieldTests
{
    [Fact]
    public void Create_ValidInput_Success()
    {
        // Arrange & Act
        var diffField = new DiffField(
            fieldName: "Title",
            displayName: "Title",
            oldValue: "Old Title",
            newValue: "New Title"
        );

        // Assert
        Assert.Equal("Title", diffField.FieldName);
        Assert.Equal("Title", diffField.DisplayName);
        Assert.Equal("Old Title", diffField.OldValue);
        Assert.Equal("New Title", diffField.NewValue);
        Assert.Null(diffField.DiffHtml);
    }

    [Fact]
    public void Create_WithDiffHtml_Success()
    {
        // Arrange & Act
        var diffField = new DiffField(
            fieldName: "Description",
            displayName: "Description",
            oldValue: "Old description",
            newValue: "New description",
            diffHtml: "<del>Old</del><ins>New</ins> description"
        );

        // Assert
        Assert.Equal("<del>Old</del><ins>New</ins> description", diffField.DiffHtml);
    }

    [Fact]
    public void Create_EmptyFieldName_ThrowsException()
    {
        // Act & Assert
        Assert.Throws<ArgumentException>(() => new DiffField(
            fieldName: "",
            displayName: "Title",
            oldValue: "Old",
            newValue: "New"
        ));
    }

    [Fact]
    public void Create_EmptyDisplayName_ThrowsException()
    {
        // Act & Assert
        Assert.Throws<ArgumentException>(() => new DiffField(
            fieldName: "Title",
            displayName: "",
            oldValue: "Old",
            newValue: "New"
        ));
    }

    [Fact]
    public void Equality_SameValues_AreEqual()
    {
        // Arrange
        var field1 = new DiffField("Title", "Title", "Old", "New");
        var field2 = new DiffField("Title", "Title", "Old", "New");

        // Act & Assert
        Assert.Equal(field1, field2);
        Assert.True(field1 == field2);
        Assert.False(field1 != field2);
    }

    [Fact]
    public void Equality_DifferentValues_AreNotEqual()
    {
        // Arrange
        var field1 = new DiffField("Title", "Title", "Old", "New");
        var field2 = new DiffField("Title", "Title", "Old", "Different");

        // Act & Assert
        Assert.NotEqual(field1, field2);
        Assert.False(field1 == field2);
        Assert.True(field1 != field2);
    }

    [Fact]
    public void HasChanged_DifferentValues_ReturnsTrue()
    {
        // Arrange
        var diffField = new DiffField("Title", "Title", "Old", "New");

        // Act & Assert
        Assert.True(diffField.HasChanged());
    }

    [Fact]
    public void HasChanged_SameValues_ReturnsFalse()
    {
        // Arrange
        var diffField = new DiffField("Title", "Title", "Same", "Same");

        // Act & Assert
        Assert.False(diffField.HasChanged());
    }

    [Fact]
    public void HasChanged_BothNull_ReturnsFalse()
    {
        // Arrange
        var diffField = new DiffField("Title", "Title", null, null);

        // Act & Assert
        Assert.False(diffField.HasChanged());
    }

    [Fact]
    public void HasChanged_OldNull_ReturnsTrue()
    {
        // Arrange
        var diffField = new DiffField("Title", "Title", null, "New");

        // Act & Assert
        Assert.True(diffField.HasChanged());
    }

    [Fact]
    public void HasChanged_NewNull_ReturnsTrue()
    {
        // Arrange
        var diffField = new DiffField("Title", "Title", "Old", null);

        // Act & Assert
        Assert.True(diffField.HasChanged());
    }

    [Fact]
    public void GetChangeDescription_NormalChange_ReturnsFormattedString()
    {
        // Arrange
        var diffField = new DiffField("Title", "Title", "Old Title", "New Title");

        // Act
        var description = diffField.GetChangeDescription();

        // Assert
        Assert.Equal("Title: Old Title → New Title", description);
    }

    [Fact]
    public void GetChangeDescription_OldNull_ReturnsFormattedString()
    {
        // Arrange
        var diffField = new DiffField("Title", "Title", null, "New Title");

        // Act
        var description = diffField.GetChangeDescription();

        // Assert
        Assert.Equal("Title: → New Title", description);
    }

    [Fact]
    public void GetChangeDescription_NewNull_ReturnsFormattedString()
    {
        // Arrange
        var diffField = new DiffField("Title", "Title", "Old Title", null);

        // Act
        var description = diffField.GetChangeDescription();

        // Assert
        Assert.Equal("Title: Old Title → (removed)", description);
    }

    [Fact]
    public void GetChangeDescription_BothNull_ReturnsFormattedString()
    {
        // Arrange
        var diffField = new DiffField("Title", "Title", null, null);

        // Act
        var description = diffField.GetChangeDescription();

        // Assert
        Assert.Equal("Title: (no change)", description);
    }
}
