using FluentValidation.TestHelper;
using TakeoutSaaS.Application.App.Tenants.Validators;
using TakeoutSaaS.Application.Tests.TestUtilities;
using TakeoutSaaS.Domain.Tenants.Enums;

namespace TakeoutSaaS.Application.Tests.App.Tenants.Validators;

public sealed class CreateAnnouncementCommandValidatorTests
{
    private readonly CreateAnnouncementCommandValidator _validator = new();

    [Fact]
    public void GivenEmptyTitle_WhenValidate_ThenShouldHaveError()
    {
        // Arrange
        var command = AnnouncementTestData.CreateValidCreateCommand() with { Title = "" };

        // Act
        var result = _validator.TestValidate(command);

        // Assert
        result.ShouldHaveValidationErrorFor(x => x.Title);
    }

    [Fact]
    public void GivenTitleTooLong_WhenValidate_ThenShouldHaveError()
    {
        // Arrange
        var command = AnnouncementTestData.CreateValidCreateCommand() with { Title = new string('A', 129) };

        // Act
        var result = _validator.TestValidate(command);

        // Assert
        result.ShouldHaveValidationErrorFor(x => x.Title);
    }

    [Fact]
    public void GivenEmptyContent_WhenValidate_ThenShouldHaveError()
    {
        // Arrange
        var command = AnnouncementTestData.CreateValidCreateCommand() with { Content = "" };

        // Act
        var result = _validator.TestValidate(command);

        // Assert
        result.ShouldHaveValidationErrorFor(x => x.Content);
    }

    [Fact]
    public void GivenEmptyTargetType_WhenValidate_ThenShouldHaveError()
    {
        // Arrange
        var command = AnnouncementTestData.CreateValidCreateCommand() with { TargetType = "" };

        // Act
        var result = _validator.TestValidate(command);

        // Assert
        result.ShouldHaveValidationErrorFor(x => x.TargetType);
    }

    [Fact]
    public void GivenTenantIdZeroAndNotPlatform_WhenValidate_ThenShouldHaveError()
    {
        // Arrange
        var command = AnnouncementTestData.CreateValidCreateCommand() with
        {
            TenantId = 0,
            PublisherScope = PublisherScope.Tenant
        };

        // Act
        var result = _validator.TestValidate(command);

        // Assert
        result.ShouldHaveValidationErrorFor(x => x);
    }

    [Fact]
    public void GivenEffectiveToBeforeFrom_WhenValidate_ThenShouldHaveError()
    {
        // Arrange
        var command = AnnouncementTestData.CreateValidCreateCommand() with
        {
            EffectiveFrom = DateTime.UtcNow,
            EffectiveTo = DateTime.UtcNow.AddMinutes(-5)
        };

        // Act
        var result = _validator.TestValidate(command);

        // Assert
        result.ShouldHaveValidationErrorFor(x => x.EffectiveTo);
    }

    [Fact]
    public void GivenValidCommand_WhenValidate_ThenShouldNotHaveErrors()
    {
        // Arrange
        var command = AnnouncementTestData.CreateValidCreateCommand();

        // Act
        var result = _validator.TestValidate(command);

        // Assert
        result.ShouldNotHaveAnyValidationErrors();
    }
}
