using EntityFramework.Mapper;
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace EntityFramework.Manager
{
    public partial class EFDataManager
    {
        public class ChampionsManager : IChampionsManager
        {
            private readonly EFDataManager parent;

            public ChampionsManager(EFDataManager parent)
            {
                this.parent = parent;
            }

            public async Task<Champion?> AddItem(Champion? item)
            {
                using(var context = new LoLDBContextWithStub())
                {
                    if (item != null)
                    {

                        context.Add(item.ToEntity());
                        context.SaveChanges();
                        return item;
                    }
                    else
                    {
                        throw new Exception();
                    }
                }
            }

            public async Task<bool> DeleteItem(Champion? item)
            {
                using (var context = new LoLDBContextWithStub())
                {
                    var champ = context.Champions.Select(c => c == item.ToEntity());
                        
                    if(champ.Count()<1)
                    {
                        return false;
                    }
                    context.Champions.Remove(item.ToEntity());
                    context.SaveChanges();
                    return true;
                    
                }
            }

            public async Task<IEnumerable<Champion?>> GetItems(int index, int count, string? orderingPropertyName = null, bool descending = false)
            {
                using(var context = new LoLDBContextWithStub() ) 
                {
                    var champ = context.Champions.ToArray();
                    if (descending == false)
                    {
                        return champ.ToList().Skip(index * count).Take(count).Select(c => c.ToChampion()).OrderBy(c => c.Name);
                    }
                    else
                    {
                        return champ.ToList().Skip(index * count).Take(count).Select(c => c.ToChampion()).OrderByDescending(c => c.Name);
                    }
                }
            }

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

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

            public async Task<IEnumerable<Champion?>> GetItemsByName(string substring, int index, int count, string? orderingPropertyName = null, bool descending = false)
            {
                using (var context = new LoLDBContextWithStub())
                {
                    var champ = context.Champions.Where(c => c.Name.Contains(substring)).AsEnumerable();
                    if (descending == false)
                    {
                    return champ.Select(c => c.ToChampion()).ToList().Skip(index * count).Take(count).OrderBy(c=> c.Name);

                    }
                    else
                    {
                        return champ.Select(c => c.ToChampion()).ToList().Skip(index*count).Take(count).OrderByDescending(c => c.Name);

                    }



                }
            }

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

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

            public async Task<IEnumerable<Champion?>> GetItemsBySkill(string skill, int index, int count, string? orderingPropertyName = null, bool descending = false)
            {
                using(var context = new LoLDBContextWithStub())
                {
                    var champ =  context.Champions.Where(c => c.Skills.Any(c => c.Name.Contains(skill)));
                    if (descending.Equals(false))
                    {
                        return champ.Select(c=> c.ToChampion()).ToList().Skip(index * count).Take(count).OrderBy(c => c.Name);

                    }
                    else
                    {
                        return champ.Select(c => c.ToChampion()).ToList().Skip(index * count).Take(count).OrderByDescending(c => c.Name);
                    }
                }
            }

            public async Task<int> GetNbItems()
            {
                using(var context = new LoLDBContextWithStub())
                {
                    return context.Champions.Count();
                }
            }

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

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

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

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

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

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

            public async Task<Champion?> UpdateItem(Champion? oldItem, Champion? newItem)
            {
                using(var context = new LoLDBContextWithStub())
                {
                    if (oldItem != null  && newItem != null)
                    {
                        var champ = context.Champions.Where(c => c == oldItem.ToEntity()).First();
                        champ = newItem.ToEntity();
                        context.SaveChanges();
                        return newItem;
                    }
                    else { throw new Exception(); }
                }
            }
        }
    }
}
