using EntityFrameworkCore.Triggered;
using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using MassTransit;

namespace IRaCIS.Core.Application.Triggers
{
    /// <summary>
    ///  处理  访视   末次评估  会影响Subject 状态
    /// </summary>
    public class SubjectVisitFinalVisitTrigger :BaseService, 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<VisitTask> _visitTaskRepository;
        private readonly IVisitTaskHelpeService _ivisitTaskHelpeService;
        private readonly IRepository _repository;

        public SubjectVisitFinalVisitTrigger(IRepository<SubjectVisit> subjectVisitRepository,

            IRepository<ReadingPeriodSet> readingPeriodSetRepository,
               IRepository<ReadingPeriodPlan> readingPeriodPlanRepository,
                IRepository<VisitTask> visitTaskRepository,
                IVisitTaskHelpeService visitTaskHelpeService,
                 IRepository<ReadModule> readModuleRepository,
            IRepository<Subject> subjectRepository, IRepository repository)
        {
            _subjectVisitRepository = subjectVisitRepository;
            this._readingPeriodSetRepository = readingPeriodSetRepository;
            this._visitTaskRepository = visitTaskRepository;
            this._ivisitTaskHelpeService = visitTaskHelpeService;
            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);

                        await DealGenerateReadModuleAndSubjectVisit(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 });


                    }
                }

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

                await DealGenerateReadModuleAndSubjectVisit(subjectVisit);
            }
        }

        /// <summary>
        /// 处理生成阅片期 以及后续访视状态
        /// </summary>
        /// <param name="subjectVisit"></param>
        /// <returns></returns>
        private async Task DealGenerateReadModuleAndSubjectVisit(SubjectVisit subjectVisit)
        {

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


            #region 末次访视生成阅片器和任务  


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


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


            if (!subjectVisit.IsBaseLine && subjectVisit.SubmitState == SubmitStateEnum.Submitted)
            {
                var criterionList = await _repository.Where<ReadingQuestionCriterionTrial>(x => x.TrialId == trialId && x.ReadingInfoSignTime != null && x.IsConfirm && x.IsReadingPeriod && x.IsReadingTaskViewInOrder).ToListAsync();
                foreach (var item in criterionList)
                {

                    var readModule = await _readModuleRepository.Where(x => x.ReadingSetType == ReadingSetType.ImageReading && x.TrialReadingCriterionId == item.Id && x.SubjectVisitId == subjectVisitId).FirstOrDefaultAsync();

                    if (readModule == null)

                    {

                        ReadModule newReadModule = new ReadModule()
                        {
                            //ReadingPeriodSetId = readingPeriodSet.Id,
                            Id = NewId.NextGuid(),
                            IsUrgent = subjectVisit.IsUrgent,
                            SubjectVisitId = subjectVisitId,
                            ReadingStatus = ReadingStatusEnum.TaskAllocate,
                            SubjectId = subjectVisit.SubjectId,
                            ModuleName = $"G-{subjectVisit.VisitName}",// 全局阅片
                            ReadingSetType = ReadingSetType.ImageReading,
                            ModuleType = ModuleTypeEnum.Global,
                            TrialId = subjectVisit.TrialId,
                            //VisitNum = subjectVisit.VisitNum,
                            TrialReadingCriterionId = item.Id,
                        };

                        readModule = await _readModuleRepository.AddAsync(newReadModule);
                    }

                    var visitTaskList = await _visitTaskRepository.Where(x => x.TrialReadingCriterionId == item.Id && x.SourceSubjectVisitId == subjectVisitId && x.TaskState == TaskState.Effect && x.ReadingTaskState == ReadingTaskState.HaveSigned).ToListAsync();

                    foreach (var visitTask in visitTaskList)
                    {
                        await _ivisitTaskHelpeService.AddTaskAsync(new GenerateTaskCommand()
                        {
                            OriginalVisitId = visitTask.Id,
                            ReadingCategory = GenerateTaskCategory.Global,
                            TrialId = subjectVisit.TrialId,

                            ReadingGenerataTaskList = new List<ReadingGenerataTaskDTO>() {

                                    new ReadingGenerataTaskDTO (){
                                    IsUrgent=subjectVisit.IsUrgent,
                                    ReadingCategory=ReadingCategory.Global,
                                    ReadingName=readModule.ModuleName,
                                    ReadModuleId=readModule.Id,
                                    SubjectId=subjectVisit.SubjectId,
                                    VisitNum=visitTask.VisitTaskNum,
                                    },

                                },
                        });

                    }

                }
                await _readModuleRepository.SaveChangesAsync();
            }


            #endregion
        }

        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(_localizer["SubjectVisit_CannotSetAsLastVisit"]);
            }

        }
    }


}
