using ColaFlow.Modules.ProjectManagement.Domain.ValueObjects;
using FluentAssertions;

namespace ColaFlow.Domain.Tests.ValueObjects;

/// <summary>
/// Unit tests for Enumeration-based value objects
/// </summary>
public class EnumerationTests
{
    #region ProjectStatus Tests

    [Fact]
    public void ProjectStatus_Active_ShouldHaveCorrectValues()
    {
        // Assert
        ProjectStatus.Active.Id.Should().Be(1);
        ProjectStatus.Active.Name.Should().Be("Active");
    }

    [Fact]
    public void ProjectStatus_Archived_ShouldHaveCorrectValues()
    {
        // Assert
        ProjectStatus.Archived.Id.Should().Be(2);
        ProjectStatus.Archived.Name.Should().Be("Archived");
    }

    [Fact]
    public void ProjectStatus_OnHold_ShouldHaveCorrectValues()
    {
        // Assert
        ProjectStatus.OnHold.Id.Should().Be(3);
        ProjectStatus.OnHold.Name.Should().Be("On Hold");
    }

    [Fact]
    public void ProjectStatus_Equals_WithSameStatus_ShouldReturnTrue()
    {
        // Arrange
        var status1 = ProjectStatus.Active;
        var status2 = ProjectStatus.Active;

        // Act & Assert
        status1.Should().Be(status2);
        status1.Equals(status2).Should().BeTrue();
    }

    [Fact]
    public void ProjectStatus_Equals_WithDifferentStatus_ShouldReturnFalse()
    {
        // Arrange
        var status1 = ProjectStatus.Active;
        var status2 = ProjectStatus.Archived;

        // Act & Assert
        status1.Should().NotBe(status2);
        status1.Equals(status2).Should().BeFalse();
    }

    [Fact]
    public void ProjectStatus_ToString_ShouldReturnName()
    {
        // Arrange
        var status = ProjectStatus.Active;

        // Act
        var result = status.ToString();

        // Assert
        result.Should().Be("Active");
    }

    #endregion

    #region WorkItemStatus Tests

    [Fact]
    public void WorkItemStatus_ToDo_ShouldHaveCorrectValues()
    {
        // Assert
        WorkItemStatus.ToDo.Id.Should().Be(1);
        WorkItemStatus.ToDo.Name.Should().Be("To Do");
    }

    [Fact]
    public void WorkItemStatus_InProgress_ShouldHaveCorrectValues()
    {
        // Assert
        WorkItemStatus.InProgress.Id.Should().Be(2);
        WorkItemStatus.InProgress.Name.Should().Be("In Progress");
    }

    [Fact]
    public void WorkItemStatus_InReview_ShouldHaveCorrectValues()
    {
        // Assert
        WorkItemStatus.InReview.Id.Should().Be(3);
        WorkItemStatus.InReview.Name.Should().Be("In Review");
    }

    [Fact]
    public void WorkItemStatus_Done_ShouldHaveCorrectValues()
    {
        // Assert
        WorkItemStatus.Done.Id.Should().Be(4);
        WorkItemStatus.Done.Name.Should().Be("Done");
    }

    [Fact]
    public void WorkItemStatus_Blocked_ShouldHaveCorrectValues()
    {
        // Assert
        WorkItemStatus.Blocked.Id.Should().Be(5);
        WorkItemStatus.Blocked.Name.Should().Be("Blocked");
    }

    [Fact]
    public void WorkItemStatus_Equals_WithSameStatus_ShouldReturnTrue()
    {
        // Arrange
        var status1 = WorkItemStatus.ToDo;
        var status2 = WorkItemStatus.ToDo;

        // Act & Assert
        status1.Should().Be(status2);
        status1.Equals(status2).Should().BeTrue();
    }

    [Fact]
    public void WorkItemStatus_Equals_WithDifferentStatus_ShouldReturnFalse()
    {
        // Arrange
        var status1 = WorkItemStatus.ToDo;
        var status2 = WorkItemStatus.Done;

        // Act & Assert
        status1.Should().NotBe(status2);
        status1.Equals(status2).Should().BeFalse();
    }

    [Fact]
    public void WorkItemStatus_ToString_ShouldReturnName()
    {
        // Arrange
        var status = WorkItemStatus.InProgress;

        // Act
        var result = status.ToString();

        // Assert
        result.Should().Be("In Progress");
    }

    #endregion

    #region TaskPriority Tests

    [Fact]
    public void TaskPriority_Low_ShouldHaveCorrectValues()
    {
        // Assert
        TaskPriority.Low.Id.Should().Be(1);
        TaskPriority.Low.Name.Should().Be("Low");
    }

    [Fact]
    public void TaskPriority_Medium_ShouldHaveCorrectValues()
    {
        // Assert
        TaskPriority.Medium.Id.Should().Be(2);
        TaskPriority.Medium.Name.Should().Be("Medium");
    }

    [Fact]
    public void TaskPriority_High_ShouldHaveCorrectValues()
    {
        // Assert
        TaskPriority.High.Id.Should().Be(3);
        TaskPriority.High.Name.Should().Be("High");
    }

    [Fact]
    public void TaskPriority_Urgent_ShouldHaveCorrectValues()
    {
        // Assert
        TaskPriority.Urgent.Id.Should().Be(4);
        TaskPriority.Urgent.Name.Should().Be("Urgent");
    }

    [Fact]
    public void TaskPriority_Equals_WithSamePriority_ShouldReturnTrue()
    {
        // Arrange
        var priority1 = TaskPriority.High;
        var priority2 = TaskPriority.High;

        // Act & Assert
        priority1.Should().Be(priority2);
        priority1.Equals(priority2).Should().BeTrue();
    }

    [Fact]
    public void TaskPriority_Equals_WithDifferentPriority_ShouldReturnFalse()
    {
        // Arrange
        var priority1 = TaskPriority.Low;
        var priority2 = TaskPriority.Urgent;

        // Act & Assert
        priority1.Should().NotBe(priority2);
        priority1.Equals(priority2).Should().BeFalse();
    }

    [Fact]
    public void TaskPriority_ToString_ShouldReturnName()
    {
        // Arrange
        var priority = TaskPriority.Medium;

        // Act
        var result = priority.ToString();

        // Assert
        result.Should().Be("Medium");
    }

    [Fact]
    public void TaskPriority_ShouldBeOrderedByImportance()
    {
        // Arrange & Act & Assert
        TaskPriority.Low.Id.Should().BeLessThan(TaskPriority.Medium.Id);
        TaskPriority.Medium.Id.Should().BeLessThan(TaskPriority.High.Id);
        TaskPriority.High.Id.Should().BeLessThan(TaskPriority.Urgent.Id);
    }

    #endregion
}
