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

namespace YGNT.QuestionLibrary.Core.Chapters.Domain
{
    public class ChapterManager : IChapterManager
    {
        private readonly ITextbookCache _textbookCache;
        private readonly IChapterCache _chapterCache;
        private readonly IRepository<Chapter, long> _chapterRepository;
        private readonly IRepository<Question, long> _questionRepository;


        public ChapterManager(ITextbookCache textbookCache, IRepository<Chapter, long> chapterRepository, IChapterCache chapterCache, IRepository<Question, long> questionRepository)
        {
            _textbookCache = textbookCache;
            _chapterRepository = chapterRepository;
            _chapterCache = chapterCache;
            _questionRepository = questionRepository;
        }

        /// <summary>
        /// 检查章节名称是否占用
        /// </summary>
        /// <param name="name"></param>
        /// <param name="textbookId"></param>
        /// <returns></returns>
        public async Task CheckNameAsync(string name, int textbookId)
        {
            var isExist = await _chapterRepository.AnyAsync(x => x.TextbookId == textbookId && x.Name == name);
            if (isExist)
                throw new UserFriendlyException($"章节名称:{name}已被占用.");
        }

        /// <summary>
        /// 创建章节
        /// </summary>
        /// <param name="name">章节名</param>
        /// <param name="textbookId">教材id</param>
        /// <param name="parentId">父章节名称</param>
        /// <param name="remark">备注</param>
        /// <returns></returns>
        public async Task<Chapter> CreateAsync(string name, int textbookId, long? parentId = null, string remark = null)
        {
            await CheckNameAsync(name, textbookId);
            var textbookCacheItem = await _textbookCache.GetAsync(textbookId);
            if (textbookCacheItem == null)
                throw new UserFriendlyException($"教材id{textbookId}不存在!");
            if (parentId.HasValue)
            {
                var parentChapterCacheItem = await _chapterCache.GetAsync((long)parentId);
                if (parentChapterCacheItem.TextbookId != textbookId)
                    throw new UserFriendlyException($"父章节所属教材和当前章节所属教材不匹配");
            }

            var lastSort = await _chapterRepository.Query(s => s
                .Where(x => x.ParentId == parentId)
                .Select(x => x.Sort)
                .OrderByDescending(x => x)
                .FirstOrDefaultAsync());
            var chapter = new Chapter()
            {
                Name = name,
                TextbookId = textbookId,
                DisciplineId = textbookCacheItem.DisciplineId,
                ParentId = parentId,
                Remark = remark,
                Sort = lastSort + 1
            };
            await _chapterRepository.InsertAndGetIdAsync(chapter);
            return chapter;
        }

        /// <summary>
        /// 排序
        /// </summary>
        /// <param name="chapter"></param>
        /// <param name="sortType"></param>
        /// <returns></returns>
        public async Task SortAsync(Chapter chapter, SortType sortType)
        {
            Chapter target = null;
            switch (sortType)
            {
                case SortType.上移:
                    target = await _chapterRepository.Query(s => s
                        .Where(x => x.Sort < chapter.Sort)
                        .OrderByDescending(x => x.Sort)
                        .FirstOrDefaultAsync());
                    break;
                case SortType.下移:
                    target = await _chapterRepository.Query(s => s
                        .Where(x => x.Sort > chapter.Sort)
                        .OrderBy(x => x.Sort)
                        .FirstOrDefaultAsync());
                    break;
            }
            if (target == null)
                return;
            var sort = target.Sort;
            target.Sort = target.Sort;
            chapter.Sort = sort;
            await _chapterRepository.UpdateAsync(chapter);
            await _chapterRepository.UpdateAsync(target);
        }

        /// <summary>
        /// 删除章节
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task DeleteAsync(long id)
        {
            var hasChild = await _chapterRepository.GetAll().AnyAsync(x => x.ParentId == id);
            if (hasChild) 
                throw new UserFriendlyException("禁止删除有子节点的章节");
            if (_questionRepository.GetAll().Any(o => o.ChapterId == id))
                throw new UserFriendlyException($"此章节中存在试题，不能删除.");
            await _chapterRepository.DeleteAsync(id);
        }
    }
}