using e_suite.API.Common.exceptions;
using e_suite.Database.Core.Models;
using e_suite.Database.Core.Tables.UserManager;
using NUnit.Framework;
using UserManager.UnitTests.Helpers;

namespace UserManager.UnitTests.UserManager;

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

    [Test]
    public Task GetCurrentEmailActionUrl_UserNotFound_ThrowsNotFoundException()
    {
        //Arrange
        var email = "missing@lost.island";

        //Act & Assert
        var exception = Assert.ThrowsAsync<NotFoundException>(async () =>
        {
            await UserManager.GetCurrentEmailActionUrl(email, EmailUserActionType.ConfirmEmailAddress,
                CancellationToken.None);
        });

        Assert.That(exception?.Message, Is.EqualTo("User not found"));
        return Task.CompletedTask;
    }

    [Test]
    public async Task GetCurrentEmailActionUrl_EmailActionNotExists_ThrowsNotFoundException()
    {
        //Arrange
        var existingUser = new User
        {
            Id = 9,
            Email = "testuser@sun-strategy.com",
            EmailConfirmed = true,
            Active = true,
            FirstName = "Test",
            LastName = "User"
        };

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

        //Act & Assert
        var exception = Assert.ThrowsAsync<NotFoundException>(async () =>
        {
            await UserManager.GetCurrentEmailActionUrl(existingUser.Email, EmailUserActionType.ConfirmEmailAddress,
                CancellationToken.None);
        });

        Assert.That(exception?.Message, Is.EqualTo("Email action not found"));
    }

    [Test]
    public async Task GetCurrentEmailActionUrl_EmailActionHasExpired_ThrowsNotFoundException()
    {
        //Arrange
        var existingUser = new User
        {
            Id = 9,
            Email = "testuser@sun-strategy.com",
            EmailConfirmed = true,
            Active = true,
            FirstName = "Test",
            LastName = "User"
        };

        _fakeClock.DateTime = new DateTimeOffset(2024, 01, 14, 1, 2, 3, TimeSpan.Zero);

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

        var emailUserAction = new EmailUserAction()
        {
            UserId = existingUser.Id,
            EmailActionType = EmailUserActionType.ConfirmEmailAddress,
            Created = new DateTimeOffset(2024, 01, 1, 1, 2, 3, TimeSpan.Zero),
            Expires = new DateTimeOffset(2024, 01, 3, 1, 2, 3, TimeSpan.Zero),
        };

        UserManagerRepository.EmailUserActions.Add(emailUserAction);


        //Act & Assert
        var exception = Assert.ThrowsAsync<NotFoundException>(async () =>
        {
            await UserManager.GetCurrentEmailActionUrl(existingUser.Email, EmailUserActionType.ConfirmEmailAddress,
                CancellationToken.None);
        });

        Assert.That(exception?.Message, Is.EqualTo("Email action not found"));
    }

    [Test]
    public async Task GetCurrentEmailActionUrl_EmailActionInDate_ThrowsNotFoundException()
    {
        //Arrange
        var expectedResult =
            "https://esuite.test/emailuseraction/eyJlbWFpbCI6InRlc3R1c2VyQHN1bi1zdHJhdGVneS5jb20iLCJ0b2tlbiI6IjAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMCIsInBhc3N3b3JkIjoiIiwiZW1haWxBY3Rpb25UeXBlIjoyfQ==";

        var existingUser = new User
        {
            Id = 9,
            Email = "testuser@sun-strategy.com",
            EmailConfirmed = true,
            Active = true,
            FirstName = "Test",
            LastName = "User"
        };

        _fakeClock.DateTime = new DateTimeOffset(2024, 01, 14, 1, 2, 3, TimeSpan.Zero);

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

        var emailUserAction = new EmailUserAction()
        {
            UserId = existingUser.Id,
            EmailActionType = EmailUserActionType.ConfirmEmailAddress,
            Created = new DateTimeOffset(2024, 01, 14, 1, 2, 3, TimeSpan.Zero),
            Expires = new DateTimeOffset(2024, 01, 16, 1, 2, 3, TimeSpan.Zero),
        };

        UserManagerRepository.EmailUserActions.Add(emailUserAction);
        
        //Act & Assert
        var result = await UserManager.GetCurrentEmailActionUrl(existingUser.Email, EmailUserActionType.ConfirmEmailAddress, CancellationToken.None);
        Assert.That(result, Is.EqualTo(expectedResult));
    }
}