using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Identity;
using pwt_0x01_ng.Models.Identity;

namespace pwt_0x01_ng.Models.Database
{
	public static class DBInit
	{

		public static void Init(DBContext dbContext)
		{
			dbContext.Database.EnsureCreated();
			if(dbContext.Carousel.Count() == 0){
				IList<Carousel> carousels = CarouselHelper.GenerateCarousel();
				foreach (var c in carousels)
				{
					dbContext.Carousel.Add(c);
				}
				dbContext.SaveChanges();
			}
			if(dbContext.Product.Count() == 0){
				IList<Product> products = ProductHelper.GenerateProduct();
				foreach (var p in products)
				{
					dbContext.Product.Add(p);
				}
				dbContext.SaveChanges();
			}
		}

		public static async Task EnsureRolesCreated(IServiceProvider sp){
			using (var services = sp.CreateScope()){
				RoleManager<Role> role_manager = services.ServiceProvider.GetRequiredService<RoleManager<Role>>();

				string[] rolespls = Enum.GetNames(typeof(Roles));
				foreach (var role in rolespls){
					Console.WriteLine(role + " => " + role.GetType());
					await role_manager.CreateAsync(new Role(role));
				}
			}
		}

		public static async Task EnsureManagerCreated(IServiceProvider sp){
			using (var services = sp.CreateScope()){
				UserManager<User> usr_manager = services.ServiceProvider.GetRequiredService<UserManager<User>>();

				User manager = new User(){
					UserName = "manager",
					Email = "manager@manager.com",
					Name = "manager",
					LastName = "",
					EmailConfirmed = true
				};

				var super_secure_password = "123"; /* TODO - rm this */
				User manager_in_db = await usr_manager.FindByNameAsync(manager.UserName);

				if (manager_in_db == null){
					IdentityResult ir = new IdentityResult();
					try {
						ir =  await usr_manager.CreateAsync(manager, super_secure_password);
					} catch (Exception e){
						Debug.WriteLine(e);
					}
					if(ir.Succeeded){
						string[] rolespls = Enum.GetNames(typeof(Roles));
						foreach (var role in rolespls){
							if(role != Roles.Admin.ToString()){
								await usr_manager.AddToRoleAsync(manager, role);
							}
						}
					} else if (ir.Errors != null && ir.Errors.Count() >0){
						foreach (var err in ir.Errors){
							Debug.WriteLine("Error during manager role creation" + err.Code + " => " + err.Description);
						}
					}
				}
			}
		}
		public static async Task EnsureAdminCreated(IServiceProvider sp){
			using (var services = sp.CreateScope()){
				UserManager<User> usr_manager = services.ServiceProvider.GetRequiredService<UserManager<User>>();

				User admin = new User(){
					UserName = "admin",
					Email = "admin@admin.com",
					Name = "admin",
					LastName = "",
					EmailConfirmed = true
				};

				var super_secure_password = "123"; /* TODO - rm this */
				User admin_in_db = await usr_manager.FindByNameAsync(admin.UserName);

				if (admin_in_db == null){
					IdentityResult ir = new IdentityResult();
					try {
						ir =  await usr_manager.CreateAsync(admin, super_secure_password);
					} catch (Exception e){
						Debug.WriteLine(e);
					}
					if(ir.Succeeded){
						string[] rolespls = Enum.GetNames(typeof(Roles));
						foreach (var role in rolespls){
							await usr_manager.AddToRoleAsync(admin, role);
						}
					} else if (ir.Errors != null && ir.Errors.Count() >0){
						foreach (var err in ir.Errors){
							Debug.WriteLine("Error during admin role creation" + err.Code + " => " + err.Description);
						}
					}
				}
			}
		}
	}
}