using Microsoft.EntityFrameworkCore;
using Model;


namespace EFLol.DBDataManager
{
	public class EFDataManager : IDataManager
	{
		public IChampionsManager ChampionsMgr => new EFChampionManager();

		public ISkinsManager SkinsMgr => throw new NotImplementedException();

		public IRunesManager RunesMgr => throw new NotImplementedException();

		public IRunePagesManager RunePagesMgr => throw new NotImplementedException();
	}

	public class EFChampionManager : IChampionsManager
	{
		private MyDbContext _context;

		public EFChampionManager()
		{
			_context = new MyDbContext();
		}

		public async Task<Champion?> AddItem(Champion? item)
		{
			if (item == null)
			{
				throw new Exception("Item is null");
			}

			_context.Add(item.ChampionToEntity());
			_context.SaveChanges();
			return item;
		}


		public async Task<bool> DeleteItem(Champion? item)
		{
			if (item == null)
			{
				return false;
			}

			var champ = _context.Champions.Select(c => c == item.ChampionToEntity());

			if (champ.Count() < 1)
			{
				return false;
			}

			_context.Champions.Remove(item.ChampionToEntity());
			_context.SaveChanges();
			return true;
		}


		public async Task<Champion?> UpdateItem(Champion? oldItem, Champion? newItem)
		{
			if (oldItem != null && newItem != null)
			{
				var champEntity = await _context.Champions.FirstOrDefaultAsync(c => c.Name == oldItem.Name);
				if (champEntity == null)
				{
					throw new Exception("Champion not found in database");
				}
				champEntity.Bio = newItem.Bio;
				_context.SaveChanges();
				return champEntity.ChampionToPoco();
			}
			throw new Exception("Invalid input parameters");
		}


		public async Task<int> GetNbItems() => _context.Champions.Count();


		public async Task<IEnumerable<Champion?>> GetItems(int index, int count, string? orderingPropertyName = null,
			bool descending = false)
		{
			IEnumerable<Champion> champions = _context.Champions.Skip(index * count)
				.Take(count)
				.OrderBy(champions => orderingPropertyName)
				.Select(champions => champions.ChampionToPoco());
			return champions;
		}


		private Func<Champion, string, bool> filterByName = (champion, substring) =>
			champion.Name.IndexOf(substring, StringComparison.InvariantCultureIgnoreCase) >= 0;


		public Task<IEnumerable<Champion?>> GetItemsByName(string substring, int index, int count,
			string? orderingPropertyName = null, bool descending = false)
			=> _context.Champions.Select(champion => champion.ChampionToPoco())
				.GetItemsWithFilterAndOrdering(champ => filterByName(champ, substring), index, count,
					orderingPropertyName, descending);

		public Task<int> GetNbItemsByName(string substring)
		{
			throw new NotImplementedException();
		}


		public Task<int> GetNbItemsByCharacteristic(string charName)
		{
			throw new NotImplementedException();
		}

		public Task<IEnumerable<Champion?>> GetItemsByCharacteristic(string charName, int index, int count,
			string? orderingPropertyName = null,
			bool @descending = false)
		{
			throw new NotImplementedException();
		}

		public Task<int> GetNbItemsByClass(ChampionClass championClass)
		{
			throw new NotImplementedException();
		}

		public Task<IEnumerable<Champion?>> GetItemsByClass(ChampionClass championClass, int index, int count,
			string? orderingPropertyName = null,
			bool @descending = false)
		{
			throw new NotImplementedException();
		}

		public Task<int> GetNbItemsBySkill(Skill? skill)
		{
			throw new NotImplementedException();
		}

		public Task<IEnumerable<Champion?>> GetItemsBySkill(Skill? skill, int index, int count,
			string? orderingPropertyName = null, bool @descending = false)
		{
			throw new NotImplementedException();
		}

		public Task<int> GetNbItemsByRunePage(RunePage? runePage)
		{
			throw new NotImplementedException();
		}

		public Task<IEnumerable<Champion?>> GetItemsByRunePage(RunePage? runePage, int index, int count,
			string? orderingPropertyName = null,
			bool @descending = false)
		{
			throw new NotImplementedException();
		}

		public Task<int> GetNbItemsBySkill(string skill)
		{
			throw new NotImplementedException();
		}

		public Task<IEnumerable<Champion?>> GetItemsBySkill(string skill, int index, int count,
			string? orderingPropertyName = null, bool @descending = false)
		{
			throw new NotImplementedException();
		}
	}
}