using Microsoft.EntityFrameworkCore;
using System.Security.Claims;
using Microsoft.AspNetCore.Http;
using Moq;
using ROLAC.API.Data;
using ROLAC.API.Data.Interceptors;
using ROLAC.API.DTOs.Ministry;
using ROLAC.API.Entities;
using ROLAC.API.Services;
using Xunit;

namespace ROLAC.API.Tests.Services;

public class MinistryServiceTests
{
    private static AppDbContext BuildDb()
    {
        var claims = new[] { new Claim(ClaimTypes.NameIdentifier, "test-user") };
        var ctx    = new DefaultHttpContext { User = new(new ClaimsIdentity(claims)) };
        var mock   = new Mock<IHttpContextAccessor>();
        mock.Setup(x => x.HttpContext).Returns(ctx);
        return new AppDbContext(new DbContextOptionsBuilder<AppDbContext>()
            .UseInMemoryDatabase(Guid.NewGuid().ToString())
            .AddInterceptors(new AuditSaveChangesInterceptor(new ROLAC.API.Services.Logging.CurrentUserAccessor(mock.Object))).Options);
    }

    [Fact]
    public async Task GetAllAsync_OrdersBySortOrder_AndExcludesInactive()
    {
        using var db = BuildDb();
        db.Ministries.AddRange(
            new Ministry { Name_en = "B", SortOrder = 2, IsActive = true },
            new Ministry { Name_en = "A", SortOrder = 1, IsActive = true },
            new Ministry { Name_en = "Z", SortOrder = 3, IsActive = false });
        await db.SaveChangesAsync();
        var svc = new MinistryService(db);

        var active = await svc.GetAllAsync(includeInactive: false);
        var all    = await svc.GetAllAsync(includeInactive: true);

        Assert.Equal(2, active.Count);
        Assert.Equal("A", active[0].Name_en);
        Assert.Equal(3, all.Count);
    }

    [Fact]
    public async Task Create_DefaultsFunctionalClassToProgram_AndUpdateChangesIt()
    {
        using var db = BuildDb();
        var svc = new MinistryService(db);
        var id  = await svc.CreateAsync(new CreateMinistryRequest { Name_en = "Worship" });

        var afterCreate = (await svc.GetAllAsync(true)).Single(m => m.Id == id);
        Assert.Equal("Program", afterCreate.DefaultFunctionalClass);

        await svc.UpdateAsync(id, new UpdateMinistryRequest { Name_en = "Worship", DefaultFunctionalClass = "ManagementGeneral" });
        var afterUpdate = (await svc.GetAllAsync(true)).Single(m => m.Id == id);
        Assert.Equal("ManagementGeneral", afterUpdate.DefaultFunctionalClass);
    }
}
