using e_suite.API.Common.exceptions;
using e_suite.API.Common.models;
using e_suite.Database.Audit;
using eSuite.Core.Sequences;
using Microsoft.AspNetCore.Mvc;
using Moq;
using NUnit.Framework;

namespace eSuite.API.UnitTests.Controllers.SequenceManagerControllerUnitTests;

[TestFixture]
public class CreateSequenceUnitTests : SequenceControllerBaseTest
{

    [SetUp]
    public override async Task Setup()
    {
        await base.Setup();
    }

    [Test]
    public void CreateSequence_WhenSequenceExists_ThrowsExistsException()
    {
        //Arrange
        const string errorText = "A sequence with this name already exists";

        var guid = new Guid("2fb9cb23-ca52-44b5-a7a5-74a5f449fa47");
        var sequence = new NewSequence
        {
            Guid = guid,
            Name = $"sequence-{guid}",
            Pattern = "orders",
            Increment = 1,
            RolloverType = Rollover.Continuous,
            Seed = 0
        };

        _sequenceManagerMock.Setup(x => x.CreateSequence(It.IsAny<AuditUserDetails>(), sequence, It.IsAny<CancellationToken>())).Throws(new ExistsException(errorText));

        //Assert
        Assert.ThrowsAsync<ExistsException>(async () =>
        {
            //Act
            var actualResult = await _sequenceController.CreateSequence(sequence);
        });
    }

    [Test]
    public async Task CreateSequence_SequenceDoesNotExist_ReturnsOK()
    {
        //Arrange
        var guid = new Guid("5fa0cd73-3cb8-4ee8-9827-1e5cd78c4aa9");
        var sequence = new NewSequence
        {
            Guid = guid,
            Name = $"sequence-{guid}",
            Pattern = "orders",
            Increment = 1,
            RolloverType = Rollover.Continuous,
            Seed = 0
        };

        //Act
        var actualResult = await _sequenceController.CreateSequence(sequence);

        //Assert
        _sequenceManagerMock.Verify(x => x.CreateSequence(It.IsAny<AuditUserDetails>(), sequence, It.IsAny<CancellationToken>()), Times.Once());

        Assert.That(actualResult.GetType(), Is.EqualTo(typeof(OkResult)));
        var objectResult = actualResult as OkResult;

        Assert.That(objectResult?.StatusCode, Is.EqualTo(200));
    }
}