using DataManagers;
using DbConnectionLibrairie;
using DTOs;
using Entities;
using EntityManagers;
using ExtensionsClassLibrairie;
using ManagerInterfaces;
using Model;
using OrderCriterias;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ServiceManagers
{
    public class QuestionServiceManager(MyDbContext dbContext) : IQuestionManager<QuestionDto>
    {

        private QuestionDataManager manager = new QuestionDataManager(dbContext);

        public async Task<QuestionDto> addQuestion(QuestionDto question)
        {
            return await Task.FromResult<QuestionDto>((await manager.addQuestion(question.ToModel())).ToDto());
        }

        public async Task<IEnumerable<QuestionDto>> addQuestions(IEnumerable<QuestionDto> questions)
        {
            var tmp = new List<Question>();
            foreach (var question in questions)
            {
                tmp.Add(question.ToModel());
            }
            var res = await manager.addQuestions(tmp);
            var tmp2 = new List<QuestionDto>();
            foreach (var item in res)
            {
                tmp2.Add(item.ToDto());
            }
            return tmp2;
        }

        public int getNbElements()
        {
            return manager.getNbElements();
        }

        public async Task<QuestionDto?> getQuestion(uint id)
        {
            return await Task.FromResult<QuestionDto?>((await manager.getQuestion(id))?.ToDto());
        }

        public async Task<(int nbPages, IEnumerable<QuestionDto>? questions)> getQuestions(int nb, int count, QuestionOrderCriteria orderCriteria = QuestionOrderCriteria.ById)
        {
            List<QuestionDto>? tmp = new List<QuestionDto>();
            var res = await manager.getQuestions(nb, count, orderCriteria);
            if (res.questions == null) tmp = null;
            else
            {
                foreach (var item in res.questions)
                {
                    tmp.Add(item.ToDto());
                }
            }
            return await Task.FromResult<(int nbPages, IEnumerable<QuestionDto>? questions)>((res.nbPages, tmp));
        }

        public async Task<(int nbPages, IEnumerable<QuestionDto>? questions)?> getQuestionsByChapterAndDifficulty(int idChapter, int difficulty, int nb, int count, QuestionOrderCriteria orderCriteria = QuestionOrderCriteria.ById)
        {
            List<QuestionDto>? tmp = new List<QuestionDto>();
            var res = await manager.getQuestionsByChapterAndDifficulty(idChapter, difficulty, nb, count, orderCriteria);
            if (res == null) return await Task.FromResult<(int nbPages, IEnumerable<QuestionDto>? questions)?>(null);
            if (res.Value.questions == null) tmp = null;
            else
            {
                foreach (var item in res.Value.questions)
                {
                    tmp.Add(item.ToDto());
                }
            }
            return await Task.FromResult<(int nbPages, IEnumerable<QuestionDto>? questions)>((res.Value.nbPages, tmp));
        }

        public async Task<QuestionDto?> removeQuestion(QuestionDto question)
        {
            return (await manager.removeQuestion(question.ToModel()))?.ToDto();
        }

        public async Task<QuestionDto?> removeQuestion(uint id)
        {
            return (await manager.removeQuestion(id))?.ToDto();
        }

        public async Task<QuestionDto?> updateQuestion(uint id, QuestionDto question)
        {
            return (await manager.updateQuestion(id, question.ToModel()))?.ToDto();
        }

        public async Task<QuestionDto?> updateQuestionNbFalls(uint id)
        {
            return (await manager.updateQuestionNbFalls(id))?.ToDto();
        }
    }
}
