using System.Data.Entity;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity.ModelConfiguration.Conventions;
using System;

namespace ResourcesManager.Models
{
    // You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
    public class ApplicationUser : IdentityUser
    {
        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            // Add custom user claims here
            return userIdentity;
        }

        public virtual ICollection<Resource> Resource { get; set; }

        public ApplicationUser()
        {
            Resource = new HashSet<Resource>();
        }
    }

    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>, IDataContext
    {
        public ApplicationDbContext() : base("DefaultConnection", throwIfV1Schema: false)
        {
            Database.SetInitializer<ApplicationDbContext>(new MyDbInitializer());
        }

        public DbSet<Reservation> Reservations { get; set; }
        public IDbSet<Resource> Resources { get; set; }
        public DbSet<Notification> Notifications { get; set; }
        public DbSet<StatisticModel> Statistic { get; set; }

        public static ApplicationDbContext Create()
        {
            return new ApplicationDbContext();
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

            modelBuilder.Entity<Resource>()
                .HasMany(c => c.Users).WithMany(i => i.Resource)
                .Map(t => t.MapLeftKey("UsersID")
                    .MapRightKey("ResourceID")
                    .ToTable("UserResource"));

            modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(l => l.UserId);
            modelBuilder.Entity<IdentityRole>().HasKey<string>(r => r.Id);
            modelBuilder.Entity<IdentityUserRole>().HasKey(r => new { r.RoleId, r.UserId });
        }

    }

    public class MyDbInitializer : CreateDatabaseIfNotExists<ApplicationDbContext>
    {
        protected override void Seed(ApplicationDbContext context)
        {
            string userRole = "User";
            string userName = "user{0}@email.hu";
            //Role létrehozása
            var roleStore = new RoleStore<IdentityRole>(context);
            var roleManager = new RoleManager<IdentityRole>(roleStore);
            var role = new IdentityRole
            {
                Name = userRole
            };
            roleManager.Create(role);
            
            var store = new UserStore<ApplicationUser>(context);
            var manager = new UserManager<ApplicationUser>(store);

            List<ApplicationUser> users = new List<ApplicationUser>();
            for (int i = 0; i < 10; i++)
            {
                //User létrehozása
                var userStore = new UserStore<ApplicationUser>(context);
                var userManager = new UserManager<ApplicationUser>(userStore);
                var user = new ApplicationUser
                {
                    UserName = string.Format(userName, i),
                    Email = string.Format(userName, i)
                };
                users.Add(user);
                userManager.Create(user, "P@ssword1");
                userManager.AddToRole(user.Id, userRole);
            }

            List<Resource> defaults = new List<Resource>();
            defaults.Add(new Resource() { Name = "Kihangosító", AssetTag = "ASDF654", Description = "A kedvenc kihangosítónk.", TimeLimit = 1, ImagePath = "~/App_Data/ResourceImages/bluetooth.jpg" });
            defaults.Add(new Resource() { Name = "Laptop", AssetTag = "GFDS5412", Description = "Ez egy szép piros laptop", TimeLimit = 24, ImagePath = "~/App_Data/ResourceImages/laptop.jpg" });
            defaults.Add(new Resource() { Name = "Piros Telefon", AssetTag = "ASDHGD5423", Description = "Ez a vészhívó telefon", ImagePath = "~/App_Data/ResourceImages/phone.jpg" });
            defaults.Add(new Resource() { Name = "Projektor", AssetTag = "BD435", Description = "A fekete projektor", TimeLimit = 4, ImagePath = "~/App_Data/ResourceImages/projector.jpg" });
            defaults.Add(new Resource() { Name = "Tárgyaló", AssetTag = "BDFS4353", Description = "A céges tárgyaló", TimeLimit = 12, ImagePath = "~/App_Data/ResourceImages/mt.jpg" });
            defaults.Add(new Resource() { Name = "Asus Laptop", AssetTag = "FSDAFAS423", Description = "Ez egy szép zöld laptop", TimeLimit = 72, ImagePath = "~/App_Data/ResourceImages/laptop.jpg" });
            defaults.Add(new Resource() { Name = "Lenovo Mobil", AssetTag = "FAS324", Description = "Ez egy mobil", ImagePath = "~/App_Data/ResourceImages/mobile.jpg" });
            defaults.Add(new Resource() { Name = "Benq Projektor", AssetTag = "BD434355", Description = "A szürke projektor", ImagePath = "~/App_Data/ResourceImages/projector.jpg" });
            defaults.Add(new Resource() { Name = "Dell Laptop", AssetTag = "HFG435", Description = "Ez egy szép laptop", ImagePath = "~/App_Data/ResourceImages/laptop.jpg" });
            defaults.Add(new Resource() { Name = "IPhone", AssetTag = "GDSG3453", Description = "Ez egy iPhone", ImagePath = "~/App_Data/ResourceImages/mobile.jpg" });
            defaults.Add(new Resource() { Name = "Epson Projektor", AssetTag = "BFR435", Description = "Az Epson projektor", TimeLimit = 8, ImagePath = "~/App_Data/ResourceImages/projector.jpg" });
            defaults.Add(new Resource() { Name = "Egyéb", AssetTag = "HFG345", Description = "Ez valami egyéb gyári képpel.", ImagePath = "~/App_Data/ResourceImages/DefaultResource.png" });
            foreach (var item in defaults)
            {
                context.Resources.Add(item);
            }

            Random r = new Random();
            for (int i = 0; i < 100; i++)
            {
                var date = DateTime.Now.AddMinutes(r.Next(0, 43800));
                var model = new Reservation()
                {
                    ResourceId = r.Next(0, defaults.Count - 1),
                    Resource = defaults[r.Next(0,defaults.Count-1)],
                    Begining = date,
                    End = date.AddHours(r.Next(0, 10)),
                    User = manager.FindByName(string.Format(userName, r.Next(0, users.Count-1))).Id
                };
                context.Reservations.Add(model);
            }

            for (int i = 0; i < 1000; i++)
            {
                var model = new StatisticModel()
                {
                    Id = i,
                    ResourceId = r.Next(0, defaults.Count - 1),
                    ReservationId = 1,
                    StatisticType = (StatisticType)r.Next(0, Enum.GetNames(typeof(StatisticType)).Length - 1),
                    DateTime = DateTime.Now.AddMinutes(r.Next(0, 43800) * (-1)),
                    UserId = manager.FindByName(string.Format(userName, r.Next(0, users.Count-1))).Id
                };
                context.Statistic.Add(model);
            }
            foreach (var resource in defaults)
            {
                foreach (var user in users)
                {
                    if (r.Next(0,10) >= 5 )
                    {
                        resource.Users.Add(user);
                    }
                }
            }

            base.Seed(context);
        }
    }

    public interface IDataContext
    {
        DbSet<Reservation> Reservations { get; set; }
        IDbSet<Resource> Resources { get; set; }
        DbSet<Notification> Notifications { get; set; }
        DbSet<StatisticModel> Statistic { get; set; }
    }
}