using IRaCIS.Core.Infrastructure.ExpressionExtend;
using IRaCIS.Application.Interfaces;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Application.Filter;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.MediatR.CommandAndQueries;
using Magicodes.ExporterAndImporter.Core;
using Magicodes.ExporterAndImporter.Excel;
using Magicodes.ExporterAndImporter.Excel.AspNetCore;
using IRaCIS.Core.Application.Service.Inspection.Interface;
using Newtonsoft.Json;

namespace IRaCIS.Application.Services
{
    [ApiExplorerSettings(GroupName = "Trial")]
    public class VisitPlanService : BaseService, IVisitPlanService
    {
        private readonly IRepository<VisitStage> _visitStageRepository;
        private readonly IRepository<Trial> _trialRepository;
        private readonly IRepository<SubjectVisit> _subjectVisitRepository;
        private readonly IRepository<VisitPlanInfluenceStat> _influnceStatRepository;
        private readonly IRepository<VisitPlanInfluenceStudy> _influnceRepository;
        private readonly IInspectionService _inspectionService;

        public VisitPlanService(IRepository<VisitStage> visitStageRepository,IRepository<Trial> trialRepository, IRepository<SubjectVisit> subjectVisitRepository,
            IRepository<VisitPlanInfluenceStat> influnceStatRepository,
            IRepository<VisitPlanInfluenceStudy> visitPlanInfluenceStudy,

            IInspectionService inspectionService)
        {
            _visitStageRepository = visitStageRepository;
            _trialRepository = trialRepository;
            this._subjectVisitRepository = subjectVisitRepository;
            this._influnceStatRepository = influnceStatRepository;
            this._influnceRepository = visitPlanInfluenceStudy;
            this._inspectionService = inspectionService;
        }


        ///暂时不用
        /// <summary> 获取项目访视计划</summary>
        public async Task<PageOutput<VisitStageDTO>> GetTrialVisitStageList(VisitPlanQueryDTO param)
        {
            var visitStageQuery = _visitStageRepository.AsQueryable(true).Where(u => u.TrialId == param.TrialId)
                  .WhereIf(!string.IsNullOrWhiteSpace(param.Keyword), t => t.VisitName.Contains(param.Keyword))
                  .ProjectTo<VisitStageDTO>(_mapper.ConfigurationProvider);

            return await visitStageQuery.ToPagedListAsync(param.PageIndex, param.PageSize, "CreateTime", param.Asc);


        }

        /// <summary> 根据项目Id,获取项目访视计划(不分页)[New]</summary>
        [HttpGet("{trialId:guid}")]
        public async Task<VisitPlanView> GetVisitStageList(Guid trialId)
        {
            var query = _visitStageRepository.AsQueryable(true).Where(u => u.TrialId == trialId)
                .ProjectTo<VisitStageDTO>(_mapper.ConfigurationProvider).OrderBy(t => t.VisitNum);
            var list = await query.ToListAsync();
            var trial = await _repository.FirstOrDefaultAsync<Trial>(t => t.Id == trialId).IfNullThrowException();

            return new VisitPlanView()
            {
                VisitPlanList = list,
                TimePointsPerPatient = trial.TimePointsPerPatient,
                VisitPlanConfirmed = trial.VisitPlanConfirmed,
                IsHaveFirstGiveMedicineDate = trial.IsHaveFirstGiveMedicineDate,
                //SubjectHasAdded = _subjectVisitRepository.Any(t => t.TrialId == trialId)
            };
        }

        /// <summary>
        /// 获取访视计划下拉框列表
        /// </summary>
        /// <param name="trialId"></param>
        /// <returns></returns>
        [HttpGet("{trialId:guid}")]
        public async Task<IEnumerable<VisitStageSelectDTO>> GetTrialVisitStageSelect(Guid trialId)
        {
            var query = _visitStageRepository.Where(u => u.TrialId == trialId)
                .ProjectTo<VisitStageSelectDTO>(_mapper.ConfigurationProvider).OrderBy(t => t.VisitNum);
            var list = await query.ToListAsync();
            return list;
        }


