using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Abp.Domain.Repositories;
using Microsoft.EntityFrameworkCore;
using YGNT.QuestionLibrary.Core.Chapters.Cache;
using YGNT.QuestionLibrary.Core.KnowledgePoints.Cache;
using YGNT.QuestionLibrary.Core.Questions;

namespace YGNT.QuestionLibrary.Core.Papers.Domain
{
    public class PaperQuestionManager : IPaperQuestionManager
    {
        private readonly IRepository<PaperQuestion, long> _paperQuestionRepository;
        private readonly IRepository<Question, long> _questionRepository;
        private readonly IRepository<QuestionKnowledgePoint, long> _questionKnowledgePointRepository;
        private readonly IChapterCache _chapterCache;
        private readonly IKnowledgePointCache _knowledgePointCache;

        public PaperQuestionManager(IRepository<PaperQuestion, long> paperQuestionRepository, IRepository<Question, long> questionRepository, IChapterCache chapterCache, IRepository<QuestionKnowledgePoint, long> questionKnowledgePointRepository, IKnowledgePointCache knowledgePointCache)
        {
            _paperQuestionRepository = paperQuestionRepository;
            _questionRepository = questionRepository;
            _chapterCache = chapterCache;
            _questionKnowledgePointRepository = questionKnowledgePointRepository;
            _knowledgePointCache = knowledgePointCache;
        }

        /// <summary>
        /// 获取试卷下所有试题所包含的章节
        /// </summary>
        /// <param name="paper"></param>
        /// <returns></returns>
        public async Task<List<ChapterCacheItem>> GetPaperQuestionChapterAsync(Paper paper)
        {
            var chapters = await _questionRepository.GetAll()
               .Where(x => x.ChapterId.HasValue)
               .Where(x => GetPaperQuestionQueryable(paper).Contains(x.Id))
                .GroupBy(x => x.ChapterId)
                .Select(x => x.Key)
                .ToListAsync();
            var result = chapters.Select(x => _chapterCache.Get(x ?? default)).ToList();
            return result;
        }

        /// <summary>
        /// 获取试卷下所有试题所包含的知识点
        /// </summary>
        /// <param name="paper"></param>
        /// <returns></returns>
        public async Task<List<KnowledgePointCacheItem>> GetPaperQuestionKnowledgePointAsync(Paper paper)
        {
            var knowledgePoints = await _questionKnowledgePointRepository.GetAll()
                 .Where(x => GetPaperQuestionQueryable(paper).Contains(x.QuestionId))
                 .GroupBy(x => x.KnowledgePointId)
                 .Select(x => x.Key)
                 .ToListAsync();
            var result = knowledgePoints.Select(x => _knowledgePointCache.Get(x)).ToList();
            return result;
        }

        private IEnumerable<long> GetPaperQuestionQueryable(Paper paper)
        {
            var queryable = paper.PaperQuestions == null ?
                _paperQuestionRepository.GetAll().Where(x => x.PaperId == paper.Id).Select(x => x.QuestionId)
                : paper.PaperQuestions.Select(x => x.QuestionId);
            return queryable;
        }
    }
}