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

namespace IamService.UnitTests.Domain.Organizations;

/// <summary>
/// EN: Unit tests for OrganizationStatus enumeration (SmartEnum pattern).
/// VI: Kiểm thử đơn vị cho OrganizationStatus enumeration (SmartEnum pattern).
/// </summary>
public class OrganizationStatusTests
{
    #region Static Values Tests

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

    [Fact]
    public void Suspended_HasCorrectIdAndName()
    {
        // Assert
        OrganizationStatus.Suspended.Id.Should().Be(2);
        OrganizationStatus.Suspended.Name.Should().Be("Suspended");
    }

    [Fact]
    public void PendingApproval_HasCorrectIdAndName()
    {
        // Assert
        OrganizationStatus.PendingApproval.Id.Should().Be(3);
        OrganizationStatus.PendingApproval.Name.Should().Be("PendingApproval");
    }

    [Fact]
    public void Archived_HasCorrectIdAndName()
    {
        // Assert
        OrganizationStatus.Archived.Id.Should().Be(4);
        OrganizationStatus.Archived.Name.Should().Be("Archived");
    }

    #endregion

    #region GetAll Tests

    [Fact]
    public void GetAll_ReturnsAllStatuses()
    {
        // Act
        var allStatuses = OrganizationStatus.GetAll().ToList();

        // Assert
        allStatuses.Should().HaveCount(4);
        allStatuses.Should().Contain(OrganizationStatus.Active);
        allStatuses.Should().Contain(OrganizationStatus.Suspended);
        allStatuses.Should().Contain(OrganizationStatus.PendingApproval);
        allStatuses.Should().Contain(OrganizationStatus.Archived);
    }

    [Fact]
    public void GetAll_ReturnsDistinctIds()
    {
        // Act
        var allStatuses = OrganizationStatus.GetAll().ToList();

        // Assert
        allStatuses.Select(s => s.Id).Distinct().Should().HaveCount(4);
    }

    #endregion

    #region Equality Tests

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

        // Assert
        status1.Should().Be(status2);
        (status1 == status2).Should().BeTrue();
    }

    [Fact]
    public void Equality_DifferentStatuses_AreNotEqual()
    {
        // Arrange
        var status1 = OrganizationStatus.Active;
        var status2 = OrganizationStatus.Suspended;

        // Assert
        status1.Should().NotBe(status2);
        (status1 != status2).Should().BeTrue();
    }

    #endregion

    #region ToString Tests

    [Fact]
    public void ToString_ReturnsName()
    {
        // Assert
        OrganizationStatus.Active.ToString().Should().Be("Active");
        OrganizationStatus.Suspended.ToString().Should().Be("Suspended");
        OrganizationStatus.PendingApproval.ToString().Should().Be("PendingApproval");
        OrganizationStatus.Archived.ToString().Should().Be("Archived");
    }

    #endregion
}
