using System;
using System.Collections.Generic;
using System.Linq;
using InventoryTraker.Web.Core;
using InventoryTraker.Web.Data;
using InventoryTraker.Web.Identity;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;

namespace InventoryTraker.Web.Migrations
{
	public static class SeedData
	{
		public static void AddAdminRole()
		{
			using (var context = new AppDbContext())
				AddAdminRole(context);
		}

		private static void AddAdminRole(AppDbContext context)
		{
			var manager = new ApplicationRoleManager(new RoleStore<IdentityRole>(context));
			if (!manager.RoleExists(ApplicationRoleManager.AdminRoleName))
			{
				var result = manager.Create(new IdentityRole(ApplicationRoleManager.AdminRoleName));
			}

			// if no users are admins, make them all!
			var adminRole = manager.Roles.First(r => r.Name == ApplicationRoleManager.AdminRoleName);
			var userManager = new ApplicationUserManager(new UserStore<User>(context), null);
			var admins = userManager.Users.Where(u => u.Roles.Any(r => r.RoleId == adminRole.Id));
			if (!admins.Any())
			{
				foreach (var user in userManager.Users.ToList())
				{
					userManager.AddToRole(user.Id, ApplicationRoleManager.AdminRoleName);
				}
			}
		}

		public static void Init()
		{
			using (var context = new AppDbContext())
				Init(context);
		}

		public static void Init(AppDbContext context)
		{
			if (!context.Users.Any())
			{
				var manager = new ApplicationUserManager(new UserStore<User>(context), null);
				manager.Create(new User
				{
					Email = "james.kolpack@gmail.com",
					UserName = "James Kolpack",
				}, "hgBdFiJTK");

				manager.Create(new User
				{
					Email = "bbanegas@ethra.org",
					UserName = "Brandi Banegas",
				}, "3v9qxe");

				manager.Create(new User
				{
					Email = "ccecil@ethra.org",
					UserName = "Cyndie Cecil",
				}, "95kdsxa");

				manager.Create(new User
				{
					Email = "knorton@ethra.org",
					UserName = "Kay Norton",
				}, "rt9pmz1");
			}

			if (!context.Inventories.Any())
			{
				//AddInventory(context);

				context.SaveChanges();
			}
		}

		private static void AddInventory(AppDbContext context)
		{
			var r = new Random(1);
			var programs = new List<string> { "Aging", "Corrections", "Employment", "Family", "Health", "Housing" };
			var colors = new List<string> {"Red", "Purple", "Blue", "Yellow", "White"};

			for (var dd = DateTime.Today.AddYears(-4); dd < DateTime.Today.AddMonths(-2); dd = dd.AddMonths(3))
			{
				ExprireLossInventory(context, dd, r);
				// add some inventory
				for (int i = 0; i < r.Next(5,10); i++)
				{
					var addedDate = dd.AddDays(r.Next(-10, 10));
					var expiration = addedDate.AddMonths(r.Next(2, 48));
					var memo =
						r.Next(0, 3) > 0
							? colors.ElementAt(r.Next(0, colors.Count)) + " box"
							: string.Empty;
					var quantity = 1;
					var id = r.Next(10000000, 99999999).ToString();
					var program = programs.ElementAt(r.Next(0, programs.Count));

					var addedTransaction = new Transaction
					{
						TransactionType = TransactionType.Added,
						AddedQuantity = quantity,
						Memo = "Added",
						CurrentQuantity = quantity,
						TransactionDate = addedDate,
						Timestamp = addedDate
					};
					var inventory = new Inventory
					{
						ShredReadyDate = expiration,
						AddedDate = addedDate,
						Memo = memo,
						Quantity = quantity,
						ProgramName = program,
						Id = id,
						Transactions = new List<Transaction> {addedTransaction}
					};
					context.Inventories.Add(inventory);
				}
				dd = dd.AddDays(14);
				// expire/loss some inventory
				ExprireLossInventory(context, dd, r);

				dd = dd.AddDays(14);
				ExprireLossInventory(context, dd, r);
			}
		}

		private static void ExprireLossInventory(AppDbContext context, DateTime dd, Random r)
		{
			var availableInventories =
				context.Inventories.Local.Where(i => i.Quantity > 0).ToList();

			foreach (var inventory in availableInventories)
			{
				if (inventory.ShredReadyDate <= dd && r.Next(0, 4) > 0)
				{
					var expiredTransaction = new Transaction
					{
						TransactionType = TransactionType.Shreded,
						RemovedQuantity = inventory.Quantity,
						CurrentQuantity = 0,
						Inventory = inventory,
						Memo = $"Expired on {inventory.ShredReadyDate.ToShortDateString()}",
						TransactionDate = dd,
						Timestamp = dd
					};
					inventory.Quantity = expiredTransaction.CurrentQuantity;
					inventory.Transactions.Add(expiredTransaction);
				}
				else if (r.Next(0, 40) == 0)
				{
					var lossQty = 1;
					var lossTransaction = new Transaction
					{
						TransactionType = TransactionType.Loss,
						RemovedQuantity = lossQty,
						CurrentQuantity = inventory.Quantity - lossQty,
						Inventory = inventory,
						Memo = $"Missing",
						TransactionDate = dd,
						Timestamp = dd
					};
					inventory.Quantity = lossTransaction.CurrentQuantity;
					inventory.Transactions.Add(lossTransaction);
				}
			}
		}
	}
}