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

namespace IRaCIS.Core.Application.Triggers
{
    /// <summary>
    ///  处理  项目访视计划确认，记录影像的检查，另外批量插入访视数据
    /// </summary>
    public class TrialVisitPlanConfirmTrigger : IAfterSaveTrigger<Trial>
    {
        private readonly IRepository<SubjectVisit> _subjectVisitRepository;
        private readonly IRepository<Subject> _subjectRepository;
        private readonly IRepository<VisitStage> _visitStageRepository;
        private readonly IRepository<VisitPlanInfluenceStat> _visitPlanInfluenceStatRepository;

        public TrialVisitPlanConfirmTrigger(IRepository<SubjectVisit> subjectVisitRepository,
            IRepository<Subject> subjectRepository,IRepository<VisitStage> visitStageRepository,
            IRepository<VisitPlanInfluenceStat> visitPlanInfluenceStatRepository)
        {
            _subjectVisitRepository = subjectVisitRepository;
            _subjectRepository = subjectRepository;
            _visitStageRepository = visitStageRepository;
            _visitPlanInfluenceStatRepository = visitPlanInfluenceStatRepository;
        }

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

            var trial = context.Entity;

            var trialId = context.Entity.Id;


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

                //项目访视计划确认  状态改变触发
                if (trial.VisitPlanConfirmed && trial.VisitPlanConfirmed != context.UnmodifiedEntity?.VisitPlanConfirmed)
                {
                    //找到访视计划修改的Item
                    var changedList = await _visitStageRepository.Where(t => t.TrialId == trial.Id && t.IsConfirmed == false)
                        .Select(t => new
                        {
                            t.Trial.IsHaveFirstGiveMedicineDate,
                            t.Id,
                            t.VisitName,
                            t.TrialId,
                            t.VisitWindowLeft,
                            t.VisitWindowRight,
                            t.VisitDay,
                            t.VisitNum,
                            t.IsBaseLine,
                            t.BlindName,

                            t.Description,
                            IsConfirmed = true,
                        }).ToListAsync();

                    var visitPlanInfluenceStat = new VisitPlanInfluenceStat() { TrialId = trial.Id };

                    foreach (var changedItem in changedList)
                    {
                        //找到该项目 访视已经执行，并且配置了有首次给药日期 并且更新后超窗的访视，要把超窗之前的值也要查询出来
                        var qcPassedVisitList = await _subjectVisitRepository.Where(t => t.TrialId == trialId
                                                        && t.VisitExecuted == VisitExecutedEnum.Executed
                                                        && t.AuditState == AuditStateEnum.QCPassed
                                                        && t.Trial.IsHaveFirstGiveMedicineDate == true
                                                        && t.VisitStageId == changedItem.Id
                                                        && t.Subject.FirstGiveMedicineTime != null
                                                         ).Select(k => new
                                                         {
                                                             SubjectVisitId = k.Id,
                                                             SelfWindowLeft = k.Subject.FirstGiveMedicineTime!.Value.AddDays(k.VisitDay + k.VisitWindowLeft),
                                                             SelfWindowRight = k.Subject.FirstGiveMedicineTime!.Value.AddDays(k.VisitDay + k.VisitWindowRight + 1).AddSeconds(-1),

                                                             NowWindowLeft = k.Subject.FirstGiveMedicineTime!.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowLeft),
                                                             NowWindowRight = k.Subject.FirstGiveMedicineTime!.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowRight + 1).AddSeconds(-1),

                                                             NoneDicomStudyList =
                                                             k.NoneDicomStudyList  //之前是查询调整之后超窗的  现在调整前超窗  调整后 没超窗的也要记录
                                                                                   //.Where(study => study.ImageDate <k.Subject.FirstGiveMedicineTime.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowLeft??0)
                                                                                   //|| study.ImageDate >k.Subject.FirstGiveMedicineTime.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowRight??0 + 1).AddSeconds(-1))
                                                             .Select(t => new { NoneDicomStudyId = t.Id, t.Modality, StudyTime = t.ImageDate }),


                                                             DicomStudyList = k.StudyList
                                                             //.Where(study => study.StudyTime <k.Subject.FirstGiveMedicineTime.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowLeft??0)
                                                             // || study.StudyTime >k.Subject.FirstGiveMedicineTime.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowRight??0 + 1).AddSeconds(-1))
                                                             .Select(t => new { StudyId = t.Id, Modality = t.Modalities, t.StudyTime })

                                                         }).ToListAsync();


