using e_suite.API.Common.exceptions;
using e_suite.API.Common.models;
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]
internal class EditGlossaryUnitTests : GlossariesManagerTestBase
{
    [SetUp]
    public override async Task Setup()
    {
        await base.Setup();
    }

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

        var glossaryItem = new NewGlossaryItem
        {
            Guid = Guid.NewGuid(),
            Name = "test root item",
        };

        await GlossariesManager.AddGlossaryItem(auditUserDetails, glossaryItem, default);

        var editedGlossaryItem = new EditGlossaryItem
        {
            Id = new GeneralIdRef
            {
                Guid = glossaryItem.Guid.Value
            },
            Name = "New root item",
        };

        // Act
        await GlossariesManager.UpdateGlossaryItem(auditUserDetails, editedGlossaryItem, default);

        var result = await GlossariesManager.GetGlossaryItem(auditUserDetails, new GeneralIdRef { Guid = glossaryItem.Guid }, default);

        // Assert
        Assert.That(result, Is.Not.Null);
        Assert.That(result!.Guid, Is.EqualTo(editedGlossaryItem.Id.Guid));
        Assert.That(result.Name, Is.EqualTo(editedGlossaryItem.Name));
    }

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

        var editedGlossaryItem = new EditGlossaryItem
        {
            Id = new GeneralIdRef
            { 
                Guid = Guid.NewGuid()
            },
            Name = "LithoSpec",
            ChildCustomFieldDefinition =
            [
                new()
                {
                    Guid = new Guid("{AA4D6C9C-EFE5-495B-993E-97C977EDF9D7}")
                }

            ]
        };

        // Act
        // Assert
        Assert.ThrowsAsync<ArgumentNullException>(async () => await GlossariesManager.UpdateGlossaryItem(auditUserDetails, editedGlossaryItem, default));
    }

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

        var glossaryGuid = Guid.NewGuid();

        GlossariesManagerRepository.Glossaries.Add(
            new Glossary
            {
                Guid = glossaryGuid,
                Id = 3,
                Name = "TestItem",
                Deleted = false,
                CustomFieldDefinitions = [],
                CustomFieldValues = [],
                ParentId = null
            });

        // Act
        var editedGlossaryItem = new EditGlossaryItem
        {
            Id = new GeneralIdRef
            {
                Id = 3,
                Guid = glossaryGuid
            },
            Name = "TestItem",
            ChildCustomFieldDefinition =
            [
                new()
                {
                    Id = 1,
                    Guid = new Guid("{AA4D6C9C-EFE5-495B-993E-97C977EDF9D7}")
                }
            ]
        };

        await GlossariesManager.UpdateGlossaryItem(auditUserDetails, editedGlossaryItem, default);

        //// Assert
        var result = await GlossariesManager.GetGlossaryItem(auditUserDetails, new GeneralIdRef { Guid = glossaryGuid }, default);

        Assert.That(result, Is.Not.Null);
        Assert.That(result!.ChildCustomFieldDefinition, Is.Not.Null);
    }

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

        var glossaryGuid = Guid.NewGuid();

        GlossariesManagerRepository.Glossaries.Add(
            new Glossary
            {
                Guid = glossaryGuid,
                Id = 3,
                Name = "TestItem",
                Deleted = false,
                CustomFieldDefinitions = [],
                CustomFieldValues = [],
                ParentId = null
            });

        // Act
        var editedGlossaryItem = new EditGlossaryItem
        {
            Id = new GeneralIdRef
            {
                Id = 3,
                Guid = glossaryGuid
            },
            Name = "TestItem",
            ChildCustomFieldDefinition =
            [
                new()
                {
                    Guid = new Guid("{0017142F-DE3C-4ED8-B8E9-230E6760B824}")
                }
            ]
        };

        //Act and Assert
        Assert.ThrowsAsync<NotFoundException>(
            () => GlossariesManager.UpdateGlossaryItem(auditUserDetails, editedGlossaryItem, default) );
    }
}