        /// <summary> 添加或更新访视计划某项[New]</summary>
        [HttpPost]
        [UnitOfWork]
        public async Task<IResponseOutput<string>> AddOrUpdateVisitStage(VisitPlanCommand visitPlan)
        {
            DateTime createtime = DateTime.Now;
            List<DataInspection> datas = new List<DataInspection>();
            if (!await _trialRepository.Where(t => t.Id == visitPlan.TrialId).IgnoreQueryFilters().AnyAsync(t => t.TrialStatusStr == StaticData.TrialOngoing || t.TrialStatusStr == StaticData.TrialInitializing))
            {
                return ResponseOutput.NotOk(" only in  Initializing  or Ongoing  State  can operate ");
            }

            var visitPlanList = await _visitStageRepository.Where(t => t.TrialId == visitPlan.TrialId,ignoreQueryFilters:true)
                .Select(t => new { t.Id, t.VisitNum, t.VisitDay }).OrderBy(t => t.VisitNum).ToListAsync();

            //更新的时候,需要排除自己
            if (visitPlan.Id != null)
            {
                visitPlanList = visitPlanList.Where(t => t.Id != visitPlan.Id).ToList();
            }

            if (visitPlanList.Any(t => t.VisitNum < visitPlan.VisitNum))
            {
                //比当前 visitNum小的 visitDay的最大值    还小 不允许添加
                if (visitPlan.VisitDay <= visitPlanList.Where(t => t.VisitNum < visitPlan.VisitNum).Select(t => t.VisitDay).Max())
                {
                    return ResponseOutput.NotOk("For the visit plan, the VisitDay with a larger VisitNum should be larger than the VisitDay with a smaller VisitNum.");
                }
            }

            if (visitPlanList.Any(t => t.VisitNum > visitPlan.VisitNum))
            {
                if (visitPlan.VisitDay >= visitPlanList.Where(t => t.VisitNum > visitPlan.VisitNum).Select(t => t.VisitDay).Min())
                {
                    return ResponseOutput.NotOk("For the visit plan, the VisitDay with a larger VisitNum should be larger than the VisitDay with a smaller VisitNum.");
                }
            }

            if (visitPlan.Id == Guid.Empty || visitPlan.Id == null)//add
            {

                if (await _visitStageRepository.AnyAsync(t => t.TrialId == visitPlan.TrialId && (t.VisitName == visitPlan.VisitName || t.VisitNum == visitPlan.VisitNum), true))
                {
                    return ResponseOutput.NotOk("A visit with the same VisitName/VisitNum already existed in the current visit plan.");
                }

                if (await _visitStageRepository.AnyAsync(t => t.TrialId == visitPlan.TrialId && t.IsBaseLine, true) && visitPlan.IsBaseLine)
                {
                    return ResponseOutput.NotOk("A visit  already is baseline in the current visit plan.");
                }

                //已添加受试者  都不存在该新增的计划名称 那么该项目所有受试者都增加一个访视记录
                if (!await _subjectVisitRepository.AnyAsync(t => t.VisitName == visitPlan.VisitName && t.TrialId == visitPlan.TrialId))
                {
                    var subjectSVS = await _subjectVisitRepository.Where(t => t.TrialId == visitPlan.TrialId).Select(t => new { t.SubjectId, t.SiteId,t.IsFinalVisit }).Distinct().ToListAsync();

                    var subjects = subjectSVS.Select(t => new { t.SubjectId, t.SiteId }).Distinct().ToList();

                    foreach (var subject in subjects)
                    {
                        var svItem = _mapper.Map<SubjectVisit>(visitPlan);

                        svItem.SiteId = subject.SiteId;

                        svItem.SubjectId = subject.SubjectId;
                        svItem.Id = Guid.NewGuid();

                        //设置了末次访视,那么加访视计划的时候,设置为不可用
                        if (subjectSVS.Any(t => t.SubjectId == svItem.SubjectId && t.IsFinalVisit))
                        {
                            svItem.VisitExecuted = VisitExecutedEnum.Unavailable;
                        }
                        //datas.Add(new DataInspection()
                        //{
                        //    SubjectVisitId = svItem.Id,
                        //    SubjectVisitName = svItem.VisitName,
                        //    BlindName = visitPlan.BlindName,
                        //    Identification = "Add|Visit|Info|Visit-Image Upload",
                        //    SiteId = svItem.SiteId,
                        //    TrialId = svItem.TrialId,
                        //    SubjectId = svItem.SubjectId,
                        //    IsSign = false,
                        //    CreateTime = createtime,
                        //    JsonDetail = JsonConvert.SerializeObject(svItem)
                        //});

                      
                        await _repository.AddAsync(svItem);
                    }
                }
              

                var visitPlanItem = _mapper.Map<VisitStage>(visitPlan);

                visitPlanItem.BlindName = "B" + ((int)visitPlanItem.VisitNum * 10).ToString("D3");

                var result = await _repository.AddAsync(visitPlanItem);
                visitPlan.Id = result.Id;
                //datas.Add(new DataInspection()
                //{
                //    BlindName = visitPlan.BlindName,
                //    Identification = "Add|Visit|Info|Visit-Image Upload",
                //    TrialId = visitPlan.TrialId,
                //    IsSign = false,
                //    CreateTime = createtime.AddSeconds(1),
                //    VisitStageId = result.Id,
                //    JsonDetail = JsonConvert.SerializeObject(visitPlan)
                //});

                //更新项目访视计划状态为未确认
                await _trialRepository.BatchUpdateAsync(u => u.Id == visitPlan.TrialId, t => new Trial() { VisitPlanConfirmed = false });

                await _repository.SaveChangesAsync();

                //return ResponseOutput.Ok(result.Id.ToString());


            }

            else//update
            {


                if (await _visitStageRepository.AnyAsync(t => t.TrialId == visitPlan.TrialId && (t.VisitName == visitPlan.VisitName || t.VisitNum == visitPlan.VisitNum) && t.Id != visitPlan.Id,true))
                {
                    return ResponseOutput.NotOk("A visit with the same VisitName/VisitNum already existed in the current visit plan.");
                }

                if (await _visitStageRepository.AnyAsync(t => t.TrialId == visitPlan.TrialId && t.IsBaseLine && t.Id != visitPlan.Id,true) && visitPlan.IsBaseLine)
                {
                    return ResponseOutput.NotOk("A visit  already is baseline in the current visit plan.");
                }



                var stage = await _visitStageRepository.FirstOrDefaultAsync(t => t.Id == visitPlan.Id,true);
                if (stage == null) return ResponseOutput.NotOk("None");

                //修改是否是基线
                if (stage.IsBaseLine && stage.IsBaseLine != visitPlan.IsBaseLine)
                {
                    if (await _repository.Where<SubjectVisit>(t => t.TrialId == visitPlan.TrialId).AnyAsync(v => v.IsBaseLine && v.SubmitState >= SubmitStateEnum.ToSubmit))
                    {
                        return ResponseOutput.NotOk("有CRC已经为基线上传了影像数据,不允许修改基线");
                    }
                }

                _mapper.Map(visitPlan, stage);

                stage.BlindName = "B" + ((int)visitPlan.VisitNum * 10).ToString("D3");

                //更新项目访视计划状态为未确认
                //await _trialRepository.UpdateFromQueryAsync(u => u.Id == visitPlan.TrialId, t => new Trial() { VisitPlanConfirmed = false });

                await _repository.SaveChangesAsync();

                //return ResponseOutput.Ok();
            }


            await _inspectionService.AddListInspectionRecordAsync(datas);
            return ResponseOutput.Ok(visitPlan.Id.Value.ToString());
        }

