using AuditLog.UnitTests.Helpers;
using e_suite.Database.Audit.Tables.Audit;
using e_suite.Utilities.Pagination;
using NUnit.Framework;

namespace AuditLog.UnitTests;

[TestFixture]
public class GetAuditLogEntriesUnitTests : AuditLogTestBase
{

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

    [Test]
    public async Task GetAuditLogEntries_WithNoExtraFilters_ReturnsPagingStructure()
    {
        //Arrange
        var paging = new Paging();

        //Act
        var result = await AuditLog.GetAuditLogEntries(paging, null, false, default);

        //Assert
        Assert.That(result, Is.Not.Null);
        Assert.That(result.Page, Is.EqualTo(1));
        Assert.That(result.PageSize, Is.EqualTo(10));
        Assert.That(result.TotalPages, Is.EqualTo(0));
        Assert.That(result.Count, Is.EqualTo(0));
        Assert.That(result.Data.Count(), Is.EqualTo(0));
    }

    [Test]
    public async Task GetAuditLogEntries_WhenDataAvailable_ReturnItem()
    {
        //Arrange
        var auditEntry = new AuditEntry
        {
            AuditLogId = 1,
            DisplayName = "Test DisplayName",
            EntityName = "TestEntiryName",
            IsPrimary = true,
            Id = 1,
            PrimaryKey = "{{ \"id\": 1 }}",
            AuditLog = new AuditDetail
            {
                Id = 10,
                Comment = "Testing",
                DateTime = new DateTimeOffset(2023, 06, 15, 23, 56, 37, TimeSpan.Zero),
                UserDisplayName = "Testy McTester",
                UserId = 666,
                Fields = "",
                Type = "Add"
            }

        };

        AuditLogRepository.AuditEntries.Add(auditEntry);


        var paging = new Paging();

        //Act
        var result = await AuditLog.GetAuditLogEntries(paging, null, false, default);

        //Assert
        Assert.That(result, Is.Not.Null);
        Assert.That(result.Page, Is.EqualTo(1));
        Assert.That(result.PageSize, Is.EqualTo(10));
        Assert.That(result.TotalPages, Is.EqualTo(1));
        Assert.That(result.Count, Is.EqualTo(1));
        Assert.That(result.Data.Count(), Is.EqualTo(1));
    }

    [Test]
    public async Task GetAuditLogEntries_WhenlogEntry_DecodesToAuditParamsCorrectly()
    {
        //Arrange
        var auditEntry = new AuditEntry
        {
            AuditLogId = 1,
            DisplayName = "Test DisplayName",
            EntityName = "TestEntiryName",
            IsPrimary = true,
            Id = 1,
            PrimaryKey = "{{ \"id\": 1 }}",
            AuditLog = new AuditDetail
            {
                Id = 10,
                Comment = "Testing",
                DateTime = new DateTimeOffset(2023, 06, 15, 23, 56, 37, TimeSpan.Zero),
                UserDisplayName = "Testy McTester",
                UserId = 666,
                Fields = "",
                Type = "Add"
            }

        };

        AuditLogRepository.AuditEntries.Add(auditEntry);

        var logEntry = "ewogICJlbnRpdHlOYW1lIjoiVGVzdEVudGl0eSIsCiAgInByaW1hcnlLZXkiOiJ7aWQ6MTAxfSIKfQ==";

        var paging = new Paging();

        //Act
        var result = await AuditLog.GetAuditLogEntries(paging, logEntry, false, default);

        //Assert
        Assert.Multiple(() =>
        {
            Assert.That(AuditLogRepository.AuditParams, Is.Not.Null);
            Assert.That(AuditLogRepository.AuditParams!.EntityName, Is.EqualTo("TestEntity"));
            Assert.That(AuditLogRepository.AuditParams.PrimaryKey, Is.EqualTo("{id:101}"));
        });
    }

    [Test]
    public async Task GetAuditLogEntries_WhenAuditEntityHasDisplayName_DisplayNameIsSetIsEntityDisplayname()
    {
        //Arrange
        var auditEntry = new AuditEntry
        {
            AuditLogId = 1,
            DisplayName = "Test DisplayName",
            EntityName = "AuditLog.UnitTests.TestEntity",
            IsPrimary = true,
            Id = 1,
            PrimaryKey = "{{ \"id\": 1 }}",
            AuditLog = new AuditDetail
            {
                Id = 10,
                Comment = "Testing",
                DateTime = new DateTimeOffset(2023, 06, 15, 23, 56, 37, TimeSpan.Zero),
                UserDisplayName = "Testy McTester",
                UserId = 666,
                Fields = "",
                Type = "Add"
            }

        };

        AuditLogRepository.AuditEntries.Add(auditEntry);

        var logEntry = "ewogICJlbnRpdHlOYW1lIjoiVGVzdEVudGl0eSIsCiAgInByaW1hcnlLZXkiOiJ7aWQ6MTAxfSIKfQ==";

        var paging = new Paging();

        //Act
        var result = await AuditLog.GetAuditLogEntries(paging, logEntry, false, default);

        //Assert
        var actualResult = result.Data.FirstOrDefault();
        Assert.Multiple(() =>
        {
            Assert.That(actualResult, Is.Not.Null);
            Assert.That(actualResult!.EntityDisplayName, Is.EqualTo("Test display name"));
        });
    }

    [Test]
    public async Task GetAuditLogEntries_WhenAuditEntityHasNoDisplayName_DisplayNameIsSetIsEntityShortName()
    {
        //Arrange
        var auditEntry = new AuditEntry
        {
            AuditLogId = 1,
            DisplayName = "Test DisplayName",
            EntityName = "AuditLog.UnitTests.TestEntityTwo",
            IsPrimary = true,
            Id = 1,
            PrimaryKey = "{{ \"id\": 1 }}",
            AuditLog = new AuditDetail
            {
                Id = 10,
                Comment = "Testing",
                DateTime = new DateTimeOffset(2023, 06, 15, 23, 56, 37, TimeSpan.Zero),
                UserDisplayName = "Testy McTester",
                UserId = 666,
                Fields = "",
                Type = "Add"
            }

        };

        AuditLogRepository.AuditEntries.Add(auditEntry);

        var logEntry = "ewogICJlbnRpdHlOYW1lIjoiVGVzdEVudGl0eSIsCiAgInByaW1hcnlLZXkiOiJ7aWQ6MTAxfSIKfQ==";

        var paging = new Paging();

        //Act
        var result = await AuditLog.GetAuditLogEntries(paging, logEntry, false, default);

        //Assert
        var actualResult = result.Data.FirstOrDefault();
        Assert.Multiple(() =>
        {
            Assert.That(actualResult, Is.Not.Null);
            Assert.That(actualResult!.EntityDisplayName, Is.EqualTo("TestEntityTwo"));
        });
    }
}