using EntityFrameworkCore.Triggered;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using MassTransit;

namespace IRaCIS.Core.Application.Triggers
{
    /// <summary>
    ///  处理  访视   末次评估  会影响Subject 状态
    /// </summary>
    public class SubjectVisitFinalVisitTrigger : IAfterSaveTrigger<SubjectVisit>
    {
        private readonly IRepository<SubjectVisit> _subjectVisitRepository;
        private readonly IRepository<ReadingPeriodSet> _readingPeriodSetRepository;
        private readonly IRepository<ReadingPeriodPlan> _readingPeriodPlanRepository;
        private readonly IRepository<ReadModule> _readModuleRepository;
        private readonly IRepository<Subject> _subjectRepository;
        private readonly IRepository _repository;

        public SubjectVisitFinalVisitTrigger(IRepository<SubjectVisit> subjectVisitRepository,

            IRepository<ReadingPeriodSet> readingPeriodSetRepository,
               IRepository<ReadingPeriodPlan> readingPeriodPlanRepository,
                 IRepository<ReadModule> readModuleRepository,
            IRepository<Subject> subjectRepository, IRepository repository)
        {
            _subjectVisitRepository = subjectVisitRepository;
            this._readingPeriodSetRepository = readingPeriodSetRepository;
            this._readingPeriodPlanRepository = readingPeriodPlanRepository;
            this._readModuleRepository = readModuleRepository;
            _subjectRepository = subjectRepository;
            _repository = repository;
        }

        public async Task AfterSave(ITriggerContext<SubjectVisit> context, CancellationToken cancellationToken)
        {

            var subjectVisit = context.Entity;


            if (context.ChangeType == ChangeType.Modified)
            {

                // 修改了IsFinalVisit
                if (context.UnmodifiedEntity?.IsFinalVisit != subjectVisit.IsFinalVisit)
                {
                    if (subjectVisit.IsFinalVisit)
                    {
                        await VerifyDealFinalVisitAsync(subjectVisit);
                    }
                    else
                    {
                        //回退

                        await _subjectRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisit.SubjectId,
                            u => new Subject() { Status = SubjectStatus.OnVisit, FinalSubjectVisitId = null });

                        await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.SubjectId == subjectVisit.SubjectId && t.VisitExecuted == VisitExecutedEnum.Unavailable, u => new SubjectVisit() { VisitExecuted = VisitExecutedEnum.UnExecuted });

                        var readingPeriodSet =await _readingPeriodSetRepository.Where(x => x.TrialId == subjectVisit.TrialId && x.IsGlobal).FirstOrDefaultAsync();

                        if (readingPeriodSet != null)
                        {
                            await _readingPeriodPlanRepository.DeleteFromQueryAsync(x => x.ReadingPeriodSetId == readingPeriodSet.Id && x.SubjectVisitId == subjectVisit.Id);
                            await _readModuleRepository.DeleteFromQueryAsync(x => x.SubjectVisitId == subjectVisit.Id && x.ReadingPeriodSetId == readingPeriodSet.Id);

                            await _readModuleRepository.SaveChangesAsync();

                        }



                    }
                }

            }
            else if (context.ChangeType == ChangeType.Added && subjectVisit.IsFinalVisit)
            {
                await VerifyDealFinalVisitAsync(subjectVisit);
            }
        }

        private async Task VerifyDealFinalVisitAsync(SubjectVisit subjectVisit)
        {
            if (await _subjectVisitRepository.AnyAsync(t => t.SubjectId == subjectVisit.SubjectId && t.VisitNum > subjectVisit.VisitNum &&
                       (t.SubmitState == SubmitStateEnum.ToSubmit || t.SubmitState == SubmitStateEnum.Submitted)))
            {
                throw new BusinessValidationFailedException("该受试者已有后续访视已上传影像或已提交,当前访视不允许设置为末次访视。");
            }

            await _subjectRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisit.SubjectId,
                  u => new Subject() { Status = SubjectStatus.OutOfVisit, FinalSubjectVisitId = subjectVisit.Id });


            //末次访视后的  访视设置为不可用
            await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.SubjectId == subjectVisit.SubjectId && t.VisitNum > subjectVisit.VisitNum &&
            t.VisitExecuted == VisitExecutedEnum.UnExecuted, u => new SubjectVisit() { VisitExecuted = VisitExecutedEnum.Unavailable });


            var trialId = subjectVisit.TrialId;
            var subjectVisitId= subjectVisit.Id;
            // 是否全局阅片


            var trial = await _repository.Where<Trial>(x => x.Id == trialId).FirstNotNullAsync();

            

            if (!subjectVisit.IsBaseLine)
            {
                var criterionList = await _repository.Where<ReadingQuestionCriterionTrial>(x => x.TrialId == trialId && x.IsConfirm && x.IsGlobalReading && x.IsReadingTaskViewInOrder).ToListAsync();
                foreach (var item in criterionList)
                {
                    ReadingPeriodSet? readingPeriodSet = await _readingPeriodSetRepository.FirstOrDefaultNoTrackingAsync(x => x.TrialId == trialId && x.IsGlobal && x.TrialReadingCriterionId == item.Id);

                    if (readingPeriodSet == null)
                    {
                        readingPeriodSet = new ReadingPeriodSet()
                        {
                            Id = NewId.NextGuid(),
                            ReadingScope = ReadingScopeEnum.All,
                            ReadingSetType = ReadingSetType.ImageReading,
                            IsTakeEffect = ReadingPeriodStatus.TakeEffect,
                            ReadingPeriodName = "Global",
                            TrialId = trialId,
                            EffectOfTime = DateTime.Now,
                            IsGlobal = true,
                            TrialReadingCriterionId = item.Id,
                        };

                        await _readingPeriodSetRepository.AddAsync(readingPeriodSet);

                    }

                    await _readingPeriodPlanRepository.AddAsync(new ReadingPeriodPlan()
                    {
                        SubjectVisitId = subjectVisitId,
                        ReadingPeriodSetId = readingPeriodSet.Id,
                    });


                    await _readModuleRepository.DeleteFromQueryAsync(x => x.ReadingSetType == ReadingSetType.ImageReading && x.TrialReadingCriterionId == item.Id && x.SubjectVisitId == subjectVisitId, true);

                    await _readModuleRepository.AddAsync(new ReadModule()
                    {
                        ReadingPeriodSetId = readingPeriodSet.Id,
                        IsUrgent = subjectVisit.IsUrgent,
                        SubjectVisitId = subjectVisitId,
                        ReadingStatus = ReadingStatusEnum.TaskAllocate,
                        SubjectId = subjectVisit.SubjectId,
                        ModuleName = "Global",// 全局阅片
                        ReadingSetType = ReadingSetType.ImageReading,
                        ModuleType = ModuleTypeEnum.Global,
                        TrialId = subjectVisit.TrialId,
                        //VisitNum = subjectVisit.VisitNum,
                        TrialReadingCriterionId = item.Id,
                    });



                }
                await _readModuleRepository.SaveChangesAsync();
            }
       

           
        }
    }


}