using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Abp.Dependency;
using Abp.Domain.Repositories;
using Abp.Events.Bus.Entities;
using Abp.Events.Bus.Handlers;
using YGNT.QuestionLibrary.Core.KnowledgePoints.Domain;

namespace YGNT.QuestionLibrary.Core.KnowledgePoints.Event
{
    public class KnowledgePointAutoTreePathFill : ITransientDependency
        , IAsyncEventHandler<EntityCreatingEventData<KnowledgePoint>>
        , IAsyncEventHandler<EntityDeletingEventData<KnowledgePoint>>
    {
        private readonly IKnowledgePointTreePathManager _treePathManager;
        private readonly IRepository<KnowledgePointTreePath, long> _treePathRepository;

        public KnowledgePointAutoTreePathFill(IKnowledgePointTreePathManager treePathManager, IRepository<KnowledgePointTreePath, long> treePathRepository)
        {
            _treePathManager = treePathManager;
            _treePathRepository = treePathRepository;
        }

        /// <summary>
        /// 为新创建的知识点添加闭包路径
        /// </summary>
        /// <param name="eventData"></param>
        /// <returns></returns>
        public async Task HandleEventAsync(EntityCreatingEventData<KnowledgePoint> eventData)
        {
            var knowledgePoint = eventData.Entity;
            await _treePathManager.CreateTreePathAsync(knowledgePoint);
        }

        /// <summary>
        /// 清除删除的知识点路径
        /// </summary>
        /// <param name="eventData">Event data</param>
        public async Task HandleEventAsync(EntityDeletingEventData<KnowledgePoint> eventData)
        {
            var knowledgePoint = eventData.Entity;
            var ancestor = await _treePathManager.GetAncestorAsync(knowledgePoint.Id);
            var descendant = await _treePathManager.GetDescendantAsync(knowledgePoint.Id);
            foreach (var ancestorTreePath in ancestor)
            {
                await _treePathRepository.DeleteAsync(x =>
                    x.Ancestor == ancestorTreePath.Ancestor
                    && descendant.Select(s => s.Descendant).Contains(x.Descendant));
            }
        }
    }
}