using ChatService.Domain.Events;
using FluentAssertions;
using Xunit;

namespace ChatService.UnitTests.Domain.Events;

/// <summary>
/// EN: Unit tests for Conversation Domain Events.
/// VI: Unit tests cho Conversation Domain Events.
/// </summary>
public class ConversationDomainEventsTests
{
    [Fact]
    public void UserJoinedRoomDomainEvent_ShouldCreateWithCorrectProperties()
    {
        // Arrange
        var userId = Guid.NewGuid();
        var conversationId = Guid.NewGuid();
        var userName = "John Doe";

        // Act
        var domainEvent = new UserJoinedRoomDomainEvent(userId, conversationId, userName);

        // Assert
        domainEvent.UserId.Should().Be(userId);
        domainEvent.ConversationId.Should().Be(conversationId);
        domainEvent.UserName.Should().Be(userName);
        domainEvent.JoinedAt.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(1));
    }

    [Fact]
    public void UserLeftRoomDomainEvent_ShouldCreateWithCorrectProperties()
    {
        // Arrange
        var userId = Guid.NewGuid();
        var conversationId = Guid.NewGuid();

        // Act
        var domainEvent = new UserLeftRoomDomainEvent(userId, conversationId);

        // Assert
        domainEvent.UserId.Should().Be(userId);
        domainEvent.ConversationId.Should().Be(conversationId);
        domainEvent.LeftAt.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(1));
    }

    [Fact]
    public void TypingDomainEvent_ShouldCreateWithCorrectProperties_WhenTyping()
    {
        // Arrange
        var userId = Guid.NewGuid();
        var conversationId = Guid.NewGuid();
        var userName = "Jane Smith";
        var isTyping = true;

        // Act
        var domainEvent = new TypingDomainEvent(userId, conversationId, userName, isTyping);

        // Assert
        domainEvent.UserId.Should().Be(userId);
        domainEvent.ConversationId.Should().Be(conversationId);
        domainEvent.UserName.Should().Be(userName);
        domainEvent.IsTyping.Should().BeTrue();
    }

    [Fact]
    public void TypingDomainEvent_ShouldCreateWithCorrectProperties_WhenStoppedTyping()
    {
        // Arrange
        var userId = Guid.NewGuid();
        var conversationId = Guid.NewGuid();
        var userName = "Jane Smith";
        var isTyping = false;

        // Act
        var domainEvent = new TypingDomainEvent(userId, conversationId, userName, isTyping);

        // Assert
        domainEvent.IsTyping.Should().BeFalse();
    }

    [Fact]
    public void MessageSentDomainEvent_ShouldImplementINotification()
    {
        // Assert
        typeof(MessageSentDomainEvent).Should().Implement<MediatR.INotification>();
    }

    [Fact]
    public void MessageReadDomainEvent_ShouldCreateWithCorrectProperties()
    {
        // Arrange
        var messageId = Guid.NewGuid();
        var conversationId = Guid.NewGuid();
        var readerId = Guid.NewGuid();

        // Act
        var domainEvent = new MessageReadDomainEvent(messageId, conversationId, readerId);

        // Assert
        domainEvent.MessageId.Should().Be(messageId);
        domainEvent.ConversationId.Should().Be(conversationId);
        domainEvent.ReaderId.Should().Be(readerId);
        domainEvent.ReadAt.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(1));
    }
}
