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

namespace YGNT.QuestionLibrary.Core.KnowledgePoints.Domain
{
    public class KnowledgePointTreePathManager : IKnowledgePointTreePathManager
    {
        private readonly IRepository<KnowledgePointTreePath, long> _treePathRepository;
        private readonly IKnowledgePointCache _knowledgePointCache;

        public KnowledgePointTreePathManager(IRepository<KnowledgePointTreePath, long> treePathRepository, IKnowledgePointCache knowledgePointCache)
        {
            _treePathRepository = treePathRepository;
            _knowledgePointCache = knowledgePointCache;
        }

        /// <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 => _knowledgePointCache.Get(x.Ancestor)).ToList();
            return string.Join("/", knowledgePointCacheItems.Select(x => x.Name));
        }

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

        /// <summary>
        /// 创建知识点路径
        /// </summary>
        /// <param name="knowledgePoint"></param>
        /// <returns></returns>
        public async Task<List<KnowledgePointTreePath>> CreateTreePathAsync(KnowledgePoint knowledgePoint)
        {
            var treePath = new List<KnowledgePointTreePath>()
            {
                new KnowledgePointTreePath()
                {
                    Ancestor = knowledgePoint.Id,
                    Descendant = knowledgePoint.Id
                }
            };
            if (knowledgePoint.ParentId.HasValue)
            {
                var ancestor = await GetAncestorAsync(knowledgePoint.ParentId ?? default);
                treePath.AddRange(ancestor.Select(x => new KnowledgePointTreePath()
                {
                    Ancestor = x.Ancestor,
                    Descendant = knowledgePoint.Id,
                    Depth = x.Depth + 1
                }));
            }
            foreach (var knowledgePointTreePath in treePath)
            {
                await _treePathRepository.InsertAndGetIdAsync(knowledgePointTreePath);
            }
            return treePath;
        }

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