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

namespace UserManager.UnitTests.UserManager;

[TestFixture]
public class DeactivateUserUnitTests : UserManagerTestBase<object>
{
    [SetUp]
    public override async Task Setup()
    {
        await base.Setup();
    }

    [Test]
    public async Task DeactivateUser_ActiveUser_DeactivatesUser()
    {
        //Arrange
        var existingUser = new User
        {
            Id = 7,
            Email = "deactivate.me@sun-strategy.com",
            Active = true,
        };

        await UserManagerRepository.AddUser(AuditUserDetails, existingUser, default);

        //Act
        await UserManager.DeactivateUser(AuditUserDetails, existingUser.Email);

        //Assert
        var user = UserManagerRepository.Users.Single(x => x.Email == existingUser.Email);
        Assert.That(user.Active, Is.False);
    }

    [Test]
    public async Task DeactivateUser_ActiveUser_DeleteUserSelf()
    {
        //Arrange
        var existingUser = new User
        {
            Id = 7,
            Email = "deactivate.me@sun-strategy.com",
            Active = true,
        };

        await UserManagerRepository.AddUser(AuditUserDetails, existingUser, default);

        AuditUserDetails = new AuditUserDetails
        {
            UserId = 7,
            UserDisplayName = "Testing User",
            Comment = "Test comment"
        };

        //Act & Assert
        Assert.ThrowsAsync<InvalidOperationException>(async () => { await UserManager.DeactivateUser(AuditUserDetails, existingUser.Email); });
    }

    [Test]
    public async Task DeactivateUser_DeactivatedUser_ThrowsArgumentException()
    {
        //Arrange
        var existingUser = new User
        {
            Id = 7,
            Email = "deactivate.me@sun-strategy.com",
            Active = false,
        };
        await UserManagerRepository.AddUser(AuditUserDetails, existingUser, default);

        //Act & Assert
        Assert.ThrowsAsync<InvalidOperationException>(async () => { await UserManager.DeactivateUser(AuditUserDetails, existingUser.Email); });
    }

    [Test]
    public Task DeactivateUser_UserNotFound_ThrowsEmailNotFoundException()
    {
        //Arrange
        var existingUser = new User
        {
            Id = 7,
            Email = "doesnot.exist@sun-strategy.com",
            Active = false,
        };

        //Act & Assert
        Assert.ThrowsAsync<NotFoundException>(async () => { await UserManager.DeactivateUser(AuditUserDetails, existingUser.Email); });
        return Task.CompletedTask;
    }

    [Test]
    public async Task DeactivateUser_GeneralIDRefVersionActiveUser_DeactivatesUser()
    {
        //Arrange
        var existingUser = new User
        {
            Id = 7,
            Email = "deactivate.me@sun-strategy.com",
            Active = true,
        };

        await UserManagerRepository.AddUser(AuditUserDetails, existingUser, default);

        var generalIdRef = new GeneralIdRef
        {
            Id = 7
        };

        //Act
        await UserManager.DeactivateUser(AuditUserDetails, generalIdRef, CancellationToken.None);

        //Assert
        var user = UserManagerRepository.Users.Single(x => x.Email == existingUser.Email);
        Assert.That(user.Active, Is.False);
    }

    [Test]
    public async Task DeactivateUser_GeneralIDRefVersionDeactivatedUser_ThrowsArgumentException()
    {
        //Arrange
        var existingUser = new User
        {
            Id = 7,
            Email = "deactivate.me@sun-strategy.com",
            Active = false,
        };
        await UserManagerRepository.AddUser(AuditUserDetails, existingUser, default);

        var generalIdRef = new GeneralIdRef
        {
            Id = 7
        };

        //Act & Assert
        Assert.ThrowsAsync<InvalidOperationException>(async () => { await UserManager.DeactivateUser(AuditUserDetails, generalIdRef, CancellationToken.None); });
    }

    [Test]
    public Task DeactivateUser_GeneralIDRefVersionUserNotFound_ThrowsEmailNotFoundException()
    {
        //Arrange
        var existingUser = new User
        {
            Id = 7,
            Email = "doesnot.exist@sun-strategy.com",
            Active = false,
        };

        var generalIdRef = new GeneralIdRef
        {
            Id = 7
        };

        //Act & Assert
        Assert.ThrowsAsync<NotFoundException>(async () => { await UserManager.DeactivateUser(AuditUserDetails, generalIdRef, CancellationToken.None); });
        return Task.CompletedTask;
    }
}