using e_suite.API.Common.exceptions;
using e_suite.Database.Core.Tables.Sequences;
using eSuite.Core.Miscellaneous;
using eSuite.Core.Sequences;
using NUnit.Framework;
using SequenceManager.UnitTests.Helpers;

namespace SequenceManager.UnitTests;

[TestFixture]
public class NextValueUnitTests : SequenceManagerTestBase
{
    [SetUp]
    public override async Task Setup()
    {
        await base.Setup();
    }
        
    [Test]
    public void NextValue_SequenceNotFound_ThrowsException()
    {
        // Arrange
        SequenceManagerRepository.Sequences.Add(new Sequence
        {
            Id = 555,
            Guid = Guid.NewGuid(),
            Increment = 1,
            Name = "Sequence name",
            Pattern = "Order [0]",
            Rollover = Rollover.Continuous,
            Deleted = false,
            Seed = 0,
            LastIssueDate = DateTime.Now,
            LastIssueValue = 998
        });

        // Act
        // Assert
        Assert.ThrowsAsync<NotFoundException>(async () => { await SequenceManager.NextValue(AuditUserDetails, new GeneralIdRef { Id = 222 }, default);  });
    }

    [Test]
    public void NextValue_SequenceDeleted_ThrowsException()
    {
        // Arrange
        SequenceManagerRepository.Sequences.Add(new Sequence
        {
            Id = 222,
            Guid = Guid.NewGuid(),
            Increment = 1,
            Name = "Sequence name",
            Pattern = "Order [0]",
            Rollover = Rollover.Continuous,
            Deleted = true,
            Seed = 0,
            LastIssueDate = DateTime.Now,
            LastIssueValue = 998
        });

        // Act
        // Assert
        Assert.ThrowsAsync<NotFoundException>(async () => { await SequenceManager.NextValue(AuditUserDetails, new GeneralIdRef { Id = 222 }, default); });
    }

    [Test]
    public async Task NextValue_RolloverContinous_OrderIncreases()
    {
        // Arrange
        _fakeClock.DateTime = new DateTimeOffset(2022, 10, 15, 17, 23, 52, TimeSpan.Zero);

        SequenceManagerRepository.Sequences.Add(new Sequence
        {
            Id = 555,
            Guid = Guid.NewGuid(),
            Increment = 1,
            Name = "Sequence name",
            Pattern = "Order [0] from {DD}-{MM}-{YYYY}",
            Rollover = Rollover.Continuous,
            Deleted = false,
            Seed = 0
        });

        // Act
        var sequenceNumbers = (await SequenceManager.NextValue(AuditUserDetails, new GeneralIdRef { Id = 555 }, 10, default)).ToList();

        // Assert
        Assert.That(sequenceNumbers, !Is.Null);
        Assert.That(sequenceNumbers[0], Is.EqualTo($"Order 1 from {_fakeClock.DateTime.Day}-{_fakeClock.DateTime.Month}-{_fakeClock.DateTime.Year}"));
        Assert.That(sequenceNumbers[1], Is.EqualTo($"Order 2 from {_fakeClock.DateTime.Day}-{_fakeClock.DateTime.Month}-{_fakeClock.DateTime.Year}"));
        Assert.That(sequenceNumbers[2], Is.EqualTo($"Order 3 from {_fakeClock.DateTime.Day}-{_fakeClock.DateTime.Month}-{_fakeClock.DateTime.Year}"));
        Assert.That(sequenceNumbers[3], Is.EqualTo($"Order 4 from {_fakeClock.DateTime.Day}-{_fakeClock.DateTime.Month}-{_fakeClock.DateTime.Year}"));
        Assert.That(sequenceNumbers[4], Is.EqualTo($"Order 5 from {_fakeClock.DateTime.Day}-{_fakeClock.DateTime.Month}-{_fakeClock.DateTime.Year}"));
        Assert.That(sequenceNumbers[5], Is.EqualTo($"Order 6 from {_fakeClock.DateTime.Day}-{_fakeClock.DateTime.Month}-{_fakeClock.DateTime.Year}"));
        Assert.That(sequenceNumbers[6], Is.EqualTo($"Order 7 from {_fakeClock.DateTime.Day}-{_fakeClock.DateTime.Month}-{_fakeClock.DateTime.Year}"));
        Assert.That(sequenceNumbers[7], Is.EqualTo($"Order 8 from {_fakeClock.DateTime.Day}-{_fakeClock.DateTime.Month}-{_fakeClock.DateTime.Year}"));
        Assert.That(sequenceNumbers[8], Is.EqualTo($"Order 9 from {_fakeClock.DateTime.Day}-{_fakeClock.DateTime.Month}-{_fakeClock.DateTime.Year}"));
        Assert.That(sequenceNumbers[9], Is.EqualTo($"Order 10 from {_fakeClock.DateTime.Day}-{_fakeClock.DateTime.Month}-{_fakeClock.DateTime.Year}"));
    }
}