        /// <summary> 删除项目计划某一项[New]</summary>
        [HttpDelete("{id:guid}/{trialId:guid}")]
        [TrialAudit(AuditType.TrialAudit, AuditOptType.DeleteTrialVisitPlanItem)]

        [TypeFilter(typeof(TrialResourceFilter))]
        public async Task<IResponseOutput> DeleteVisitStage(Guid id)
        {

            var visitPlan = await _visitStageRepository.FirstOrDefaultAsync(t => t.Id == id);

            if (visitPlan == null) return Null404NotFound(visitPlan);

            if (await _repository.AnyAsync<SubjectVisit>(t => t.VisitName == visitPlan.VisitName && t.TrialId == visitPlan.TrialId && t.VisitExecuted == VisitExecutedEnum.Executed))
            {
                return ResponseOutput.NotOk("The visit plan has been assigned to the subjects and executed.");
            }


            var list = await _subjectVisitRepository.Where(t => t.TrialId == visitPlan.TrialId && t.VisitName == visitPlan.VisitName).ToListAsync();


            List<DataInspection> datas = new List<DataInspection>();
            var createtime = DateTime.Now.AddSeconds(1);
            list.ForEach(x =>
            {
                datas.Add(new DataInspection()
                {
                    BlindName = x.BlindName,
                    IsSign = false,
                    SiteId = x.SiteId,
                    SubjectId = x.SubjectId,
                    SubjectVisitId = x.Id,
                    CreateTime = createtime,
                    SubjectVisitName = x.VisitName,
                    TrialId = x.TrialId,
                    JsonDetail = JsonConvert.SerializeObject(x),
                    Identification = "Delete|Visit|Data|Visit-Image Upload"
                });
            });


            await _inspectionService.AddListInspectionRecordAsync(datas);
            await _repository.BatchDeleteAsync<SubjectVisit>(t => t.TrialId == visitPlan.TrialId && t.VisitName == visitPlan.VisitName);

            var result = await _visitStageRepository.BatchDeleteAsync(u => u.Id == id);

            return ResponseOutput.Result(result);
        }


