using Xunit;
using FluentAssertions;
using IamService.Domain.AggregatesModel.AccessRequestAggregate;

namespace IamService.UnitTests.Domain.AccessControl;

/// <summary>
/// EN: Unit tests for AccessRequestStatus enumeration.
/// VI: Unit tests cho AccessRequestStatus enumeration.
/// </summary>
public class AccessRequestStatusTests
{
    [Fact]
    public void GetAll_Returns6Statuses()
    {
        // Act
        var statuses = AccessRequestStatus.GetAll();

        // Assert
        statuses.Should().HaveCount(6);
    }

    [Theory]
    [InlineData(1, "Draft")]
    [InlineData(2, "Pending")]
    [InlineData(3, "Approved")]
    [InlineData(4, "Rejected")]
    [InlineData(5, "Cancelled")]
    [InlineData(6, "Expired")]
    public void FromId_ValidId_ReturnsCorrectStatus(int id, string expectedName)
    {
        // Act
        var status = AccessRequestStatus.FromId(id);

        // Assert
        status.Should().NotBeNull();
        status!.Name.Should().Be(expectedName);
    }

    [Theory]
    [InlineData(0)]
    [InlineData(7)]
    [InlineData(-1)]
    public void FromId_InvalidId_ReturnsNull(int id)
    {
        // Act
        var status = AccessRequestStatus.FromId(id);

        // Assert
        status.Should().BeNull();
    }

    [Theory]
    [InlineData("Approved", true)]
    [InlineData("Rejected", true)]
    [InlineData("Cancelled", true)]
    [InlineData("Expired", true)]
    [InlineData("Draft", false)]
    [InlineData("Pending", false)]
    public void IsTerminal_ReturnsCorrectValue(string statusName, bool expectedTerminal)
    {
        // Arrange
        var status = AccessRequestStatus.GetAll().First(s => s.Name == statusName);

        // Assert
        status.IsTerminal.Should().Be(expectedTerminal);
    }

    [Fact]
    public void StaticInstances_AreCorrect()
    {
        // Assert
        AccessRequestStatus.Draft.Id.Should().Be(1);
        AccessRequestStatus.Pending.Id.Should().Be(2);
        AccessRequestStatus.Approved.Id.Should().Be(3);
        AccessRequestStatus.Rejected.Id.Should().Be(4);
        AccessRequestStatus.Cancelled.Id.Should().Be(5);
        AccessRequestStatus.Expired.Id.Should().Be(6);
    }
}
