using e_suite.API.Common;
using e_suite.API.Common.models;
using e_suite.Database.Audit;
using e_suite.Modules.UserManager.Facade;
using e_suite.Modules.UserManager.Services;
using e_suite.Nuget.PasswordHasher;
using e_suite.UnitTestCore;
using eSuite.Core.MailService;
using Google.Authenticator;
using Microsoft.AspNetCore.Identity;
using Moq;
using UserManager.UnitTests.Repository;

namespace UserManager.UnitTests.Helpers;

public class UserManagerTestBase<T> : TestBase
{
    protected Mock<IPasswordHasher<IPassword>> CustomPasswordHasherMock = null!;
    protected Mock<ITwoFactorAuthenticator> TwoFactorAuthenticatorMock = null!;
    protected Mock<IJwtService> JwtServiceMock = null!;
    protected Mock<IMailService> MailServiceMock = null!;
    protected Mock<IRandomNumberGenerator> RandomNumberGeneratorMock = null!;
    protected FakeUserManagerRepository UserManagerRepository = null!;
    protected FakeDomainRepository DomainRepository = null!;
    protected Mock<IPatchFactory> PatchFactoryMock = null!;
    protected Mock<IPatch<T>> PatchMock = null!;

    protected AuditUserDetails AuditUserDetails = null!;
    protected SetupCode SetupCode = null!;

    protected IUserManager UserManager = null!;

    public override async Task Setup()
    {
        await base.Setup();

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

        JwtServiceMock = new Mock<IJwtService>();
        CustomPasswordHasherMock = new Mock<IPasswordHasher<IPassword>>();
        TwoFactorAuthenticatorMock = new Mock<ITwoFactorAuthenticator>();

        SetupCode = new SetupCode();

        TwoFactorAuthenticatorMock.Setup(
            x => x.GenerateSetupCode(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>(),
                It.IsAny<int>())).Returns(SetupCode);

        MailServiceMock = new Mock<IMailService>();
        RandomNumberGeneratorMock = new Mock<IRandomNumberGenerator>();
        UserManagerRepository = new FakeUserManagerRepository(_fakeClock);
        DomainRepository = new FakeDomainRepository();
        
        PatchFactoryMock = new Mock<IPatchFactory>();
        PatchMock = new Mock<IPatch<T>>();
        PatchFactoryMock
            .Setup(f => f.Create(It.IsAny<T>()))
            .Returns(PatchMock.Object);

        UserManager = new e_suite.Modules.UserManager.UserManager(_configuration, CustomPasswordHasherMock.Object,
            TwoFactorAuthenticatorMock.Object, JwtServiceMock.Object, MailServiceMock.Object, RandomNumberGeneratorMock.Object, _fakeClock, UserManagerRepository, DomainRepository, PatchFactoryMock.Object);
    }
}