        [UnitOfWork]
        [HttpPost("{trialId:guid}")]
        [TrialAudit(AuditType.TrialAudit, AuditOptType.ConfirmTrialVisitPlan)]

        public async Task<IResponseOutput> ConfirmTrialVisitPlan(Guid trialId)
        {
            if (!await _trialRepository.AnyAsync(t => t.Id == trialId &&( t.TrialStatusStr==StaticData.TrialInitializing || t.TrialStatusStr == StaticData.TrialOngoing)))
            {
                return ResponseOutput.NotOk("仅仅在项目初始化或者进行中时,才允许修改确认");
            }

            if (!await _visitStageRepository.AnyAsync(t => t.TrialId == trialId && t.IsBaseLine))
            {
                return ResponseOutput.NotOk("没有基线,不允许确认");
            }

            if (!await _trialRepository.AnyAsync(t => t.Id == trialId && t.IsTrialBasicLogicConfirmed && t.IsTrialProcessConfirmed && t.IsTrialUrgentConfirmed))
            {
                return ResponseOutput.NotOk("项目配置未确认,不允许确认访视计划");
            }

            var svList = await _visitStageRepository.Where(t => t.TrialId == trialId).Select(u => new { u.VisitDay, u.IsBaseLine }).ToListAsync();

            if (svList.Min(t => t.VisitDay) != svList.Where(t => t.IsBaseLine).FirstOrDefault()?.VisitDay)
            {
                return ResponseOutput.NotOk("基线VisitDay 不是最小的, 不允许确认");
            }

            List<DataInspection> datas = new List<DataInspection>();

            var addvisitStages = await _visitStageRepository.Where(x => !x.IsHaveFirstConfirmed&&x.TrialId== trialId).ToListAsync();

            //更新项目访视计划状态为已确认
            await _trialRepository.BatchUpdateAsync(u => u.Id == trialId, t => new Trial() { VisitPlanConfirmed = true });

            //找到访视计划修改的Item
            var changedList = await _visitStageRepository.Where(t => t.TrialId == trialId && 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 }).ToListAsync();
            var createtime = DateTime.Now.AddSeconds(1);


            changedList.ForEach(x =>
            {
                datas.Add(new DataInspection()
                {
                    IsSign = false,

                    CreateTime = createtime,
                    //SubjectVisitName = x.VisitName,
                    VisitStageId = x.Id,
                    TrialId = x.TrialId,
                    JsonDetail = JsonConvert.SerializeObject(x),
                    Identification = "Confirm|Visit Plan Template|Data|Trial Setting-Visit Plan"
                });

            });

            //访视计划 整体状态变更为 确认
            await _visitStageRepository.BatchUpdateAsync(u => u.TrialId == trialId, t => new VisitStage() { IsConfirmed = true ,IsHaveFirstConfirmed = true});

            var stat = new VisitPlanInfluenceStat() { TrialId = trialId };
          
            foreach (var changedItem in changedList)
            {
                //找到该项目 访视已经执行,并且配置了有首次给药日期 并且更新后超窗的访视,要把超窗之前的值也要查询出来
                var qcPassedVisitList = await _repository.Where<SubjectVisit>(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 =>
                    {
                        stat.InconsistentCount++;
                        stat.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 =>
                    {
                        stat.InconsistentCount++;
                        stat.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 =>
                    {
                        stat.InconsistentCount++;
                        stat.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 =>
                    {
                        stat.InconsistentCount++;
                        stat.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")

                        });
                    });
                }


              
            

                var list = await _subjectVisitRepository.Where(t => t.TrialId == trialId && t.VisitStageId == changedItem.Id).ToListAsync();
                list.ForEach(x =>
                {
                    datas.Add(new DataInspection()
                    {
                        BlindName = x.BlindName,
                        IsSign = false,
                        SiteId = x.SiteId,
                        SubjectId = x.SubjectId,
                        SubjectVisitId = x.Id,
                        CreateTime = createtime,
                        SubjectVisitName = x.VisitName,
                        TrialId = x.TrialId,
                        JsonDetail = JsonConvert.SerializeObject(new {

                            IsBaseLine = changedItem.IsBaseLine,
                            VisitName = changedItem.VisitName,
                            VisitNum = changedItem.VisitNum,
                            VisitDay = changedItem.VisitDay,
                            VisitWindowLeft = changedItem.VisitWindowLeft,
                            VisitWindowRight = changedItem.VisitWindowRight
                        }),
                        Identification = "Edit|Visit|Info|Visit-Image Upload"
                    });
                });


            



                //变更某一访视计划Item  受试者访视相关字段
                await _repository.BatchUpdateAsync<SubjectVisit>(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
                });

            }
            var subjectsids = _repository.GetQueryable<Subject>().Where(x => x.TrialId == trialId).Select(x => new
            {
                x.Code,
                x.SiteId,
                x.Id,
                x.IsEnrollment,
                x.IsUrgent

            });
           
