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

namespace YGNT.QuestionLibrary.Core.Chapters.Domain
{
    public class ChapterTreePathManager : IChapterTreePathManager
    {
        private readonly IRepository<ChapterTreePath, long> _treeRepository;
        private readonly IChapterCache _chapterCache;

        public ChapterTreePathManager(IRepository<ChapterTreePath, long> treeRepository, IChapterCache chapterCache)
        {
            _treeRepository = treeRepository;
            _chapterCache = chapterCache;
        }

        /// <summary>
        /// 获取章节名称路径
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<string> GetNamePathAsync(long id)
        {
            var ancestors = await GetAncestorAsync(id);
            var knowledgePointCacheItems = ancestors.Select(x => _chapterCache.Get(x.Ancestor)).ToList();
            return string.Join("/", knowledgePointCacheItems.Select(x => x.Name));
        }

        /// <summary>
        /// 创建章节路径
        /// </summary>
        /// <param name="chapter"></param>
        /// <returns></returns>
        public async Task<List<ChapterTreePath>> CreateTreePathAsync(Chapter chapter)
        {
            var treePath = new List<ChapterTreePath>()
            {
                new ChapterTreePath()
                {
                    Ancestor = chapter.Id,
                    Descendant = chapter.Id
                }
            };
            if (chapter.ParentId.HasValue)
            {
                var ancestor = await GetAncestorAsync(chapter.ParentId ?? default);
                treePath.AddRange(ancestor.Select(x => new ChapterTreePath()
                {
                    Ancestor = x.Ancestor,
                    Descendant = chapter.Id,
                    Depth = x.Depth + 1
                }));
            }
            foreach (var knowledgePointTreePath in treePath)
            {
                await _treeRepository.InsertAndGetIdAsync(knowledgePointTreePath);
            }
            return treePath;
        }

        /// <summary>
        /// 获取所有的祖先节点
        /// </summary>
        /// <param name="descendant"></param>
        /// <returns></returns>
        public async Task<List<ChapterTreePath>> GetAncestorAsync(long descendant)
        {
            return await _treeRepository.Query(x =>
                    x.Where(f => f.Descendant == descendant))
                .OrderByDescending(x => x.Depth)
                .ToListAsync();
        }

        /// <summary>
        /// 获取所有的后代节点(包括了自己)
        /// </summary>
        /// <param name="ancestor"></param>
        /// <returns></returns>
        public async Task<List<ChapterTreePath>> GetDescendantAsync(long ancestor)
        {
            return await _treeRepository.GetAll()
                .Where(x => x.Ancestor == ancestor)
                .OrderBy(x => x.Depth)
                .ToListAsync();
        }
    }
}