using Microsoft.EntityFrameworkCore;

namespace NetinaShop.Repository.Services;


public class DbInitializerService : IDbInitializerService
{
    private readonly IOptionsSnapshot<SiteSettings> _adminUserSeedOptions;
    private readonly ApplicationContext _context;
    private readonly ILogger<DbInitializerService> _logger;
    private readonly RoleManager<ApplicationRole> _roleManager;
    private readonly UserManager<ApplicationUser> _userManager;

    public DbInitializerService(
        ApplicationContext context,
        RoleManager<ApplicationRole> roleManager,
        UserManager<ApplicationUser> userManager,
        IOptionsSnapshot<SiteSettings> adminUserSeedOptions,
        ILogger<DbInitializerService> logger)
    {
        _context = context;
        _roleManager = roleManager;
        _userManager = userManager;
        _adminUserSeedOptions = adminUserSeedOptions;
        _logger = logger;
    }

    public void Initialize()
    {
        try
        {
            _context.Database.Migrate();
            _logger.LogInformation("Migration SUCCESS !!!!");
        }
        catch (Exception e)
        {
            _logger.LogError(e, e.Message);
        }
    }

    public async Task SeedDate(bool force = false)
    {
        try
        {
            await SeedRoles();
            var seedAdmin = _adminUserSeedOptions.Value.UserSetting;
            var user = await _userManager.FindByNameAsync(seedAdmin.Username);
            if (user == null)
            {
                var adminUser = new ApplicationUser
                {
                    UserName = seedAdmin.Username,
                    Email = seedAdmin.Email,
                    EmailConfirmed = true,
                    LockoutEnabled = true,
                    FirstName = seedAdmin.FirstName,
                    LastName = seedAdmin.LastName,
                    Gender = Gender.Male,
                    PhoneNumberConfirmed = true,
                    PhoneNumber = seedAdmin.Phone,
                    BirthDate = DateTime.Now.AddYears(-23)
                };
                var adminUserResult = await _userManager.CreateAsync(adminUser, seedAdmin.Password);
                if (adminUserResult.Succeeded) await _userManager.AddToRoleAsync(adminUser, seedAdmin.RoleName);
            }

            var mahanUser = await _userManager.FindByNameAsync("09128387004");
            if (mahanUser == null)
            {
                mahanUser = new ApplicationUser
                {
                    UserName = "09128387004",
                    Email = "mahanmasiha6@gmail.com",
                    EmailConfirmed = true,
                    LockoutEnabled = true,
                    FirstName = "ماهان",
                    LastName = "",
                    Gender = Gender.Male,
                    PhoneNumberConfirmed = true,
                    PhoneNumber = "09128387004",
                    BirthDate = DateTime.Now.AddYears(-23)
                };
                var adminUserResult = await _userManager.CreateAsync(mahanUser, seedAdmin.Password);
                if (adminUserResult.Succeeded) await _userManager.AddToRoleAsync(mahanUser, "Manager");
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
    }

    public async Task SeedRoles()
    {
        var seedAdmin = _adminUserSeedOptions.Value.UserSetting;
        var rootRole = await _roleManager.FindByNameAsync(seedAdmin.RoleName);

        if (rootRole == null)
        {
            rootRole = new ApplicationRole
            {
                Name = seedAdmin.RoleName,
                EnglishName = seedAdmin.RoleName,
                Description = "root admin role"
            };
            var adminRoleResult = await _roleManager.CreateAsync(rootRole);
            foreach (var claim in ApplicationClaims.AllClaims)
                await _roleManager.AddClaimAsync(rootRole, claim);
        }

        var managerRole = await _roleManager.FindByNameAsync("Manager");

        if (managerRole == null)
        {
            managerRole = new ApplicationRole
            {
                Name = "Manager",
                EnglishName = "Manager",
                PersianName = "مدیریتـــ",
                Description = "admin role"
            };
            var adminRoleResult = await _roleManager.CreateAsync(managerRole);
            foreach (var claim in ApplicationClaims.AllClaims)
                await _roleManager.AddClaimAsync(managerRole, claim);
        }

        var customerRole = await _roleManager.FindByNameAsync("Customer");
        if (customerRole == null)
        {
            customerRole = new ApplicationRole
            {
                Name = "Customer",
                PersianName = "مشتری",
                EnglishName = "Customer",

            };
            var customerRoleResult = await _roleManager.CreateAsync(customerRole);
            foreach (var claim in ApplicationClaims.CustomerClaims)
                await _roleManager.AddClaimAsync(customerRole, claim);
        }
    }
}