            List<SubjectVisit> subjectVisits = new List<SubjectVisit>();


        

          
           
            addvisitStages.ForEach(x =>
            {
                subjectsids.ForEach(y =>
                {
                    var guid = new Guid();
                    // 新增受试者
                    datas.Add(new DataInspection()
                    {
                        BlindName = x.BlindName,
                        IsSign = false,
                        SiteId = y.SiteId,
                        SubjectId = y.Id,
                        SubjectVisitId = guid,
                        CreateTime = createtime.AddMilliseconds(200),
                        SubjectVisitName = x.VisitName,
                        TrialId = x.TrialId,
                        Identification = "Add|Visit|Info|Visit-Image Upload",
                        JsonDetail = JsonConvert.SerializeObject(new
                        {
                            IsBaseLine = x.IsBaseLine,
                            VisitName = x.VisitName,
                            VisitNum = x.VisitNum,
                            VisitDay = x.VisitDay,
                            VisitExecuted=false,
                            BlindName=x.BlindName,
                            VisitWindowLeft = x.VisitWindowLeft,
                            VisitWindowRight = x.VisitWindowRight,
                            IsEnrollment=y.IsEnrollment,
                            IsUrgent=y.IsUrgent,
                        }),
                    });

                    // 初始化受试者
                    datas.Add(new DataInspection()
                    {
                        SiteId = y.SiteId,
                        SubjectId = y.Id,
                        SubjectVisitId = guid,
                        TrialId = x.TrialId,
                        SubjectCode = y.Code,
                        BlindName = x.BlindName,
                      
                        SubjectVisitName = x.VisitName,
                        IsSign = false,
                        CreateTime = createtime.AddMilliseconds(500),
                        Identification = "Init|Visit|Status|Visit-Image Upload",
                        JsonDetail = JsonConvert.SerializeObject(new
                        {
                            BlindName = x.BlindName,
                            VisitName = x.VisitName,
                            SubmitState = "",
                            AuditState = "",
                            IsBaseLine = x.IsBaseLine,
                            IsEnrollment = y.IsEnrollment,
                            IsUrgent = y.IsUrgent,
                        })
                    });

                    subjectVisits.Add(new SubjectVisit()
                    {

                        SiteId = y.SiteId,
                        SubjectId = y.Id,
                        Id = guid,
                        VisitName=x.VisitName,
                        BlindName=x.BlindName,
                        IsBaseLine=x.IsBaseLine,
                        IsCheckBack=x.IsBaseLine,
                        IsUrgent=y.IsUrgent,
                        
                        
                    });
                });


            });
            await _inspectionService.AddListInspectionRecordAsync(datas);
            await _repository.AddAsync(stat);
            await _repository.AddRangeAsync(subjectVisits);
            await _repository.SaveChangesAsync();
            return ResponseOutput.Ok();

        }


        

        [HttpGet("{trialId:guid}")]
        public async Task<List<VisitPlanInfluenceSubjectVisitStatDTO>> GetInfluenceHistoryList(Guid trialId, [FromServices] IRepository<VisitPlanInfluenceStat> _influnceStatRepository)
        {
            var list = await _influnceStatRepository.Where(t => t.TrialId == trialId).ProjectTo<VisitPlanInfluenceSubjectVisitStatDTO>(_mapper.ConfigurationProvider).OrderByDescending(t => t.CreateTime).ToListAsync();

            return list;
        }

        [HttpGet("{visitPlanInfluenceStatId:guid}")]
        public async Task<IActionResult> DownloadInflunceStudyList(Guid visitPlanInfluenceStatId)
        {
            var list = _influnceRepository.Where(t => t.VisitPlanInfluenceStatId == visitPlanInfluenceStatId)
                .ProjectTo<VisitPlanInfluenceSubjectVisitDTO>(_mapper.ConfigurationProvider).ToList();


            IExporter exporter = new ExcelExporter();

            var result = await exporter.ExportAsByteArray(list);


            return new XlsxFileResult(bytes: result, fileDownloadName: $"检查导出_{DateTime.Now.ToString("yyyy-MM-dd:hh:mm:ss")}.xlsx");


        }


    }
}