using e_suite.API.Common.exceptions;
using e_suite.Database.Audit;
using e_suite.Database.Core.Tables.Glossaries;
using eSuite.Core.Miscellaneous;
using GlossariesManager.UnitTests.Helpers;
using NUnit.Framework;

namespace GlossariesManager.UnitTests;

[TestFixture]
public class DeleteGlossaryUnitTests : GlossariesManagerTestBase
{
    [SetUp]
    public override async Task Setup()
    {
        await base.Setup();
    }

    [Test]
    public void DeleteGlossaryItem_ItemDoesNotExist_ThrowsException()
    {
        //Arrange
        var auditUserDetails = new AuditUserDetails
        {
            UserDisplayName = "Testy McTester",
            UserId = 666
        };

        var generalIdRef = new GeneralIdRef
        {
            Guid = new Guid("{8A909C67-BC70-4FE2-8B5A-B5799B8E9E98}")
        };

        // Act & Assert
        Assert.ThrowsAsync<NotFoundException>( async() => await GlossariesManager.DeleteGlossaryItem(auditUserDetails, generalIdRef,default) );
    }

    [Test]
    public void DeleteGlossaryItem_ItemDoesAlreadyDeleted_ThrowsException()
    {
        //Arrange
        var auditUserDetails = new AuditUserDetails
        {
            UserDisplayName = "Testy McTester",
            UserId = 666
        };

        var generalIdRef = new GeneralIdRef
        {
            Guid = new Guid("{8A909C67-BC70-4FE2-8B5A-B5799B8E9E98}")
        };


        GlossariesManagerRepository.Glossaries.Add( new Glossary
        {
            Id = 1,
            Guid = generalIdRef.Guid.Value,
            Deleted = true
        });

        // Act & Assert
        Assert.ThrowsAsync<InvalidOperationException>(async () => await GlossariesManager.DeleteGlossaryItem(auditUserDetails, generalIdRef, default));
    }

    [Test]
    public async Task DeleteGlossaryItem_ItemFound_ItemIsMarkedDeleted()
    {
        //Arrange
        var auditUserDetails = new AuditUserDetails
        {
            UserDisplayName = "Testy McTester",
            UserId = 666
        };

        var generalIdRef = new GeneralIdRef
        {
            Guid = new Guid("{8A909C67-BC70-4FE2-8B5A-B5799B8E9E98}")
        };


        GlossariesManagerRepository.Glossaries.Add(new Glossary
        {
            Id = 1,
            Guid = generalIdRef.Guid.Value,
            Deleted = false
        });

        // Act
        await GlossariesManager.DeleteGlossaryItem(auditUserDetails, generalIdRef, default);

        //Assert
        Assert.That(GlossariesManagerRepository.Glossaries[0].Deleted, Is.True);
    }


    [Test]
    public async Task DeleteGlossaryItem_ItemHasChildren_ChildrenAreAlsoDeleted()
    {
        //Arrange
        var auditUserDetails = new AuditUserDetails
        {
            UserDisplayName = "Testy McTester",
            UserId = 666
        };

        var generalIdRef = new GeneralIdRef
        {
            Guid = new Guid("{8A909C67-BC70-4FE2-8B5A-B5799B8E9E98}")
        };


        var parentItem = new Glossary
        {
            Id = 1,
            Guid = generalIdRef.Guid.Value,
            Deleted = false
        };

        GlossariesManagerRepository.Glossaries.Add(parentItem);

        var unrelatedItem = new Glossary
        {
            Id = 2,
            Guid = new Guid("{FF497364-1AB6-4316-9CB7-B27D06B5A469}"),
            Deleted = false
        };

        GlossariesManagerRepository.Glossaries.Add(unrelatedItem);

        var childItem = new Glossary
        {
            Id = 3,
            Guid = new Guid("{902958C9-0D46-458D-98A1-ED9602706FEF}"),
            Deleted = false,
            ParentId = parentItem.Id,
            Parent = parentItem
        };

        GlossariesManagerRepository.Glossaries.Add(childItem);

        var grandChild = new Glossary
        {
            Id = 4,
            Guid = new Guid("{72CD4B61-1EDB-494E-91FE-3A40AEC3FEC3}"),
            Deleted = false,
            ParentId = childItem.Id,
            Parent = childItem
        };

        GlossariesManagerRepository.Glossaries.Add(grandChild);

        // Act
        await GlossariesManager.DeleteGlossaryItem(auditUserDetails, generalIdRef, default);

        //Assert
        Assert.That(GlossariesManagerRepository.Glossaries[0].Deleted, Is.True);
        Assert.That(GlossariesManagerRepository.Glossaries[1].Deleted, Is.False);
        Assert.That(GlossariesManagerRepository.Glossaries[2].Deleted, Is.True);
        Assert.That(GlossariesManagerRepository.Glossaries[3].Deleted, Is.True);
    }
}