using TeleWave.Application.Admin.Users.CreateUser;
using TeleWave.Application.Admin.Users.ResetPassword;
using TeleWave.Application.Broadcast;
using TeleWave.Application.Broadcast.Bumpers;
using TeleWave.Application.Broadcast.UpdateChannelSettings;
using TeleWave.Domain.Broadcast;
using Xunit;

namespace TeleWave.Application.Tests.Validators;

public class ValidatorTests
{
    [Fact]
    public void UpdateBumperVariant_ChecksNameWeightAndLines()
    {
        var v = new UpdateBumperVariantCommandValidator();

        var good = new UpdateBumperVariantCommand(
            Guid.NewGuid(),
            Guid.NewGuid(),
            new BumperVariantInput(
                "Name",
                BumperTrigger.Both,
                BumperBackground.NextPoster,
                3,
                [new BumperLineDto(BumperLineStyle.Title, BumperLineColor.Text, "{next.title}")]
            )
        );
        Assert.True(v.Validate(good).IsValid);

        Assert.False(v.Validate(Patch(good, input => input with { Name = "" })).IsValid);
        Assert.False(v.Validate(Patch(good, input => input with { Weight = -1 })).IsValid);
        Assert.False(
            v.Validate(
                Patch(
                    good,
                    input =>
                        input with
                        {
                            Lines =
                            [
                                new BumperLineDto(
                                    BumperLineStyle.Title,
                                    BumperLineColor.Text,
                                    new string('x', 121)
                                ),
                            ],
                        }
                )
            ).IsValid
        );
    }

    private static UpdateBumperVariantCommand Patch(
        UpdateBumperVariantCommand command,
        Func<BumperVariantInput, BumperVariantInput> change
    ) => command with { Input = change(command.Input) };

    [Fact]
    public void UpdateChannelSettings_ChecksRanges()
    {
        var v = new UpdateChannelSettingsCommandValidator();

        var good = new UpdateChannelSettingsCommand(Guid.NewGuid(), "Name", true, null);
        Assert.True(v.Validate(good).IsValid);

        Assert.False(v.Validate(good with { Name = "" }).IsValid);
    }

    [Fact]
    public void ResetUserPassword_RequiresMinLength()
    {
        var v = new ResetUserPasswordCommandValidator();

        Assert.True(v.Validate(new ResetUserPasswordCommand(Guid.NewGuid(), "Password1")).IsValid);
        Assert.False(v.Validate(new ResetUserPasswordCommand(Guid.NewGuid(), "short")).IsValid);
        Assert.False(v.Validate(new ResetUserPasswordCommand(Guid.Empty, "Password1")).IsValid);
    }

    [Fact]
    public void CreateUser_ChecksNameAndPassword()
    {
        var v = new CreateUserCommandValidator();

        Assert.True(v.Validate(new CreateUserCommand("bob", "Password1", Guid.NewGuid())).IsValid);
        Assert.False(v.Validate(new CreateUserCommand("ab", "Password1", Guid.NewGuid())).IsValid);
        Assert.False(v.Validate(new CreateUserCommand("bob", "short", Guid.NewGuid())).IsValid);
        Assert.False(v.Validate(new CreateUserCommand("bob", "Password1", Guid.Empty)).IsValid);
    }
}
