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 (trial.IsGlobalReading&&trial.IsReadingTaskViewInOrder)
            {

                ReadingPeriodSet? readingPeriodSet =await _readingPeriodSetRepository.FirstOrDefaultNoTrackingAsync(x => x.TrialId == trialId && x.IsGlobal);

                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,
                    };

                    await _readingPeriodSetRepository.AddAsync(readingPeriodSet);

                }

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


                await _readModuleRepository.DeleteFromQueryAsync(x => x.ReadingSetType == ReadingSetType.ImageReading && 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,
                });
              

                await _readModuleRepository.SaveChangesAsync();
            }
        }
    }


}