//--------------------------------------------------------------------
//     此代码由T4模板自动生成  byzhouhang 20210918
//	   生成时间 2023-03-17 11:58:57 
//     对此文件的更改可能会导致不正确的行为，并且如果重新生成代码，这些更改将会丢失。
//--------------------------------------------------------------------

using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Domain.Share.Reading;
using Microsoft.AspNetCore.Mvc;
using Panda.DynamicWebApi.Attributes;
using System.Linq.Dynamic.Core;

namespace IRaCIS.Core.Application.Service
{
    /// <summary>
    /// SubjectCriteriaEvaluationService
    /// </summary>	
    [ApiExplorerSettings(GroupName = "Trial")]
    public class SubjectCriteriaEvaluationService(IRepository<SubjectCriteriaEvaluation> _subjectCriteriaEvaluationRepository,
        IRepository<Subject> _subjectRepository,
        IRepository<SubjectVisit> _subjectVisitRepository,
        IRepository<SubjectCriteriaEvaluationVisitFilter> _subjectCriteriaEvaluationVisitFilterRepository,
        IRepository<SubjectCriteriaEvaluationVisitStudyFilter> _subjectCriteriaEvaluationVisitStudyFilterRepository,
        IRepository<ReadingQuestionCriterionTrial> _trialReadingCriterionRepository,
        IRepository<ReadingQuestionTrial> _trialReadingQuestionRepository,
        IRepository<VisitTask> _visitTaskRepository,
        IVisitTaskHelpeService _IVisitTaskHelpeService,
        IRepository<DicomStudy> _dicomStudyRepository,
        IRepository<DicomSeries> _dicomSeriesRepository,
        IRepository<TaskMedicalReview> _taskMedicalReviewRepository,
        IRepository<VisitTaskReReading> _visitTaskReReadingRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ISubjectCriteriaEvaluationService
    {




        /// <summary>
        /// subject  某标准  是否评估列表
        /// </summary>
        /// <param name="inQuery"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput<PageOutput<SubjectCriteriaEvaluationView>>> GetSubjectCriteriaEvaluationList(SubjectCriteriaEvaluationQuery inQuery)
        {

            var trialReadingCritionList = _trialReadingCriterionRepository.Where(t => t.TrialId == inQuery.TrialId).ToList();

            var resultTrialReadingCriterionId = Guid.Empty;

            var resultTrialReadingCriterion = trialReadingCritionList.First();

            var curentCriterionType = CriterionType.NoCriterion;


            //BM  需要找基线 两个人做的结果
            if (trialReadingCritionList.First(t => t.Id == inQuery.TrialReadingCriterionId).CriterionType == CriterionType.RECIST1Pointt1_MB)
            {

                resultTrialReadingCriterion = trialReadingCritionList.First(t => t.CriterionType == CriterionType.RECIST1Point1);
                resultTrialReadingCriterionId = resultTrialReadingCriterion.Id;

                curentCriterionType = CriterionType.RECIST1Pointt1_MB;
            }

            var addtionalQustionInfoList = _trialReadingQuestionRepository.Where(t => t.ReadingQuestionCriterionTrialId == resultTrialReadingCriterionId && t.IsAdditional == true && t.Type != "group").IgnoreQueryFilters().Select(t => new
            {
                QuestionId = t.Id,
                t.QuestionEnName,
                t.QuestionName
            }).ToList();

            var questionIdList = addtionalQustionInfoList.Select(t => t.QuestionId).ToList();


            var subjectCriteriaEvaluationQueryable = from subject in _subjectRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsDeleted == false)
                   .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectCode), t => t.Code.Contains(inQuery.SubjectCode))
                   .WhereIf(!string.IsNullOrWhiteSpace(inQuery.TrialSiteCode), t => t.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode))
                   .WhereIf(inQuery.SubjectStatus != null, t => t.Status == inQuery.SubjectStatus)

                                                     join subjectCriteriaEvaluation in _subjectCriteriaEvaluationRepository
                                                     .Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)

                                                     on subject.Id equals subjectCriteriaEvaluation.SubjectId into d
                                                     from subjectCriteriaEvaluation in d.DefaultIfEmpty()

                                                     select new SubjectCriteriaEvaluationView()
                                                     {
                                                         SubjectCode = subject.Code,
                                                         SubjectId = subject.Id,
                                                         SubjectStatus = subject.Status,
                                                         TrialSiteCode = subject.TrialSite.TrialSiteCode,

                                                         Id = subjectCriteriaEvaluation.Id,
                                                         TrialReadingCriterionId = inQuery.TrialReadingCriterionId,

                                                         IsImageFiltering = subject.SubjectCriteriaEvaluationVisitFilterList.Any(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId
                                                         && t.ImageFilterState == ImageFilterState.None),

                                                         IsJoinEvaluation = subjectCriteriaEvaluation.IsJoinEvaluation,


                                                         ReadingEvaluationList = subject.ReadingTaskQuestionAnswerList.AsQueryable().IgnoreQueryFilters()
                                                         .Where(t => t.ReadingQuestionCriterionTrialId == resultTrialReadingCriterionId &&
                                                        questionIdList.Contains(t.ReadingQuestionTrialId)
                                                         && t.VisitTask.TaskState == TaskState.Effect)
                                                         .Select(u => new EvaluationInfo()
                                                         {
                                                             QuestionId = u.ReadingQuestionTrialId,
                                                             Answer = u.Answer,
                                                             ArmEnum = u.VisitTask.ArmEnum,
                                                             FinalTranslateDictionaryCode = u.ReadingQuestionTrial.DictionaryCode
                                                         }).ToList()

                                                     };

            var pageList = await subjectCriteriaEvaluationQueryable
                 .WhereIf(inQuery.IsImageFiltering != null, t => t.IsImageFiltering == inQuery.IsImageFiltering)
                 .WhereIf(inQuery.IsJoinEvaluation != null, t => t.IsJoinEvaluation == inQuery.IsJoinEvaluation)
                .ToPagedListAsync(inQuery, nameof(SubjectCriteriaEvaluationView.SubjectCode));


            foreach (var item in pageList.CurrentPageData)
            {
                switch (curentCriterionType)
                {

                    case CriterionType.RECIST1Pointt1_MB:

                        if (resultTrialReadingCriterion.ReadingType == ReadingMethod.Double)
                        {
                            if (item.ReadingEvaluationList.Count == 2)
                            {
                                if (item.ReadingEvaluationList.All(t => t.Answer == 1.ToString()))
                                {
                                    item.FinalEvaluationList.Add(new EvaluationInfo()
                                    {
                                        QuestionId = item.ReadingEvaluationList.First().QuestionId,
                                        Answer = ((int)BrainMetastasisResult.Yes).ToString(),
                                        FinalTranslateDictionaryCode = nameof(BrainMetastasisResult)
                                    });
                                }
                                else if (item.ReadingEvaluationList.All(t => t.Answer == 0.ToString()))
                                {
                                    item.FinalEvaluationList.Add(new EvaluationInfo()
                                    {
                                        QuestionId = item.ReadingEvaluationList.First().QuestionId,
                                        Answer = ((int)BrainMetastasisResult.No).ToString(),
                                        FinalTranslateDictionaryCode = nameof(BrainMetastasisResult)
                                    });
                                }
                                else if (item.ReadingEvaluationList.First().Answer != item.ReadingEvaluationList.Last().Answer && item.ReadingEvaluationList.Any(t => t.Answer == 1.ToString()))
                                {
                                    item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = item.ReadingEvaluationList.First().QuestionId, Answer = ((int)BrainMetastasisResult.Maybe).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) });
                                }
                                else
                                {
                                    item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = addtionalQustionInfoList.FirstOrDefault()?.QuestionId, Answer = ((int)BrainMetastasisResult.Unknown).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) });
                                }

                            }
                            else
                            {
                                item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = addtionalQustionInfoList.FirstOrDefault()?.QuestionId, Answer = ((int)BrainMetastasisResult.Unknown).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) });
                            }
                        }
                        else if (resultTrialReadingCriterion.ReadingType == ReadingMethod.Single)
                        {

                            if (item.ReadingEvaluationList.Count == 1)
                            {
                                if (item.ReadingEvaluationList.All(t => t.Answer == 1.ToString()))
                                {
                                    item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = item.ReadingEvaluationList.First().QuestionId, Answer = ((int)BrainMetastasisResult.Yes).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) });
                                }
                                else if (item.ReadingEvaluationList.All(t => t.Answer == 0.ToString()))
                                {
                                    item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = item.ReadingEvaluationList.First().QuestionId, Answer = ((int)BrainMetastasisResult.No).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) });
                                }
                                else
                                {
                                    item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = addtionalQustionInfoList.FirstOrDefault()?.QuestionId, Answer = ((int)BrainMetastasisResult.Unknown).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) });
                                }
                            }
                            else
                            {
                                item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = addtionalQustionInfoList.FirstOrDefault()?.QuestionId, Answer = ((int)BrainMetastasisResult.Unknown).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) });
                            }

                        }
                        else
                        {

                        }

                        break;
                    default:
                        break;
                }
            }






            return ResponseOutput.Ok(pageList, addtionalQustionInfoList);
        }


        /// <summary>
        ///  添加 编辑 是否参与评估
        /// </summary>
        /// <param name="addOrEditSubjectCriteriaEvaluationList"></param>
        /// <returns></returns>
        [UnitOfWork]
        public async Task<IResponseOutput> BatchAddOrUpdateSubjectCriteriaEvaluation(List<SubjectCriteriaEvaluationAddOrEdit> addOrEditSubjectCriteriaEvaluationList)
        {
            //  在此处拷贝automapper 映射

            foreach (var addOrEditSubjectCriteriaEvaluation in addOrEditSubjectCriteriaEvaluationList)
            {


                if (addOrEditSubjectCriteriaEvaluation.Id == null)
                {
                    var entity = await _subjectCriteriaEvaluationRepository.InsertFromDTOAsync(addOrEditSubjectCriteriaEvaluation);

                    if (addOrEditSubjectCriteriaEvaluation.IsJoinEvaluation)
                    {

                        //找到一致性核查通过的访视  并且没有 自动影像筛选的数据
                        var subjectVisitIdList = await _subjectVisitRepository.Where(t => t.SubjectId == addOrEditSubjectCriteriaEvaluation.SubjectId && t.CheckState == CheckStateEnum.CVPassed
                        && !t.SubjectCriteriaEvaluationVisitFilterList.Any(t => t.TrialReadingCriterionId == addOrEditSubjectCriteriaEvaluation.TrialReadingCriterionId && t.SubjectId == addOrEditSubjectCriteriaEvaluation.SubjectId)).Select(t => t.Id)
                        .ToListAsync();


                        foreach (var subjectVisitId in subjectVisitIdList)
                        {
                            await AutoSubjectCriteriaEvaluationVisitFilter(addOrEditSubjectCriteriaEvaluation.SubjectId, subjectVisitId, addOrEditSubjectCriteriaEvaluation.TrialReadingCriterionId);
                        }

                    }




                }
                //编辑
                else
                {
                    //参与评估
                    if (addOrEditSubjectCriteriaEvaluation.IsJoinEvaluation)
                    {
                        var dbBeforeEntity = await _subjectCriteriaEvaluationRepository.UpdateFromDTOAsync(addOrEditSubjectCriteriaEvaluation);

                        //从不评估 改为评估
                        if (addOrEditSubjectCriteriaEvaluation.IsJoinEvaluation != dbBeforeEntity.IsJoinEvaluation)
                        {
                            //找到一致性核查通过的访视    并且没有 自动影像筛选的数据
                            var subjectVisitIdList = await _subjectVisitRepository.Where(t => t.SubjectId == addOrEditSubjectCriteriaEvaluation.SubjectId && t.CheckState == CheckStateEnum.CVPassed &&
                              !t.SubjectCriteriaEvaluationVisitFilterList.Any(t => t.TrialReadingCriterionId == addOrEditSubjectCriteriaEvaluation.TrialReadingCriterionId && t.SubjectId == addOrEditSubjectCriteriaEvaluation.SubjectId)).
                                Select(t => t.Id).ToListAsync();


                            foreach (var subjectVisitId in subjectVisitIdList)
                            {
                                await AutoSubjectCriteriaEvaluationVisitFilter(addOrEditSubjectCriteriaEvaluation.SubjectId, subjectVisitId, addOrEditSubjectCriteriaEvaluation.TrialReadingCriterionId);
                            }
                        }
                        //未修改  不做任何操作


                    }
                    //不参与评估
                    else
                    {
                        //删除该Subject  该标准访视的所有 访视筛选记录数据
                        await _subjectCriteriaEvaluationVisitFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterionId == addOrEditSubjectCriteriaEvaluation.TrialReadingCriterionId && t.SubjectId == addOrEditSubjectCriteriaEvaluation.SubjectId);
                        await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterionId == addOrEditSubjectCriteriaEvaluation.TrialReadingCriterionId && t.SubjectVisit.SubjectId == addOrEditSubjectCriteriaEvaluation.SubjectId);
                    }
                }

            }

            await _subjectCriteriaEvaluationRepository.SaveChangesAsync();
            return ResponseOutput.Ok();

        }

        /// <summary>
        /// 自动访视筛选  (针对单一访视，重新筛选一遍，可能不存在该接口，仅仅留存)
        /// </summary>
        /// <returns></returns>
        [NonDynamicMethod]
        public async Task AutoSubjectCriteriaEvaluationVisitFilter(Guid subjectId, Guid subjectVisitId, Guid trialReadingCriterionId)
        {

            if ((await _trialReadingCriterionRepository.FindAsync(trialReadingCriterionId)).CriterionType == CriterionType.RECIST1Pointt1_MB)
            {
                //如果所有访视 的所有序列部位都是脑部  那么自动筛选通过，同时需要插入序列的筛选记录


                //找到该方式的所有序列
                var list = await _dicomSeriesRepository.Where(t => t.SubjectVisitId == subjectVisitId && t.SubjectId == subjectId).Select(t => new { SeriesId = t.Id, t.StudyId, t.BodyPartForEdit }).ToListAsync();


                ////已经自动筛选过
                //if (await _subjectCriteriaEvaluationVisitFilterRepository.AnyAsync(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.SubjectVisitId == subjectVisitId))
                //{
                //    await _subjectCriteriaEvaluationVisitFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.SubjectVisitId == subjectVisitId);

                //    await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.SubjectVisitId == subjectVisitId);
                //}

                var existEntity = await _subjectCriteriaEvaluationVisitFilterRepository.FirstOrDefaultAsync(t => t.SubjectId == subjectId && t.SubjectVisitId == subjectVisitId && t.TrialReadingCriterionId == trialReadingCriterionId);

                //已经自动筛选过

                if (existEntity != null)
                {
                    await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.SubjectVisitId == subjectVisitId);
                }

                //有不是脑部的序列
                if (list.Any(t => t.BodyPartForEdit != "脑部"))
                {


                    if (existEntity == null)
                    {
                        var addItem = new SubjectCriteriaEvaluationVisitFilter
                        {
                            SubjectVisitId = subjectVisitId,
                            SubjectId = subjectId,
                            ImageDeterminationResultState = ImageDeterminationResultState.None,
                            ImageFilterState = ImageFilterState.None,
                            TrialReadingCriterionId = trialReadingCriterionId
                        };


                        var subjectCriteriaEvaluationVisitFilter = await _subjectCriteriaEvaluationVisitFilterRepository.AddAsync(addItem);
                    }
                    else
                    {
                        existEntity.ImageDeterminationResultState = ImageDeterminationResultState.None;
                        existEntity.ImageFilterState = ImageFilterState.None;
                    }

                }
                //都是脑部的序列
                else
                {

                    if (existEntity == null)
                    {
                        var addItem = new SubjectCriteriaEvaluationVisitFilter
                        {
                            SubjectVisitId = subjectVisitId,
                            SubjectId = subjectId,
                            ImageDeterminationResultState = ImageDeterminationResultState.Passed,
                            ImageFilterState = ImageFilterState.Finished,
                            TrialReadingCriterionId = trialReadingCriterionId,
                            IsGeneratedTask = true
                        };

                        var subjectCriteriaEvaluationVisitFilter = await _subjectCriteriaEvaluationVisitFilterRepository.AddAsync(addItem);

                    }
                    else
                    {
                        existEntity.ImageDeterminationResultState = ImageDeterminationResultState.Passed;
                        existEntity.ImageFilterState = ImageFilterState.Finished;
                    }

                    foreach (var item in list)
                    {
                        await _subjectCriteriaEvaluationVisitStudyFilterRepository.AddAsync(new SubjectCriteriaEvaluationVisitStudyFilter { SubjectVisitId = subjectVisitId, SeriesId = item.SeriesId, TrialReadingCriterionId = trialReadingCriterionId, StudyId = item.StudyId, IsConfirmed = true, IsReading = true });
                    }

                    //自动生成任务

                    var trialId = _subjectVisitRepository.Where(t => t.Id == subjectVisitId).Select(t => t.TrialId).FirstOrDefault();

                    await _IVisitTaskHelpeService.BaseCritrionGenerateVisitTask(trialId, trialReadingCriterionId, true, new List<Guid>() { subjectVisitId });

                }
            }

            await _subjectCriteriaEvaluationVisitFilterRepository.SaveChangesAsync();


        }


        /// <summary>
        /// 评估访视筛选列表(一致性核查通过的访视都会出现  根据条件筛选)
        /// </summary>
        /// <param name="inQuery"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<SubjectCriteriaEvaluationVisitFilterView>> GetSubjectCriteriaEvaluationVisitFilterList(SubjectCriteriaEvaluationVisitFilterQuery inQuery)
        {




            var subjectCriteriaEvaluationVisitFilterQueryable = from subjectVisit in _subjectVisitRepository.Where(t => t.SubjectId == inQuery.SubjectId && t.CheckState == CheckStateEnum.CVPassed)


                                                                join subjectCriteriaEvaluationVisitFilter in _subjectCriteriaEvaluationVisitFilterRepository
                                                                .Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
                                                                .WhereIf(inQuery.ImageDeterminationResultState != null, t => t.ImageDeterminationResultState == inQuery.ImageDeterminationResultState)
                                                                .WhereIf(inQuery.ImageFilterState != null, t => t.ImageFilterState == inQuery.ImageFilterState)
                                                                .WhereIf(inQuery.IsGeneratedTask != null, t => t.IsGeneratedTask == inQuery.IsGeneratedTask)
                                                                on subjectVisit.Id equals subjectCriteriaEvaluationVisitFilter.SubjectVisitId

                                                                //into d from subjectCriteriaEvaluationVisitFilter in d.DefaultIfEmpty()

                                                                select new SubjectCriteriaEvaluationVisitFilterView()
                                                                {
                                                                    VisitName = subjectVisit.VisitName,
                                                                    VisitNum = subjectVisit.VisitNum,
                                                                    SubjectVisitId = subjectVisit.Id,
                                                                    TrialId = subjectVisit.TrialId,
                                                                    SubjectId = subjectVisit.SubjectId,
                                                                    SubjectCode = subjectVisit.Subject.Code,
                                                                    TrialSiteId = subjectVisit.TrialSiteId,
                                                                    TrialReadingCriterionId = inQuery.TrialReadingCriterionId,
                                                                    LatestScanDate = subjectVisit.LatestScanDate,
                                                                    EarliestScanDate = subjectVisit.LatestScanDate,
                                                                    ImageDeterminationResultState = subjectCriteriaEvaluationVisitFilter.ImageDeterminationResultState,
                                                                    ImageFilterState = subjectCriteriaEvaluationVisitFilter.ImageFilterState,
                                                                    IsGeneratedTask = subjectCriteriaEvaluationVisitFilter.IsGeneratedTask,
                                                                    Id = subjectCriteriaEvaluationVisitFilter.Id,

                                                                    CreateTime = subjectCriteriaEvaluationVisitFilter.CreateTime,
                                                                    CreateUserId = subjectCriteriaEvaluationVisitFilter.CreateUserId,
                                                                    UpdateTime = subjectCriteriaEvaluationVisitFilter.UpdateTime,
                                                                    UpdateUserId = subjectCriteriaEvaluationVisitFilter.UpdateUserId,

                                                                };


            return await subjectCriteriaEvaluationVisitFilterQueryable.OrderBy(t => t.VisitNum).ToListAsync();
        }

        /// <summary>
        /// 已生成任务列表
        /// </summary>
        /// <param name="inQuery"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<HaveGeneratedTaskDto>> GetHaveGeneratedTaskList(HaveGeneratedTaskQuery inQuery)
        {
            var list = await _visitTaskRepository.Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SubjectId == inQuery.SubjectId && t.TaskState == TaskState.Effect).OrderBy(t => t.VisitTaskNum)
                .ProjectTo<HaveGeneratedTaskDto>(_mapper.ConfigurationProvider).ToListAsync();

            return list;
        }

        /// <summary>
        /// 批量勾选 生成该标准的任务
        /// </summary>
        /// <returns></returns>
        [UnitOfWork]
        public async Task<IResponseOutput> BatchGenerateTask(BatchGenerateTaskCommand batchGenerateTaskCommand)
        {

            var trakingList = await _subjectCriteriaEvaluationVisitFilterRepository.Where(t => t.SubjectId == batchGenerateTaskCommand.SubjectId
            && t.TrialReadingCriterionId == batchGenerateTaskCommand.TrialReadingCriterionId
            && batchGenerateTaskCommand.SubjectVisitIdList.Contains(t.SubjectVisitId), true).ToListAsync();

            foreach (var item in trakingList)
            {
                item.IsGeneratedTask = true;
            }

            //await _subjectCriteriaEvaluationVisitFilterRepository.BatchUpdateNoTrackingAsync(t => t.SubjectId == batchGenerateTaskCommand.SubjectId
            //&& t.TrialReadingCriterionId == batchGenerateTaskCommand.TrialReadingCriterionId
            //&& batchGenerateTaskCommand.SubjectVisitIdList.Contains(t.SubjectVisitId), u => new SubjectCriteriaEvaluationVisitFilter { IsGeneratedTask = true });

            //自动生成任务

            var idList = batchGenerateTaskCommand.SubjectVisitIdList.Select(t => (Guid?)t).ToList();

            //存在任务的访视
            var haveGenerateVisitIdList = await _visitTaskRepository.Where(t => idList.Contains(t.SourceSubjectVisitId) && t.TrialReadingCriterionId == batchGenerateTaskCommand.TrialReadingCriterionId && t.TaskState == TaskState.Effect)
                .Select(t => t.SourceSubjectVisitId).ToListAsync();

            var generateVisitIdList = idList.Except(haveGenerateVisitIdList);

            await _IVisitTaskHelpeService.BaseCritrionGenerateVisitTask(batchGenerateTaskCommand.TrialId, batchGenerateTaskCommand.TrialReadingCriterionId, true, generateVisitIdList.Select(t => (Guid)t.Value).ToList());

            await _subjectCriteriaEvaluationVisitFilterRepository.SaveChangesAsync();

            return ResponseOutput.Ok();
        }


        /// <summary>
        /// 获取dicom     访视检查列表  （序列的 Id  CreateTime    是否为空 代表了记录是否创建、IsConfirmed 代表 保存  确认）
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<SelctStudySeriesView> GetVisitStudyAndSeriesList(VisitStudyAndSeriesQuery inQuery)
        {
            var studyList = await _dicomStudyRepository.Where(s => s.SubjectVisitId == inQuery.SubjectVisitId).ProjectTo<SelectStudyView>(_mapper.ConfigurationProvider).ToListAsync();

            var studyIds = studyList.Select(t => t.StudyId).ToList();


            var query = from series in _dicomSeriesRepository.Where(t => studyIds.Contains(t.StudyId))
                        join visitStudyFilter in _subjectCriteriaEvaluationVisitStudyFilterRepository.Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SubjectVisitId == inQuery.SubjectVisitId) on series.Id equals visitStudyFilter.SeriesId into d
                        from visitStudyFilter in d.DefaultIfEmpty()

                        select new SelectSeriesView()
                        {
                            Description = series.Description,
                            BodyPartExamined = series.BodyPartExamined,
                            BodyPartForEdit = series.BodyPartForEdit,
                            Modality = series.Modality,
                            SeriesInstanceUid = series.SeriesInstanceUid,
                            StudyCode = series.DicomStudy.StudyCode,
                            SeriesNumber = series.SeriesNumber,
                            SeriesTime = series.SeriesTime,

                            InstanceCount = series.InstanceCount,
                            StudyTime = series.DicomStudy.StudyTime,
                            StudyId = series.StudyId,
                            SeriesId = series.Id,
                            SubjectVisitId = series.SubjectVisitId,
                            TrialReadingCriterionId = inQuery.TrialReadingCriterionId,


                            IsReading = visitStudyFilter.IsReading,
                            Id = visitStudyFilter.Id,
                            CreateTime = visitStudyFilter.CreateTime,
                            IsConfirmed = visitStudyFilter.IsConfirmed,
                        };


            var seriesList = query.ToList();




            return new SelctStudySeriesView { StudyList = studyList, SeriesList = seriesList };

        }

        /// <summary>
        /// 批量保存或者确认  选择的序列
        /// </summary>
        /// <returns></returns>
        public async Task<IResponseOutput> BatchAddSubjectCriteriaEvaluationVisitStudyFilter(List<SubjectCriteriaEvaluationVisitStudyFilterAddOrEdit> batchList)
        {

            var ids = batchList.Where(t => t.Id != null).Select(t => t.Id).ToList();
            #region 稽查修改前

            //await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => ids.Contains(t.Id));

            //await _subjectCriteriaEvaluationVisitStudyFilterRepository.AddRangeAsync(_mapper.Map<List<SubjectCriteriaEvaluationVisitStudyFilter>>(batchList));

            #endregion


            #region 查询再更新
            if (ids.Count > 0)
            {
                var list = await _subjectCriteriaEvaluationVisitStudyFilterRepository.Where(t => ids.Contains(t.Id), true).ToListAsync();

                foreach (var item in list)
                {
                    item.IsReading = batchList.FirstOrDefault(t => t.Id == item.Id)?.IsReading ?? item.IsReading;
                    item.IsConfirmed = batchList.FirstOrDefault(t => t.Id == item.Id)?.IsConfirmed ?? item.IsConfirmed;
                }
            }
            else
            {
                await _subjectCriteriaEvaluationVisitStudyFilterRepository.AddRangeAsync(_mapper.Map<List<SubjectCriteriaEvaluationVisitStudyFilter>>(batchList));
            }
            #endregion




            var first = batchList.First();

            if (batchList.Count(t => t.IsReading == true) >= 0 && batchList.All(t => t.IsConfirmed == false))
            {
                await _subjectCriteriaEvaluationVisitFilterRepository.UpdatePartialFromQueryAsync(t => t.SubjectVisitId == first.SubjectVisitId && t.TrialReadingCriterionId == first.TrialReadingCriterionId,
                u => new SubjectCriteriaEvaluationVisitFilter() { ImageFilterState = ImageFilterState.Filtering });
            }

            if (batchList.All(t => t.IsConfirmed == true))
            {

                await _subjectCriteriaEvaluationVisitFilterRepository.UpdatePartialFromQueryAsync(t => t.SubjectVisitId == first.SubjectVisitId && t.TrialReadingCriterionId == first.TrialReadingCriterionId,
                    u => new SubjectCriteriaEvaluationVisitFilter() { ImageFilterState = ImageFilterState.Finished });
            }



            await _subjectCriteriaEvaluationVisitStudyFilterRepository.SaveChangesAsync();
            return ResponseOutput.Ok();

        }



        /// <summary>
        /// 附加评估标准 PM 退回某一访视 影响任务列表
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        [HttpPost]

        public async Task<(List<InfluenceTaskInfo>, object)> GetCriteriaVisitBackInfluenceTaskList(CriteriaVisitBackCommand command)
        {

            var isIRAppyTaskInfluenced = false;

            var filterExpression = await GetTaskExpressionAsync(command);

            var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == command.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException();

            var subjectVisit = await _subjectVisitRepository.FindAsync(command.SubjectVisitId);

            if (await _visitTaskReReadingRepository.AnyAsync(t => t.RequestReReadingType == RequestReReadingType.DocotorApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default &&
  t.OriginalReReadingTask.VisitTaskNum >= subjectVisit.VisitNum && t.OriginalReReadingTask.SubjectId == subjectVisit.SubjectId && t.OriginalReReadingTask.TrialReadingCriterionId == command.TrialReadingCriterionId))
            {
                isIRAppyTaskInfluenced = true;
            }

            var list = await _visitTaskRepository.Where(filterExpression)

               .OrderBy(t => t.VisitTaskNum).ProjectTo<InfluenceTaskInfo>(_mapper.ConfigurationProvider).ToListAsync();
            foreach (var influenceTask in list)
            {

                //重阅重置或者失效
                influenceTask.OptType = influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned ? ReReadingOrBackOptType.Return : ReReadingOrBackOptType.Abandon;
            }


            return (list, new { IsIRAppyTaskInfluenced = isIRAppyTaskInfluenced });
        }

        private async Task<Expression<Func<VisitTask, bool>>> GetTaskExpressionAsync(CriteriaVisitBackCommand command)
        {
            var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == command.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException();

            var subjectVisit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == command.SubjectVisitId);

            //仅仅影响该标准自己的任务
            Expression<Func<VisitTask, bool>> filterExpression = t => t.TrialId == command.TrialId && t.SubjectId == command.SubjectId && t.TaskState == TaskState.Effect /*&& t.TaskAllocationState == TaskAllocationState.Allocated*/
            && t.TrialReadingCriterionId == command.TrialReadingCriterionId;

            //有序
            if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
            {
                filterExpression = filterExpression.And(t => t.VisitTaskNum >= subjectVisit.VisitNum);
            }
            else
            {
                filterExpression = filterExpression.And(t => t.VisitTaskNum == subjectVisit.VisitNum);
            }

            return filterExpression;
        }

        /// <summary>
        ///  退回任务
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public async Task ConfirmBackCriteriaVisitTask(CriteriaVisitBackCommand command)
        {

            var filterExpression = await GetTaskExpressionAsync(command);

            var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync();

            var subjectVisit = await _subjectVisitRepository.FindAsync(command.SubjectVisitId);

            foreach (var influenceTask in influenceTaskList)
            {

                if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned)
                {
                    influenceTask.TaskState = TaskState.HaveReturned;
                }
                else
                {
                    influenceTask.TaskState = TaskState.Adbandon;
                }
            }

            var taskIdList = influenceTaskList.Select(t => t.Id).ToList();
            var subjectVisitIdLsit = influenceTaskList.Where(t => t.SourceSubjectVisitId != null).Select(t => t.SourceSubjectVisitId).ToList();

            if (subjectVisitIdLsit.Count == 0)
            {
                subjectVisitIdLsit.Add(command.SubjectVisitId);
            }

            //医学审核任务失效
            await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(t => taskIdList.Contains(t.VisitTaskId) && t.AuditState != MedicalReviewAuditState.HaveSigned, u => new TaskMedicalReview() { IsInvalid = true });

            //将筛选的访视 序列状态重置


            //当前申请影像回退的访视  筛选状态重置，任务生成状态重置


            var otherVisitIdList = subjectVisitIdLsit.Where(t => t != command.SubjectVisitId).ToList();

            await _subjectCriteriaEvaluationVisitFilterRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.SubjectId == command.SubjectId && t.SubjectVisitId == command.SubjectVisitId,
                t => new SubjectCriteriaEvaluationVisitFilter()
                {
                    ImageFilterState = ImageFilterState.None,
                    ImageDeterminationResultState = ImageDeterminationResultState.None,
                    IsGeneratedTask = false
                });

            //删除序列数据
            await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.SubjectVisitId == command.SubjectVisitId);

            //BM后续访视 ，筛选状态不变，任务生成状态重置（实际该访视任务状态 可能是重阅重置了或者失效了，需要后续生成，或者取消分配了，需要后续重新分配）
            await _subjectCriteriaEvaluationVisitFilterRepository.BatchUpdateNoTrackingAsync(t => t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.SubjectId == command.SubjectId && otherVisitIdList.Contains(t.SubjectVisitId),
                t => new SubjectCriteriaEvaluationVisitFilter()
                {
                    IsGeneratedTask = false
                });




            await _visitTaskRepository.SaveChangesAsync();
        }
    }
}