                        foreach (var visit in qcPassedVisitList)
                        {
                            //找到本身没有超窗的数据 修改后超窗的
                            visit.DicomStudyList.Where(t => (t.StudyTime > visit.SelfWindowLeft && t.StudyTime < visit.SelfWindowRight) && (t.StudyTime < visit.NowWindowLeft || t.StudyTime > visit.NowWindowRight)).ForEach(t =>
                            {
                                visitPlanInfluenceStat.InconsistentCount++;
                                visitPlanInfluenceStat.InfluenceStudyList.Add(new VisitPlanInfluenceStudy()
                                {
                                    IsOverWindowNowNotOverWindow = false,
                                    Modality = t.Modality,
                                    SubjectVisitId = visit.SubjectVisitId,
                                    StudyId = t.StudyId,
                                    IsDicomStudy = true,
                                    StudyTime = t.StudyTime,
                                    TrialId = trialId,
                                    HistoryWindow = visit.SelfWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.SelfWindowRight.ToString("yyyy-MM-dd"),
                                    NowWindow = visit.NowWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.NowWindowRight.ToString("yyyy-MM-dd")

                                });

                            });

                            visit.NoneDicomStudyList.Where(t => (t.StudyTime > visit.SelfWindowLeft && t.StudyTime < visit.SelfWindowRight) && (t.StudyTime < visit.NowWindowLeft || t.StudyTime > visit.NowWindowRight)).ForEach(t =>
                            {
                                visitPlanInfluenceStat.InconsistentCount++;
                                visitPlanInfluenceStat.InfluenceStudyList.Add(new VisitPlanInfluenceStudy()
                                {
                                    IsOverWindowNowNotOverWindow = false,
                                    Modality = t.Modality,
                                    SubjectVisitId = visit.SubjectVisitId,
                                    StudyId = t.NoneDicomStudyId,
                                    IsDicomStudy = false,
                                    StudyTime = t.StudyTime,
                                    TrialId = trialId,
                                    HistoryWindow = visit.SelfWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.SelfWindowRight.ToString("yyyy-MM-dd"),
                                    NowWindow = visit.NowWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.NowWindowRight.ToString("yyyy-MM-dd")

                                });
                            });

                            //本身超窗  修改后没超窗的
                            visit.DicomStudyList.Where(t => (t.StudyTime < visit.SelfWindowLeft || t.StudyTime > visit.SelfWindowRight) && (t.StudyTime > visit.NowWindowLeft && t.StudyTime < visit.NowWindowRight)).ForEach(t =>
                            {
                                visitPlanInfluenceStat.InconsistentCount++;
                                visitPlanInfluenceStat.InfluenceStudyList.Add(new VisitPlanInfluenceStudy()
                                {
                                    IsOverWindowNowNotOverWindow = true,
                                    Modality = t.Modality,
                                    SubjectVisitId = visit.SubjectVisitId,
                                    StudyId = t.StudyId,
                                    IsDicomStudy = true,
                                    StudyTime = t.StudyTime,
                                    TrialId = trialId,
                                    HistoryWindow = visit.SelfWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.SelfWindowRight.ToString("yyyy-MM-dd"),
                                    NowWindow = visit.NowWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.NowWindowRight.ToString("yyyy-MM-dd")

                                });
                            });

                            visit.NoneDicomStudyList.Where(t => (t.StudyTime < visit.SelfWindowLeft || t.StudyTime > visit.SelfWindowRight) && (t.StudyTime > visit.NowWindowLeft && t.StudyTime < visit.NowWindowRight)).ForEach(t =>
                            {
                                visitPlanInfluenceStat.InconsistentCount++;
                                visitPlanInfluenceStat.InfluenceStudyList.Add(new VisitPlanInfluenceStudy()
                                {
                                    IsOverWindowNowNotOverWindow = true,
                                    Modality = t.Modality,
                                    SubjectVisitId = visit.SubjectVisitId,
                                    StudyId = t.NoneDicomStudyId,
                                    IsDicomStudy = false,
                                    StudyTime = t.StudyTime,
                                    TrialId = trialId,
                                    HistoryWindow = visit.SelfWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.SelfWindowRight.ToString("yyyy-MM-dd"),
                                    NowWindow = visit.NowWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.NowWindowRight.ToString("yyyy-MM-dd")

                                });
                            });

                            //变更某一访视计划Item  受试者访视相关字段
                            await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.VisitStageId == changedItem.Id, k => new SubjectVisit()
                            {
                                IsBaseLine = changedItem.IsBaseLine,
                                VisitName = changedItem.VisitName,
                                VisitNum = changedItem.VisitNum,
                                VisitDay = changedItem.VisitDay,
                                VisitWindowLeft = changedItem.VisitWindowLeft,
                                VisitWindowRight = changedItem.VisitWindowRight
                            });
                        }

                    }


                    await _visitPlanInfluenceStatRepository.AddAsync(visitPlanInfluenceStat,true);
                }

            }



        }


    }
}