using e_suite.API.Common.exceptions;
using e_suite.API.Common.models;
using e_suite.Database.Audit;
using e_suite.Database.Core.Tables.Domain;
using e_suite.Database.Core.Tables.UserManager;
using e_suite.Modules.DomainManager.UnitTests.Helpers;
using eSuite.Core.Miscellaneous;
using NUnit.Framework;

namespace e_suite.Modules.DomainManager.UnitTests;

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

    [Test]
    public void EditDomainAsync_DomainNotFound_ThrowsNotFoundException()
    {
        //Arrange
        var auditUserDetails = new AuditUserDetails
        {
            UserId = 100,
            UserDisplayName = "Testy McTester",
            Comment = string.Empty
        };

        var editDomain = new EditDomain
        {
            Id = new GeneralIdRef
            {
                Guid = new Guid("55359f68-47f3-4b79-8bb2-e7a5e2f92cae")
            }
        };

        //Assert
        var actualResult = Assert.ThrowsAsync<NotFoundException>(async () =>
        {
            //Act
            await DomainManager.EditDomainAsync(auditUserDetails, editDomain, CancellationToken.None);
        });

        Assert.That(actualResult!.Message, Is.EqualTo("Domain not found"));
    }

    [Test]
    public async Task EditDomainAsync_DomainExists_DomainIsEditedProperly()
    {
        //Arrange
        var auditUserDetails = new AuditUserDetails
        {
            UserId = 100,
            UserDisplayName = "Testy McTester",
            Comment = string.Empty
        };

        var domain = new Domain
        {
            Guid = new Guid("8b7a3e33-9ab8-4c10-b0d5-8dbcade59569"),
            Id = 777,
            Name = "Inglish Teetchers"
        };

        DomainManagerRepository.Domains.Add(domain);

        var editDomain = new EditDomain
        {
            Id = new GeneralIdRef
            {
                Guid = domain.Guid
            },
            Name = "English Teachers"
        };

        //Act
        await DomainManager.EditDomainAsync(auditUserDetails, editDomain, CancellationToken.None);

        //Assert
        Assert.That(domain.Name, Is.EqualTo("English Teachers"));
    }

    [Test]
    public async Task EditDomainAsync_SsoProviderIsNullAndGetsSet_DomainIsEditedProperly()
    {
        //Arrange
        var ssoProviderId = 234;

        SoManagerRepository.SsoProviders.Add(new SsoProvider
        {
            Id = ssoProviderId
        });

        var auditUserDetails = new AuditUserDetails
        {
            UserId = 100,
            UserDisplayName = "Testy McTester",
            Comment = string.Empty
        };

        var domain = new Domain
        {
            Guid = new Guid("8b7a3e33-9ab8-4c10-b0d5-8dbcade59569"),
            Id = 777,
            Name = "English Teachers",
            SsoProviderId = null,
            SsoProvider = null
        };

        DomainManagerRepository.Domains.Add(domain);

        var editDomain = new EditDomain
        {
            Id = new GeneralIdRef
            {
                Guid = domain.Guid
            },
            Name = "English Teachers",
            SsoProviderId = new GeneralIdRef{Id = ssoProviderId}
        };

        //Act
        await DomainManager.EditDomainAsync(auditUserDetails, editDomain, CancellationToken.None);

        //Assert
        Assert.That(domain.SsoProviderId, Is.EqualTo(ssoProviderId));
        Assert.That(domain.SsoProvider, Is.Not.Null);
    }

    [Test]
    public async Task EditDomainAsync_SsoProviderIsChanged_DomainIsEditedProperly()
    {
        //Arrange
        var originalSsoProvider = new SsoProvider
        {
            Id = 234
        };

        var changedSsoProvider = new SsoProvider
        {
            Id = 345
        };

        SoManagerRepository.SsoProviders.Add(originalSsoProvider);
        SoManagerRepository.SsoProviders.Add(changedSsoProvider);

        var auditUserDetails = new AuditUserDetails
        {
            UserId = 100,
            UserDisplayName = "Testy McTester",
            Comment = string.Empty
        };

        var domain = new Domain
        {
            Guid = new Guid("8b7a3e33-9ab8-4c10-b0d5-8dbcade59569"),
            Id = 777,
            Name = "English Teachers",
            SsoProviderId = originalSsoProvider.Id,
            SsoProvider = null
        };

        DomainManagerRepository.Domains.Add(domain);

        var editDomain = new EditDomain
        {
            Id = new GeneralIdRef
            {
                Guid = domain.Guid
            },
            Name = "English Teachers",
            SsoProviderId = new GeneralIdRef { Id = changedSsoProvider.Id }
        };

        //Act
        await DomainManager.EditDomainAsync(auditUserDetails, editDomain, CancellationToken.None);

        //Assert
        Assert.That(domain.SsoProviderId, Is.EqualTo(changedSsoProvider.Id));
        Assert.That(domain.SsoProvider, Is.EqualTo(changedSsoProvider));
    }
}