using DbConnectionLibrairie;
using Entities;
using ManagerInterfaces;
using Microsoft.EntityFrameworkCore;
using Model;
using OrderCriterias;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EntityManagers
{
    public class LobbyEntityManager(MyDbContext dbContext) : ILobbyManager<LobbyEntity>
    {
        MyDbContext dbContext = dbContext;

        public async Task<LobbyEntity> addLobby(LobbyEntity lobby)
        {
            var tmp = await dbContext.Lobbies.Where(l => l.Equals(lobby)).FirstOrDefaultAsync();
            if (tmp != null) // <=> he already exist
            {
                return tmp!;
            }
            dbContext.Lobbies.Add(lobby);
            await dbContext.SaveChangesAsync();
            return await dbContext.Lobbies.Where(l => l.Equals(lobby)).FirstAsync();
        }

        public async Task<(int nbPages, IEnumerable<LobbyEntity>? lobbies)> getLobbies(int nb, int count, LobbyOrderCriteria orderCriteria = LobbyOrderCriteria.ById)
        {
            int nbEl = getNbElements();
            if (nb < 0 || count < 0 || nb > nbEl / count) return await Task.FromResult<(int nbPages, IEnumerable<LobbyEntity>? lobbies)>((nbEl / count, null));
            var tmp = dbContext.Lobbies;
            switch (orderCriteria)
            {
                case LobbyOrderCriteria.ById:
                    tmp.OrderBy(l => l.Id);
                    break;
                case LobbyOrderCriteria.ByName:
                    tmp.OrderBy(l => l.Name);
                    break;
                case LobbyOrderCriteria.ByNbJoueur:
                    tmp.OrderBy(l => l.NbPlayers);
                    break;
            }
            return await Task.FromResult<(int nbPages, IEnumerable<LobbyEntity>? lobbies)>((nbEl / count, tmp.Skip((nb - 1) * count).Take(count)));
        }

        public async Task<LobbyEntity?> getLobby(uint id)
        {
            return await Task.FromResult<LobbyEntity?>(dbContext.Lobbies.Where(l => l.Id == id).FirstOrDefault());
        }

        public int getNbElements()
        {
            return dbContext.Lobbies.CountAsync().Result;
        }

        public async Task<LobbyEntity?> removeLobby(LobbyEntity lobby)
        {
            var tmp = dbContext.Lobbies.Where(a => a.Equals(lobby)).FirstOrDefaultAsync().Result;
            if (tmp == null) return await Task.FromResult<LobbyEntity?>(tmp);
            dbContext.Lobbies.Remove(tmp);
            await dbContext.SaveChangesAsync();
            return await Task.FromResult<LobbyEntity?>(tmp);
        }

        public async Task<LobbyEntity?> removeLobby(uint id)
        {
            var tmp = dbContext.Lobbies.Where(a => a.Id == id).FirstOrDefaultAsync().Result;
            if (tmp == null) return await Task.FromResult<LobbyEntity?>(tmp);
            dbContext.Lobbies.Remove(tmp);
            await dbContext.SaveChangesAsync();
            return await Task.FromResult<LobbyEntity?>(tmp);
        }
    }
}
