using ErsatzTV.Application.Troubleshooting;
using ErsatzTV.Application.Troubleshooting.Queries;
using ErsatzTV.Core.Interfaces.Scheduling;
using NSubstitute;
using NUnit.Framework;
using Shouldly;

namespace ErsatzTV.Tests.Application.Troubleshooting;

[TestFixture]
public class ValidateSequentialScheduleHandlerTests
{
    private ISequentialScheduleValidator _validator = null!;
    private ValidateSequentialScheduleHandler _handler = null!;

    [SetUp]
    public void SetUp()
    {
        _validator = Substitute.For<ISequentialScheduleValidator>();
        _handler = new ValidateSequentialScheduleHandler(_validator);
    }

    [Test]
    public async Task Should_Report_Valid_When_No_Messages()
    {
        _validator.ToJson(Arg.Any<string>()).Returns("{ }");
        _validator.GetValidationMessages(Arg.Any<string>(), Arg.Any<bool>())
            .Returns(Task.FromResult<IList<string>>([]));

        ValidateSequentialScheduleViewModel result =
            await _handler.Handle(new ValidateSequentialSchedule("content: []", false), CancellationToken.None);

        result.IsValid.ShouldBeTrue();
        result.Messages.ShouldBeEmpty();
        result.Json.ShouldBe("{ }");
    }

    [Test]
    public async Task Should_Report_Invalid_With_Messages()
    {
        _validator.ToJson(Arg.Any<string>()).Returns("{ }");
        _validator.GetValidationMessages(Arg.Any<string>(), Arg.Any<bool>())
            .Returns(Task.FromResult<IList<string>>(["content is required"]));

        ValidateSequentialScheduleViewModel result =
            await _handler.Handle(new ValidateSequentialSchedule("nope: true", true), CancellationToken.None);

        result.IsValid.ShouldBeFalse();
        result.Messages.ShouldBe(["content is required"]);
        result.Json.ShouldBe("{ }");
    }

    [Test]
    public async Task Should_Capture_Exception_Message_When_Conversion_Throws()
    {
        _validator.ToJson(Arg.Any<string>()).Returns(_ => throw new InvalidOperationException("bad yaml"));

        ValidateSequentialScheduleViewModel result =
            await _handler.Handle(new ValidateSequentialSchedule(": : :", false), CancellationToken.None);

        result.IsValid.ShouldBeFalse();
        result.Messages.ShouldBe(["bad yaml"]);
        result.Json.ShouldBeEmpty();
    }
}
