using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Abp.Domain.Repositories;
using Abp.UI;
using Microsoft.EntityFrameworkCore;
using YGNT.Infrastructure.Extension;
using YGNT.QuestionLibrary.Core.Chapters.Cache;
using YGNT.QuestionLibrary.Core.Disciplines.Cache;
using YGNT.QuestionLibrary.Core.Models;
using YGNT.QuestionLibrary.Core.Questions;

namespace YGNT.QuestionLibrary.Core.Papers.Domain.AutoPaper
{
    /// <summary>
    /// 章节组卷
    /// </summary>
    public class AutoPaperByChapterManager : IAutoPaperManager
    {
        private readonly IRepository<Question, long> _questionRepository;
        private readonly IDisciplineCache _disciplineCache;
        private readonly IDisciplineQuestionTypeCache _disciplineQuestionTypeCache;
        private readonly IChapterCache _chapterCache;

        public AutoPaperByChapterManager(IRepository<Question, long> questionRepository, IDisciplineCache disciplineCache, IDisciplineQuestionTypeCache disciplineQuestionTypeCache, IChapterCache chapterCache)
        {
            _questionRepository = questionRepository;
            _disciplineCache = disciplineCache;
            _disciplineQuestionTypeCache = disciplineQuestionTypeCache;
            _chapterCache = chapterCache;
        }

        /// <summary>
        /// 添加随机抽选的试题
        /// </summary>
        /// <param name="paper">试卷</param>
        /// <param name="id">章节id</param>
        /// <param name="disciplineQuestionTypeId">学科下细分题型id</param>
        /// <param name="count">题量</param>
        /// <param name="score"></param>
        /// <param name="difficulty"></param>
        /// <returns>难度</returns>
        public async Task<List<PaperQuestion>> AddRandomQuestionAsync(Paper paper, long id,
            int disciplineQuestionTypeId, int count, float score, Difficulty difficulty)
        {
            var hasQuestion = paper.PaperQuestions.Select(x => x.QuestionId);
            var queryable = _questionRepository.GetAll()
                .Where(x => x.IsActive)
                .Where(x => !hasQuestion.Contains(x.Id))
                .Where(x => x.ChapterId == id)
                .Where(x => x.Difficulty == difficulty)
                .Where(x => x.DisciplineQuestionTypeId == disciplineQuestionTypeId);
            var residueCount = await queryable.CountAsync();
            if (residueCount < count)
            {
                var questionTypeCacheItem = await _disciplineQuestionTypeCache.GetAsync(disciplineQuestionTypeId);
                var disciplineCacheItem = await _disciplineCache.GetAsync(questionTypeCacheItem.DisciplineId);
                var chapterCacheItem = await _chapterCache.GetAsync(id);
                throw new UserFriendlyException($"学科《{disciplineCacheItem.Name}》下,章节:{chapterCacheItem.Name},题型:{questionTypeCacheItem.Name},难度{difficulty}中没有足够的题量进行组合,请修改对应的题量!");
            }


            var questions = await queryable.GetRandomListAsync(count);
            var paperQuestions = new List<PaperQuestion>();
            foreach (var question in questions)
            {
                var paperQuestion = new PaperQuestion()
                {
                    QuestionId = question.Id,
                    Question = question,
                    DisciplineQuestionTypeId = disciplineQuestionTypeId,
                    PaperId = paper.Id,
                    Paper = paper,
                    SingleScore = score
                };
                paperQuestions.Add(paperQuestion);
                paper.PaperQuestions.Add(paperQuestion);
            }
            return paperQuestions;
        }
    }
}