using Baya.Domain.Entities.User;
using Baya.Infrastructure.Identity.Identity.Manager;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;

namespace Baya.Infrastructure.Identity.Identity.SeedDatabaseService;

public interface ISeedDataBase
{
    Task Seed();
}

public class SeedDataBase : ISeedDataBase
{
    private readonly AppUserManager _userManager;
    private readonly AppRoleManager _roleManager;
    private readonly IConfiguration _configuration;

    public SeedDataBase(AppUserManager userManager, AppRoleManager roleManager, IConfiguration configuration)
    {
        _userManager = userManager;
        _roleManager = roleManager;
        _configuration = configuration;
    }

    public async Task Seed()
    {
        // The full role vocabulary: public actor roles (customer/nurse — self-selectable) and the
        // admin sub-roles (internally provisioned only, never self-assignable).
        foreach (var roleName in RoleNames.All)
        {
            if (!_roleManager.Roles.AsNoTracking().Any(r => r.Name.Equals(roleName)))
            {
                await _roleManager.CreateAsync(new Role
                {
                    Name = roleName,
                });
            }
        }

        await SeedBootstrapAdminAsync();
    }

    // The bootstrap admin is config-driven, never a committed credential: it is created only when both
    // Seed:AdminUsername and Seed:AdminPassword are supplied (via user-secrets in Development, environment
    // variables in a deployment). With neither configured — the default for Testing and any fresh boot —
    // no admin account is created, so no well-known password ever lands in a real database. Day-to-day
    // admins reach the backoffice through the phone-OTP demo seeds (Development) or are provisioned
    // out-of-band; this account is a break-glass bootstrap only.
    private async Task SeedBootstrapAdminAsync()
    {
        var username = _configuration["Seed:AdminUsername"];
        var password = _configuration["Seed:AdminPassword"];

        if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
            return;

        if (_userManager.Users.AsNoTracking().Any(u => u.UserName.Equals(username)))
            return;

        var user = new User
        {
            UserName = username,
            Email = _configuration["Seed:AdminEmail"] ?? "admin@balinyaar.local",
            PhoneNumberConfirmed = true,
            IsActive = true
        };

        await _userManager.CreateAsync(user, password);
        await _userManager.AddToRoleAsync(user, "admin");
    }
}