namespace CSR.Infrastructure.Data;

using CSR.Infrastructure.Persistence;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

public static class DbInitializer
{
  public static async Task SeedDatabase(IServiceProvider serviceProvider)
  {
    using var scope = serviceProvider.CreateScope();
    var services = scope.ServiceProvider;
    var context = services.GetRequiredService<CSRDbContext>();
    var config = services.GetRequiredService<IConfiguration>();
    var userService = services.GetRequiredService<Application.Interfaces.IUserService>();
    var roleRepository = services.GetRequiredService<Application.Interfaces.IRoleRepository>();
    var userRepository = services.GetRequiredService<Application.Interfaces.IUserRepository>();

    // --- create roles if not exists --- //

    if (!await context.Roles.AnyAsync())
    {
      await roleRepository.AddAsync(Domain.Entities.Role.Admin);
      await roleRepository.AddAsync(Domain.Entities.Role.User);
    }

    // --- create admin user if not exists --- //

    var adminUsername = config["Admin:Username"] ?? "admin";
    var adminEmail = config["Admin:Email"] ?? "admin@example.com";
    var adminPassword = config["Admin:Password"] ?? "Admin123";

    var admins = await userRepository.GetAllByRoleIdAsync(Domain.Entities.Role.Admin.Id);
    if (admins == null || !admins.Any())
    {
      var result = await userService.RegisterNewUser(adminUsername, adminEmail, adminPassword);
      if (result.User == null)
      {
        Console.WriteLine($"Error creating admin user: {string.Join(", ", result.Errors!)}");
      }
      else
      {
        var adminEntity = await context.Users
          .Include(u => u.Role)
          .SingleAsync(u => u.Id == result.User.Id);

        adminEntity.RoleId = Domain.Entities.Role.Admin.Id;
        context.Users.Update(adminEntity);
        await context.SaveChangesAsync();
        Console.WriteLine("Admin user created successfully.");
      }
    }
  }
}
