using JobTrackerApi.Data;
using JobTrackerApi.Models;
using JobTrackerApi.Services;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Moq;

namespace JobTrackerApi.Tests.TestSupport;

public static class TestHostFactory
{
    // Keep the EF-backed controller tests on the same minimal setup so they fail for product
    // reasons, not because each file drifted into a slightly different fake host configuration.
    public static JobTrackerContext CreateInMemoryDb(string? userId = "user-1")
    {
        var options = new DbContextOptionsBuilder<JobTrackerContext>()
            .UseInMemoryDatabase(Guid.NewGuid().ToString())
            .Options;
        var currentUser = new Mock<ICurrentUserService>();
        currentUser.SetupGet(service => service.UserId).Returns(userId);
        return new JobTrackerContext(options, currentUser.Object);
    }

    public static Mock<UserManager<ApplicationUser>> CreateUserManager(ApplicationUser? lookupUser = null)
    {
        var store = new Mock<IUserStore<ApplicationUser>>();
        var manager = new Mock<UserManager<ApplicationUser>>(
            store.Object,
            Options.Create(new IdentityOptions()),
            new PasswordHasher<ApplicationUser>(),
            Array.Empty<IUserValidator<ApplicationUser>>(),
            Array.Empty<IPasswordValidator<ApplicationUser>>(),
            new UpperInvariantLookupNormalizer(),
            new IdentityErrorDescriber(),
            null!,
            new NullLogger<UserManager<ApplicationUser>>()
        );

        if (lookupUser is not null)
        {
            manager
                .Setup(x => x.FindByIdAsync(It.IsAny<string>()))
                .ReturnsAsync((string id) => lookupUser.Id == id ? lookupUser : null);
        }

        return manager;
    }
}
