//--------------------------------------------------------------------
//     此代码由T4模板自动生成  byzhouhang 20210918
//	   生成时间 2022-06-07 14:10:49 
//     对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------

using IRaCIS.Core.Domain.Models;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Infra.EFCore.Common;
using System.Linq.Expressions;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using DocumentFormat.OpenXml.Office2010.Word;
using System.Linq.Dynamic.Core;
using System.Linq;
using DocumentFormat.OpenXml.Bibliography;
using Org.BouncyCastle.Crypto;
using IRaCIS.Core.Domain.Share.Reading;
using Quartz;
using IRaCIS.Application.Services.BackGroundJob;
using Magicodes.ExporterAndImporter.Core.Extension;
using Hangfire;

namespace IRaCIS.Core.Application.Service.Allocation
{
    /// <summary>
    /// 访视读片任务
    /// </summary>	
    [ApiExplorerSettings(GroupName = "Trial")]
    public class VisitTaskService : BaseService, IVisitTaskService
    {

        private readonly IRepository<VisitTask> _visitTaskRepository;
        private readonly IRepository<Trial> _trialRepository;
        private readonly IRepository<SubjectVisit> _subjectVisitRepository;
        private readonly IRepository<Subject> _subjectRepository;
        private readonly IRepository<ReadModule> _readModuleRepository;

        private readonly IRepository<VisitTaskReReading> _visitTaskReReadingRepository;
        private readonly IRepository<TaskMedicalReview> _taskMedicalReviewRepository;
        private readonly IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository;

        private readonly IRepository<ReadingClinicalData> _readingClinicalDataReposiotry;


        private readonly IRepository<ReadingQuestionCriterionTrial> _trialReadingCriterionRepository;

        private readonly IRepository<PIAudit> _PIAuditRepository;

        public VisitTaskService(IRepository<SubjectVisit> subjectVisitRepository, IRepository<VisitTask> visitTaskRepository, IRepository<Trial> trialRepository,
            IRepository<Subject> subjectRepository,
            IRepository<ReadModule> readModuleRepository, IRepository<VisitTaskReReading> visitTaskReReadingRepository,
             IRepository<TaskMedicalReview> taskMedicalReviewRepository,
            IRepository<ReadingTaskQuestionAnswer> readingTaskQuestionAnswerRepository
            , IRepository<ReadingQuestionCriterionTrial> trialReadingCriterionRepository,
            IRepository<ReadingClinicalData> readingClinicalDataReposiotry,
            IRepository<PIAudit> PIAuditRepository
            )
        {
            _PIAuditRepository = PIAuditRepository;
            _readingClinicalDataReposiotry = readingClinicalDataReposiotry;
            _visitTaskRepository = visitTaskRepository;
            _trialRepository = trialRepository;
            _subjectVisitRepository = subjectVisitRepository;
            _subjectRepository = subjectRepository;
            _readModuleRepository = readModuleRepository;
            _visitTaskReReadingRepository = visitTaskReReadingRepository;
            _taskMedicalReviewRepository = taskMedicalReviewRepository;
            _readingTaskQuestionAnswerRepository = readingTaskQuestionAnswerRepository;
            _trialReadingCriterionRepository = trialReadingCriterionRepository;

        }

        /// <summary>
        /// 设置任务加急
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<bool> SetTaskUrgent(SetTaskUrgentInDto inDto)
        {
            await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask()
            {
                IsUrgent = inDto.IsUrgent,
                TaskUrgentType = inDto.TaskUrgentType,
                TaskUrgentRemake = inDto.TaskUrgentRemake,

            });

            return await _visitTaskRepository.SaveChangesAsync();
        }

        public async Task<List<TrialReadingCriterionDto>> GetTrialCriterionList(Guid trialId, bool isHaveSigned = true, bool? isAutoCreate = null)
        {
            var list = await _repository.Where<ReadingQuestionCriterionTrial>(t => t.TrialId == trialId && t.IsConfirm)

                .OrderBy(t => t.ShowOrder)
                .Select(t => new TrialReadingCriterionDto() { TrialReadingCriterionId = t.Id, IsAutoCreate = t.IsAutoCreate, IsAdditionalAssessment = t.IsAdditionalAssessment, TrialReadingCriterionName = t.CriterionName, CriterionType = t.CriterionType, ReadingType = t.ReadingType, ReadingInfoSignTime = t.ReadingInfoSignTime })
                .ToListAsync();

            return list.AsQueryable().WhereIf(isHaveSigned == true, t => t.ReadingInfoSignTime != null)
                 .WhereIf(isAutoCreate == false, t => t.IsAutoCreate == isAutoCreate).ToList();
        }


        /// <summary>
        /// 获取项目下 阅片人下拉
        /// </summary>
        /// <param name="trialId"></param>
        /// <returns></returns>
        [HttpGet("{trialId:guid}")]
        public async Task<List<TrialDoctorUserSelectView>> GetTrialDoctorUserSelectList(Guid trialId)
        {
            var query = from trialUser in _trialRepository.Where(t => t.Id == trialId).SelectMany(t => t.TrialUserList).Where(t => t.User.UserTypeEnum == UserTypeEnum.SR || t.User.UserTypeEnum == UserTypeEnum.PI)

                        select new TrialDoctorUserSelectView()
                        {
                            TrialId = trialUser.TrialId,
                            //ReadingType = enroll.Trial.ReadingType,
                            DoctorUserId = trialUser.UserId,
                            FullName = trialUser.User.FullName,
                            UserCode = trialUser.User.UserCode,
                            UserName = trialUser.User.UserName,
                            UserTypeEnum = trialUser.User.UserTypeRole.UserTypeEnum
                        };

            return await query.ToListAsync();
        }

        /// <summary>
        /// 访视任务
        /// </summary>
        /// <param name="queryVisitTask"></param>
        /// <param name="_visitTaskCommonService"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageOutput<VisitTaskView>> GetVisitTaskList(VisitTaskQuery queryVisitTask, [FromServices] IVisitTaskHelpeService _visitTaskCommonService)
        {
            //以前访视未产生任务的,在查询这里要产生 
            var svIdList = await _subjectVisitRepository.Where(t => t.TrialId == queryVisitTask.TrialId && t.CheckState == CheckStateEnum.CVPassed && t.IsVisitTaskGenerated == false).Select(t => t.Id).ToListAsync();

            //之前没有生成任务的逻辑 但是现在加了,任务要自动生成
            await _visitTaskCommonService.GenerateVisitTaskAsync(queryVisitTask.TrialId, svIdList);


            var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId && t.IsAnalysisCreate == false)
                .WhereIf(queryVisitTask.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory)
                .WhereIf(queryVisitTask.ReadingCategory == null, t => t.ReadingCategory != ReadingCategory.Judge)

                .WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState)
                .WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId)
                .WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId)
                .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
                .WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId)
                .WhereIf(queryVisitTask.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory)
                .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.TaskAllocationState == queryVisitTask.TaskAllocationState)
                .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId)

                 .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate == false))
                .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.TaskName.Contains(queryVisitTask.TaskName) || t.TaskBlindName.Contains(queryVisitTask.TaskName))

                .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => (t.Subject.Code.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate))
                .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate)
                .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1))
                .ProjectTo<VisitTaskView>(_mapper.ConfigurationProvider);

            var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) };

            var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray);

            //var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo<TrialTaskConfigView>(_mapper.ConfigurationProvider).FirstOrDefault();
            return pageList;
        }



        private IQueryable<VisitTask> GetReadingTaskQueryable(VisitTaskQuery queryVisitTask)
        {
            var trialConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).Select(t => new { t.EnrollConfirmDefaultUserType, t.PDProgressDefaultUserType }).FirstOrDefault();

            var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId && t.IsAnalysisCreate == false)

               .WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState)
               .WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId)
               .WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId)
               .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
               .WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId)
               .WhereIf(queryVisitTask.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory)
               .WhereIf(queryVisitTask.ReadingTaskState != null, t => t.ReadingTaskState == queryVisitTask.ReadingTaskState)
               .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.TaskAllocationState == queryVisitTask.TaskAllocationState)
               .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId)
               .WhereIf(queryVisitTask.ReReadingApplyState != null, t => t.ReReadingApplyState == queryVisitTask.ReReadingApplyState)


                .WhereIf(queryVisitTask.CompleteClinicalDataEnum == CompleteClinicalDataEnum.Complete, t => t.IsClinicalDataSign && t.IsNeedClinicalDataSign == true)
                .WhereIf(queryVisitTask.CompleteClinicalDataEnum == CompleteClinicalDataEnum.NotComplete, t => t.IsClinicalDataSign == false && t.IsNeedClinicalDataSign == true)
                .WhereIf(queryVisitTask.CompleteClinicalDataEnum == CompleteClinicalDataEnum.NA, t => t.IsNeedClinicalDataSign == false)
               .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate == false))
               .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.TaskName.Contains(queryVisitTask.TaskName) || t.TaskBlindName.Contains(queryVisitTask.TaskName))
               .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => (t.Subject.Code.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate))
               .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate)
               .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1))

               .WhereIf(trialConfig?.EnrollConfirmDefaultUserType == UserTypeEnum.MIM && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.MIM, t => t.SourceSubjectVisit.IsBaseLine == true)
               .WhereIf(trialConfig?.PDProgressDefaultUserType == UserTypeEnum.MIM && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.MIM, t => t.SourceSubjectVisit.IsBaseLine == false)
                .WhereIf(queryVisitTask.IsWaitPIAudit == true, t => t.FirstAuditUserId == null)
                .WhereIf(queryVisitTask.IsWaitPIAudit == false, t => t.FirstAuditUserId != null)
                .WhereIf(queryVisitTask.PIAuditState != null, t => t.PIAuditState == queryVisitTask.PIAuditState)
               .WhereIf(queryVisitTask.FirstAuditTimeBegin != null, t => t.AllocateTime > queryVisitTask.FirstAuditTimeBegin)
               .WhereIf(queryVisitTask.FirstAuditTimeEnd != null, t => t.AllocateTime < queryVisitTask.FirstAuditTimeEnd)
               .WhereIf(queryVisitTask.LatestReplyTimeBegin != null, t => t.AllocateTime > queryVisitTask.LatestReplyTimeBegin)
               .WhereIf(queryVisitTask.LatestReplyTimeEnd != null, t => t.AllocateTime < queryVisitTask.LatestReplyTimeEnd);

            return visitTaskQueryable;
        }

        [HttpPost]
        public async Task<IResponseOutput<PageOutput<PIReaingTaskView>>> GetPIReadingAuditList(VisitTaskQuery queryVisitTask)
        {

            var visitTaskQueryable = GetReadingTaskQueryable(queryVisitTask)
               .ProjectTo<PIReaingTaskView>(_mapper.ConfigurationProvider);

            var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) };

            var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray);

            var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo<TrialUrgentConfig>(_mapper.ConfigurationProvider).FirstOrDefault();

            return ResponseOutput.Ok(pageList, trialTaskConfig);
        }


        /// <summary>
        ///new-  首次审核 后续编辑审核
        /// </summary>
        /// <param name="incommand"></param>
        /// <returns></returns>
        [HttpPost]

        public async Task<IResponseOutput> PIAuditTask(PIAuditTaskCommand incommand)
        {
            //需要设置首次审核时间 审核人
            var visitTask = await _visitTaskRepository.FirstOrDefaultAsync(t => t.Id == incommand.VisitTaskId);
            var isFirstAudit = visitTask.FirstAuditUserId == null;

            visitTask.NotAgreeReason = incommand.NotAgreeReason;
            visitTask.PIAuditNote = incommand.PIAuditNote;
            visitTask.PIAuditImagePath = string.Join('|', incommand.PIAuditImagePathList);
            visitTask.PIAuditState = incommand.PIAuditState;

            visitTask.LatestReplyUserId = _userInfo.Id;
            visitTask.LatestReplyTime = DateTime.Now;
            visitTask.IsEnrollment = incommand.PIAuditState == PIAuditState.PINotAgree ? null : visitTask.IsEnrollment;
            visitTask.IsPDConfirm = incommand.PIAuditState == PIAuditState.PINotAgree ? null : visitTask.IsPDConfirm;

            if (isFirstAudit)
            {
                visitTask.FirstAuditUserId = _userInfo.Id;
                visitTask.FirstAuditTime = DateTime.Now;
            }

            //发送对话
            var addDialig = _mapper.Map<PIAudit>(incommand);

            addDialig.PIAuditImagePath = visitTask.PIAuditImagePath;

            await _PIAuditRepository.AddAsync(addDialig);

            await _visitTaskRepository.SaveChangesAsync();

            return ResponseOutput.Ok();

        }


        [HttpPost]
        [UnitOfWork]
        public async Task<IResponseOutput> PIAuditTaskEnrollOrPD(PIAuditTaskEnrollOrPdCommand incommand, [FromServices] ITrialEmailNoticeConfigService trialEmailNoticeConfigService)
        {
            var visitTask = await _visitTaskRepository.FirstOrDefaultAsync(t => t.Id == incommand.VisitTaskId);
            visitTask.IsEnrollment = incommand.IsEnrollment != null ? incommand.IsEnrollment : visitTask.IsEnrollment;
            visitTask.IsPDConfirm = incommand.IsPDConfirm != null ? incommand.IsPDConfirm : visitTask.IsPDConfirm;
            visitTask.LatestReplyUserId = _userInfo.Id;
            visitTask.LatestReplyTime = DateTime.Now;

            await _visitTaskRepository.SaveChangesAsync();

            await trialEmailNoticeConfigService.CommonBusinessScenarioSendEmailAsync(visitTask.Id, incommand.IsEnrollment, incommand.IsPDConfirm);

            return ResponseOutput.Ok();
        }

        /// <summary>
        ///new-  回复审核内容
        /// </summary>
        /// <param name="incommand"></param>
        /// <returns></returns>
        public async Task<IResponseOutput> PIAuditTaskReply(PIAuditTaskReplyCommand incommand)
        {
            await _PIAuditRepository.AddAsync(new PIAudit() { ReplyContent = incommand.ReplyContent, VisitTaskId = incommand.VisitTaskId });

            await _PIAuditRepository.SaveChangesAsync();

            return ResponseOutput.Ok();
        }

        /// <summary>
        /// new- 获取审核对话列表
        /// </summary>
        /// <param name="inQuery"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<PIAuditDialogListView>> GetPIAuditDialogList(PIAuditDialogQuery inQuery)
        {


            var list = await _PIAuditRepository.Where(t => t.VisitTaskId == inQuery.VisitTaskId).OrderBy(t => t.CreateTime).ProjectTo<PIAuditDialogListView>(_mapper.ConfigurationProvider).ToListAsync();

            foreach (var item in list)
            {
                item.IsCurrentUser = item.CreateUserId == _userInfo.Id;
            }
            return list;
        }


        public async Task<IResponseOutput> AddClinicalDataDialog(Guid visiTaskId, string content,
            [FromServices] IRepository<SubjectVisitClinicalDialog> subjectVisitClinicalDialogRepository,
            [FromServices] IEmailSendService emailSendService)
        {
            var taskInfo = await _visitTaskRepository.Where(t => t.Id == visiTaskId).Select(t => new { t.SourceSubjectVisitId, t.Subject.Code, t.SourceSubjectVisit.VisitName, t.Trial.ResearchProgramNo, t.Trial.TrialCode }).FirstOrDefaultAsync();

            await subjectVisitClinicalDialogRepository.AddAsync(new SubjectVisitClinicalDialog() { SubjectVisitId = (Guid)taskInfo.SourceSubjectVisitId, Content = content }, true);

            BackgroundJob.Enqueue(   () =>  emailSendService.SendClinicalDataQuestionAsync(visiTaskId, content).Wait());

            return ResponseOutput.Ok();
        }

        public async Task<List<ClinicalDataDialog>> GetClinicalDataDialog(Guid visiTaskId,
             [FromServices] IRepository<SubjectVisitClinicalDialog> _subjectVisitClinicalDialogRepository)
        {
            var subjectVisitId= await _visitTaskRepository.Where(t => t.Id == visiTaskId).Select(t=>t.SourceSubjectVisitId).FirstOrDefaultAsync();
            var list = _subjectVisitClinicalDialogRepository.Where(t => t.SubjectVisitId == subjectVisitId).ProjectTo<ClinicalDataDialog>(_mapper.ConfigurationProvider).OrderByDescending(t => t.CreateTime).ToList();

            return list;
        }


        /// <summary>
        /// PM阅片跟踪
        /// </summary>
        /// <param name="queryVisitTask"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput<PageOutput<ReadingTaskView>>> GetReadingTaskList(VisitTaskQuery queryVisitTask)
        {
            var visitTaskQueryable = GetReadingTaskQueryable(queryVisitTask)
               .ProjectTo<ReadingTaskView>(_mapper.ConfigurationProvider);

            var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) };

            var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray);

            var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo<TrialUrgentConfig>(_mapper.ConfigurationProvider).FirstOrDefault();

            return ResponseOutput.Ok(pageList, trialTaskConfig);
        }





        /// <summary>
        /// PM 重阅追踪 
        /// </summary>
        /// <param name="queryVisitTask"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageOutput<ReReadingTaskView>> GetReReadingTaskList(VisitTaskQuery queryVisitTask)
        {


            var visitTaskQueryable = _visitTaskReReadingRepository
                .Where(t => t.OriginalReReadingTask.TrialId == queryVisitTask.TrialId /*&& t.OriginalReReadingTask.IsAnalysisCreate == false*/)
                .WhereIf(queryVisitTask.RootReReadingTaskId != null, t => t.RootReReadingTaskId == queryVisitTask.RootReReadingTaskId || t.OriginalReReadingTaskId == queryVisitTask.RootReReadingTaskId)
                .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!))
                .WhereIf(queryVisitTask.SiteId != null, t => t.OriginalReReadingTask.Subject.SiteId == queryVisitTask.SiteId)
                .WhereIf(queryVisitTask.TaskState != null, t => t.OriginalReReadingTask.TaskState == queryVisitTask.TaskState)
                .WhereIf(queryVisitTask.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == queryVisitTask.ReReadingApplyState)
                 .WhereIf(queryVisitTask.RequestReReadingType != null, t => t.RequestReReadingType == queryVisitTask.RequestReReadingType)
                .WhereIf(queryVisitTask.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == queryVisitTask.SubjectId)
                .WhereIf(queryVisitTask.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == queryVisitTask.IsUrgent)
                .WhereIf(queryVisitTask.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == queryVisitTask.DoctorUserId)
                .WhereIf(queryVisitTask.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == queryVisitTask.ReadingTaskState)
                .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == queryVisitTask.TaskAllocationState)
                .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId)
                .WhereIf(queryVisitTask.ReadingCategory != null, t => t.OriginalReReadingTask.ReadingCategory == queryVisitTask.ReadingCategory)

                .WhereIf(queryVisitTask.RequestReReadingResultEnum != null, t => t.RequestReReadingResultEnum == queryVisitTask.RequestReReadingResultEnum)

                 .WhereIf(queryVisitTask.PIAuditState != null, t => t.OriginalReReadingTask.PIAuditState == queryVisitTask.PIAuditState)
                 .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false))
                .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(queryVisitTask.TaskName) || t.OriginalReReadingTask.TaskBlindName.Contains(queryVisitTask.TaskName))
                .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => (t.OriginalReReadingTask.Subject.Code.Contains(queryVisitTask.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate))
                .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > queryVisitTask.BeginAllocateDate)
                .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1))
                .ProjectTo<ReReadingTaskView>(_mapper.ConfigurationProvider);

            //var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectId), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) };

            var defalutSortArray = new string[] {
                nameof(ReReadingTaskView.RequestReReadingResultEnum) ,
                nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc",
                nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.TaskState),
                nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectId),nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) };



            var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray);

            return pageList;
        }


        /// <summary>
        /// 获取IR 重阅影像阅片列表 
        /// </summary>
        /// <param name="queryVisitTask"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageOutput<ReReadingTaskView>> GetIRReReadingTaskList(VisitTaskQuery queryVisitTask)
        {

            var visitTaskQueryable = _visitTaskReReadingRepository
                .Where(t => t.RequestReReadingType == RequestReReadingType.DocotorApply)
                .Where(t => t.OriginalReReadingTask.DoctorUserId == _userInfo.Id)
                .Where(t => t.OriginalReReadingTask.TrialId == queryVisitTask.TrialId)

                .WhereIf(queryVisitTask.RootReReadingTaskId != null, t => t.RootReReadingTaskId == queryVisitTask.RootReReadingTaskId || t.OriginalReReadingTaskId == queryVisitTask.RootReReadingTaskId)
                .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!))
                .WhereIf(queryVisitTask.TaskState != null, t => t.OriginalReReadingTask.TaskState == queryVisitTask.TaskState)
                 .WhereIf(queryVisitTask.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == queryVisitTask.ReReadingApplyState)
                .WhereIf(queryVisitTask.SiteId != null, t => t.OriginalReReadingTask.Subject.SiteId == queryVisitTask.SiteId)
                .WhereIf(queryVisitTask.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == queryVisitTask.SubjectId)
                .WhereIf(queryVisitTask.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == queryVisitTask.IsUrgent)
                .WhereIf(queryVisitTask.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == queryVisitTask.DoctorUserId)
                .WhereIf(queryVisitTask.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == queryVisitTask.ReadingTaskState)
                .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == queryVisitTask.TaskAllocationState)
                 .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId)


                 .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false))
                .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(queryVisitTask.TaskName) || t.NewReReadingTask.TaskBlindName.Contains(queryVisitTask.TaskName))
                .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => (t.OriginalReReadingTask.Subject.Code.Contains(queryVisitTask.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate))
                .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > queryVisitTask.BeginAllocateDate)
                .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1))
                .ProjectTo<ReReadingTaskView>(_mapper.ConfigurationProvider);



            var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectId), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) };

            var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray);

            return pageList;
        }


        /// <summary>
        /// IR  待阅片任务列表
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<(PageOutput<IRUnReadSubjectView>, object)> GetIRUnReadSubjectTaskList(IRUnReadSubjectQuery iRUnReadSubjectQuery)
        {

            var trialId = iRUnReadSubjectQuery.TrialId;

            var trialReadingCriterionId = iRUnReadSubjectQuery.TrialReadingCriterionId;

            var critrion = await _trialReadingCriterionRepository.Where(x => x.Id == iRUnReadSubjectQuery.TrialReadingCriterionId).FirstNotNullAsync();

            var readingTool = critrion.ReadingTool;
            var isReadingTaskViewInOrder = critrion.IsReadingTaskViewInOrder;

            #region 按照Subject 维度
            if (isReadingTaskViewInOrder)
            {


                var visitTaskListInfo = await GetOrderReadingIQueryable(new GetOrderReadingIQueryableInDto()
                {
                    TrialId = trialId,
                    TrialReadingCriterionId = trialReadingCriterionId,
                    SubjectCode = iRUnReadSubjectQuery.SubjectCode,
                    Page = new PageInput()
                    {
                        PageIndex = iRUnReadSubjectQuery.PageIndex,
                        PageSize = iRUnReadSubjectQuery.PageSize,
                        Asc = iRUnReadSubjectQuery.Asc,
                        SortField = iRUnReadSubjectQuery.SortField,

                    }

                });


                var totalCount = visitTaskListInfo.Item1;
                var currentPageData = visitTaskListInfo.Item2;



                var result = new PageOutput<IRUnReadSubjectView>()
                {
                    PageSize = iRUnReadSubjectQuery.PageSize,
                    PageIndex = iRUnReadSubjectQuery.PageIndex,
                    TotalCount = totalCount,
                    CurrentPageData = currentPageData,
                };

                // 封装的方法有问题
                //var result = await visitQuery.ToPagedListAsync(iRUnReadSubjectQuery.PageIndex, iRUnReadSubjectQuery.PageSize, String.IsNullOrEmpty(iRUnReadSubjectQuery.SortField) ? nameof(IRUnReadSubjectView.SubjectId) : iRUnReadSubjectQuery.SortField, iRUnReadSubjectQuery.Asc);
                return (result, new
                {
                    RandomReadInfo = new IRUnReadOutDto(),
                    IsReadingTaskViewInOrder = isReadingTaskViewInOrder,
                    ReadingTool = readingTool,
                    IseCRFShowInDicomReading = critrion.IseCRFShowInDicomReading,
                    IsReadingShowSubjectInfo = critrion.IsReadingShowSubjectInfo,
                    IsReadingShowPreviousResults = critrion.IsReadingShowPreviousResults,
                    DigitPlaces = critrion.DigitPlaces,
                    CriterionType = critrion.CriterionType,
                });
            }
            else
            {




                var taskQuery = await GetNotOrderReadingQueryableAsync(iRUnReadSubjectQuery.TrialId, trialReadingCriterionId);


                IRUnReadOutDto iRUnReadOut = new IRUnReadOutDto()
                {
                    FinishTaskCount = await taskQuery.Where(x => x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).CountAsync(),
                    SuggesteFinishedTime = await taskQuery.Where(x => x.ReadingTaskState != ReadingTaskState.HaveSigned).MaxAsync(x => x.SuggesteFinishedTime),

                    UnReadTaskCount = await taskQuery.Where(x => x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState != ReadingTaskState.HaveSigned).CountAsync(),
                };

                var result = new PageOutput<IRUnReadSubjectView>()
                {
                    PageSize = iRUnReadSubjectQuery.PageSize,
                    PageIndex = iRUnReadSubjectQuery.PageIndex,
                };

                return (result, new
                {
                    IsReadingTaskViewInOrder = isReadingTaskViewInOrder,
                    RandomReadInfo = iRUnReadOut,
                    ReadingTool = readingTool,
                    IseCRFShowInDicomReading = critrion.IseCRFShowInDicomReading,
                    IsReadingShowSubjectInfo = critrion.IsReadingShowSubjectInfo,
                    IsReadingShowPreviousResults = critrion.IsReadingShowPreviousResults,
                    DigitPlaces = critrion.DigitPlaces,
                    CriterionType = critrion.CriterionType,
                });

            }



            #endregion


        }


        public async Task<IQueryable<VisitTask>> GetNotOrderReadingQueryableAsync(Guid trialId, Guid trialReadingCriterionId)
        {
            var critrion = await _trialReadingCriterionRepository.FindAsync(trialReadingCriterionId);

            var readingDivisionEnum = critrion.ReadingDivisionEnum;

            var piReadingScopenEnum = critrion.PIReadingScopenEnum;

            var taskQuery = _visitTaskRepository.Where(x => x.TrialId == trialId /*&& x.DoctorUserId == _userInfo.Id*/ && x.TaskState == TaskState.Effect && x.TrialReadingCriterionId == trialReadingCriterionId)

                     .Where(x => (x.IsNeedClinicalDataSign && x.IsClinicalDataSign) || !x.IsNeedClinicalDataSign)
                      .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR, t => t.Subject.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.Id))
              // 仅仅SR阅片 PI 没有任务列表
              .WhereIf(readingDivisionEnum == ReadingDivisionEnum.OnlySR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI, t => t.TrialId == Guid.Empty)


               .WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI && piReadingScopenEnum == PIReadingScopenEnum.AllBaseline,
               t => t.SourceSubjectVisit.IsBaseLine == true)

                //PI 阅片所有
                .WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI && piReadingScopenEnum == PIReadingScopenEnum.AllBaselineandVisit,
               t => true)

                 .WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI && piReadingScopenEnum == PIReadingScopenEnum.AllVisit,
               t => t.SourceSubjectVisit.IsBaseLine == false)

                  .WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR && piReadingScopenEnum == PIReadingScopenEnum.AllBaseline,
               t => t.SourceSubjectVisit.IsBaseLine == false)

                   //SR 不阅片
                   .WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR && piReadingScopenEnum == PIReadingScopenEnum.AllBaselineandVisit,
               t => t.TrialId == Guid.Empty)

               .WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR && piReadingScopenEnum == PIReadingScopenEnum.AllVisit,
               t => t.SourceSubjectVisit.IsBaseLine == true);

            return taskQuery;
        }

        /// <summary>
        /// 获取有序阅片IQuery对象
        /// </summary>
        /// <param name="inDto"></param>

        /// <returns></returns>
        public async Task<(int, List<IRUnReadSubjectView>)> GetOrderReadingIQueryable(GetOrderReadingIQueryableInDto inDto)
        {
            var trialReadingCriterionId = inDto.TrialReadingCriterionId;

            //Expression<Func<VisitTask, bool>> visitTaskLambda = x => x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect && x.TrialReadingCriterionId == inDto.TrialReadingCriterionId;

            var critrion = await _trialReadingCriterionRepository.FindAsync(trialReadingCriterionId);

            var readingDivisionEnum = critrion.ReadingDivisionEnum;

            var piReadingScopenEnum = critrion.PIReadingScopenEnum;

            var visitQuery = _visitTaskRepository
                .Where(x => x.TrialId == inDto.TrialId && x.TaskState == TaskState.Effect)

                //PI 读基线的时候,subject 如果PI基线没阅片完,SR就不能看
                .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR && piReadingScopenEnum == PIReadingScopenEnum.AllBaseline,
                t => t.Subject.SubjectVisitTaskList.Any(c => c.SourceSubjectVisit.IsBaseLine == true && c.ReadingTaskState == ReadingTaskState.HaveSigned && c.TaskState == TaskState.Effect && c.TrialReadingCriterionId == trialReadingCriterionId))

                //PI 读随访的时候, subject 如果SR基线没阅片完,PI就不能看
                .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI && piReadingScopenEnum == PIReadingScopenEnum.AllVisit,
                t => t.Subject.SubjectVisitTaskList.Any(c => c.SourceSubjectVisit.IsBaseLine == true && c.ReadingTaskState == ReadingTaskState.HaveSigned && c.TaskState == TaskState.Effect && c.TrialReadingCriterionId == trialReadingCriterionId))



                .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR, t => t.Subject.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.Id))
                // 仅仅SR阅片 PI 没有任务列表
                .WhereIf(readingDivisionEnum == ReadingDivisionEnum.OnlySR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI, t => t.TrialId == Guid.Empty)


                 .WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI && piReadingScopenEnum == PIReadingScopenEnum.AllBaseline,
                 t => t.SourceSubjectVisit.IsBaseLine == true)

                  //PI 阅片所有
                  .WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI && piReadingScopenEnum == PIReadingScopenEnum.AllBaselineandVisit,
                 t => true)

                   .WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI && piReadingScopenEnum == PIReadingScopenEnum.AllVisit,
                 t => t.SourceSubjectVisit.IsBaseLine == false)

                    .WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR && piReadingScopenEnum == PIReadingScopenEnum.AllBaseline,
                 t => t.SourceSubjectVisit.IsBaseLine == false)

                     //SR 不阅片
                     .WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR && piReadingScopenEnum == PIReadingScopenEnum.AllBaselineandVisit,
                 t => t.TrialId == Guid.Empty)

                 .WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR && piReadingScopenEnum == PIReadingScopenEnum.AllVisit,
                 t => t.SourceSubjectVisit.IsBaseLine == true)


                // 前序 不存在 未一致性核查未通过的  并且前序不存在未完成阅片的有效任务
                .Where(t => !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum > sv.VisitNum))

                //.WhereIf(piReadingScopenEnum == PIReadingScopenEnum.AllVisit,t => 
                //  !t.Subject.SubjectVisitTaskList.Any(tk => tk.ReadingTaskState != ReadingTaskState.HaveSigned && tk.TaskState == TaskState.Effect && tk.VisitTaskNum < t.VisitTaskNum))

                .WhereIf(!string.IsNullOrEmpty(inDto.SubjectCode), t => (t.Subject.Code.Contains(inDto.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inDto.SubjectCode) && t.IsAnalysisCreate));


            var visitGroupQuery = visitQuery.GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode, x.SubjectCriterionClaimUserId, x.SubjectCriterionClaimUser.UserName });

            var visitTaskQuery = visitGroupQuery.Select(x => new IRUnReadSubjectView()
            {
                SubjectId = x.Key.SubjectId,
                SubjectCode = x.Key.BlindSubjectCode == string.Empty ? x.Key.Code : x.Key.BlindSubjectCode,

                ClaimUserId = x.Key.SubjectCriterionClaimUserId,
                ClaimUserName = x.Key.UserName,

                SuggesteFinishedTime = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Min(x => x.SuggesteFinishedTime),

                //未读任务量
                UnReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Count(),

                //未读 里可读任务量   
                UnReadCanReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned && y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)

                ).Count(),


                //已读任务量
                HaveReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState == ReadingTaskState.HaveSigned).Count(),

                ExistReadingApply = x.Any(y => (y.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed && y.TrialReadingCriterionId == trialReadingCriterionId) || y.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed),

                //查出所有未读的  未读的可读的  在这个列表基础上 过滤下   y.IsFrontTaskNeedSignButNotSign==false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)  这样容易排错 确认这三个字段是否维护有误
                UnReadTaskList = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).OrderBy(x => x.VisitTaskNum)
                .Select(u => new IRUnreadTaskView()
                {
                    Id = u.Id,
                    IsUrgent = u.IsUrgent,
                    VisitNum = u.VisitTaskNum,
                    TaskBlindName = u.TaskBlindName,
                    VisistId = u.SourceSubjectVisitId,
                    SuggesteFinishedTime = u.SuggesteFinishedTime,
                    ReadingCategory = u.ReadingCategory,
                    IsAnalysisCreate = u.IsAnalysisCreate,
                    ArmEnum = u.ArmEnum,
                    TrialReadingCriterionId = u.TrialReadingCriterionId,
                    IsNeedClinicalDataSign = u.IsNeedClinicalDataSign,
                    IsClinicalDataSign = u.IsClinicalDataSign,
                    IsFrontTaskNeedSignButNotSign = u.IsFrontTaskNeedSignButNotSign
                })
                .ToList(),
            }).Where(x => x.UnReadCanReadTaskCount > 0)/*.OrderBy(x => x.UnReadCanReadTaskCount)*/;
            // 有序阅片需要找到最小需要


            // 不这样写会有问题
            var count = visitQuery.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned && y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true))
             .GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode }).Count();

            var result = new List<IRUnReadSubjectView>();

            var propName = string.IsNullOrWhiteSpace(inDto.Page.SortField) ? "UnReadCanReadTaskCount" : inDto.Page.SortField;

            var visitTaskOrderQuery = inDto.Page.Asc ? visitTaskQuery.OrderBy(propName) : visitTaskQuery.OrderBy(propName + " desc");
            if (inDto.Page != null)
            {
                result = await visitTaskOrderQuery
                     .Skip((inDto.Page.PageIndex - 1) * inDto.Page.PageSize)
                     .Take(inDto.Page.PageSize).ToListAsync();
            }
            else
            {
                result = await visitTaskOrderQuery.ToListAsync();
            }


            return (count, result);
        }


        /// <summary>
        /// IR  已阅片任务
        /// </summary>
        /// <param name="queryVisitTask"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageOutput<IRHaveReadView>> GetIRHaveReadTaskList(VisitTaskQuery queryVisitTask)
        {


            var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId)
                 .Where(t => t.DoctorUserId == _userInfo.Id && t.ReadingTaskState == ReadingTaskState.HaveSigned)//该医生 已经签名的数据


                .WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId)
                .WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId)
                .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
                .WhereIf(queryVisitTask.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory)
                .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.TaskAllocationState == queryVisitTask.TaskAllocationState)
                .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId)

                .WhereIf(queryVisitTask.PIAuditState != null, t => t.PIAuditState == queryVisitTask.PIAuditState)
                .WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState)
                .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate == false))
                .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.TaskName.Contains(queryVisitTask.TaskName) || t.TaskBlindName.Contains(queryVisitTask.TaskName))
                .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => (t.Subject.Code.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate))
                .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate)
                .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1))
                .ProjectTo<IRHaveReadView>(_mapper.ConfigurationProvider);

            var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) };

            var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray);

            return pageList;
        }



        [HttpPost]
        [UnitOfWork]
        public async Task<IResponseOutput> AIRReReading(AIRReReadingCommand command, [FromServices] IVisitTaskHelpeService _visitTaskCommonService)
        {
            var baseLineTaskList = await _visitTaskRepository.Where(t => t.TrialId == command.TrialId && t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.DoctorUserId == _userInfo.Id
                 && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.SourceSubjectVisit.IsBaseLine == true).ToListAsync();


            var baseLineTaskIdList = baseLineTaskList.Select(t => t.Id).ToList();

            if (baseLineTaskIdList.Count == 0)
            {
                return ResponseOutput.Ok();
            }

            //if (baseLineTaskList == null)
            //{
            //    return ResponseOutput.NotOk("基线任务未阅完,不允许重阅基线任务");
            //}

            await ApplyReReading(new ApplyReReadingCommand() { IsCopyFollowForms = false, IsCopyOrigenalForms = false, TaskIdList = baseLineTaskIdList, TrialId = command.TrialId, RequestReReadingReason = "AIR自动重阅基线", RequestReReadingType = RequestReReadingType.DocotorApply });



            var requestRecordList = await _visitTaskReReadingRepository.Where(t => baseLineTaskIdList.Contains(t.OriginalReReadingTaskId) && t.RequestReReadingUserId == _userInfo.Id && t.RequestReReadingReason == "AIR自动重阅基线").ToListAsync();

            if (requestRecordList.Count() != baseLineTaskIdList.Count())
            {
                //---后台数据有错误
                return ResponseOutput.NotOk(_localizer["VisitTask_DoctorConfiguration"]);
            }

            await ConfirmReReading(new ConfirmReReadingCommand()
            {
                TrialId = command.TrialId,
                RequestReReadingResultEnum = RequestReReadingResult.Agree,
                //ConfirmReReadingList = new List<ConfirmReReadingDTO>() { new ConfirmReReadingDTO() { Id = requestRecord.Id, OriginalReReadingTaskId = task.Id } }
                ConfirmReReadingList = requestRecordList.Select(t => new ConfirmReReadingDTO() { Id = t.Id, OriginalReReadingTaskId = t.OriginalReReadingTaskId }).ToList()
            }, _visitTaskCommonService);

            return ResponseOutput.Ok();

        }



        /// <summary>
        /// 申请重阅  1:IR  2:PM
        /// </summary>
        /// <param name="applyReReadingCommand"></param>
        /// <returns></returns>
        [HttpPost]
        [UnitOfWork]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]

        public async Task<IResponseOutput> ApplyReReading(ApplyReReadingCommand applyReReadingCommand)
        {


            var taskList = await _visitTaskRepository.Where(t => applyReReadingCommand.TaskIdList.Contains(t.Id), true).ToListAsync();

            var trialReadingCriterionId = taskList.First()!.TrialReadingCriterionId;

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


            foreach (var task in taskList)
            {


                if (task.ReadingTaskState != ReadingTaskState.HaveSigned || (task.TaskState != TaskState.Effect && task.TaskState != TaskState.Freeze))
                {
                    //---未阅片完成,或者未生效的任务不允许申请重阅
                    throw new BusinessValidationFailedException(_localizer["VisitTask_BackendData"]);
                }

                if (task.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || task.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed || task.ReReadingApplyState == ReReadingApplyState.Agree)
                {
                    //---重阅已申请,或者重阅已同意状态下不允许申请重阅
                    throw new BusinessValidationFailedException(_localizer["VisitTask_UnreadTask"]);
                }


                if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI)
                {
                    task.ReReadingApplyState = ReReadingApplyState.DocotorHaveApplyed;

                    // 有序
                    if (criterionConfig.IsReadingTaskViewInOrder)
                    {
                        // 针对同一个subject   不同阅片人 针对同一个访视申请重阅,是允许的,所以同一阅片人,针对同一suject 有访视申请重阅还未处理,不允许申请重阅
                        if (await _visitTaskReReadingRepository.AnyAsync(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect
                                                       && t.OriginalReReadingTask.TrialReadingCriterionId == task.TrialReadingCriterionId
                                                       && t.OriginalReReadingTask.ReadingTaskState == ReadingTaskState.HaveSigned && t.RequestReReadingType == RequestReReadingType.DocotorApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default))
                        {
                            //---当前为有序阅片,该受试者已有访视已申请重阅还未处理,暂不能继续申请重阅
                            throw new BusinessValidationFailedException(_localizer["VisitTask_SequentialReading"]);
                        }

                    }
                    else
                    {
                        if (task.ReadingCategory != ReadingCategory.Visit && task.ReadingCategory != ReadingCategory.Global)
                        {
                            //---无序阅片,仅仅允许IR 申请  全局和访视类型类别的任务进行重阅
                            throw new BusinessValidationFailedException(_localizer["VisitTask_IRGlobalRecheck"]);
                        }
                    }

                }

                //AIR  不加验证
                if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.AIR)
                {
                    task.ReReadingApplyState = ReReadingApplyState.DocotorHaveApplyed;
                }



                var rootReReadingTaskId = _visitTaskReReadingRepository.Where(t => t.NewReReadingTaskId == task.Id).Select(u => u.RootReReadingTaskId).FirstOrDefault();

                //添加申请记录
                var visitTaskReReading = await _visitTaskReReadingRepository.AddAsync(new VisitTaskReReading()
                {
                    TrialId = applyReReadingCommand.TrialId,
                    RootReReadingTaskId = rootReReadingTaskId == Guid.Empty ? task.Id : rootReReadingTaskId,
                    OriginalReReadingTaskId = task.Id,
                    RequestReReadingTime = DateTime.Now,
                    RequestReReadingUserId = _userInfo.Id,
                    IsCopyOrigenalForms = applyReReadingCommand.IsCopyOrigenalForms,
                    IsCopyFollowForms = applyReReadingCommand.IsCopyFollowForms,
                    RequestReReadingReason = applyReReadingCommand.RequestReReadingReason,
                    RequestReReadingType = applyReReadingCommand.RequestReReadingType,

                });
            }


            await _visitTaskRepository.SaveChangesAsync();

            return ResponseOutput.Ok();
        }


        /// <summary>
        /// 重阅原任务跟踪处理   只会在同意的时候调用这个
        /// </summary>
        /// <param name="origenalTask"></param>
        /// <param name="agreeReReadingCommand"></param>
        private void ReReadingTaskTrackingDeal(VisitTask origenalTask, ConfirmReReadingCommand agreeReReadingCommand)
        {
            if (origenalTask.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || origenalTask.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed)
            {
                origenalTask.ReReadingApplyState = agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree ? ReReadingApplyState.Agree : ReReadingApplyState.Reject;
                origenalTask.TaskState = agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree ? TaskState.HaveReturned : origenalTask.TaskState;
            }
            else
            {
                //---当前重阅任务状态不为已申请状态,不允许进行处理,请刷新页面
                throw new BusinessValidationFailedException(_localizer["VisitTask_InvalidReapplyStatus"]);
            }

        }

        private async Task SetMedicalReviewInvalidAsync(List<VisitTask> influenceTaskList, bool isPMApply = true)
        {
            //将医学审核设置为失效
            var taskIdList = influenceTaskList.Select(t => t.Id).ToList();

            //PM 申请      医学审核任务状态为待审核、审核中的,设置为失效。

            //IR 申请  当前任务进入医学审核,医学审核任务未签名且结论中是否有问题项,答案为否的,设置为失效

            if (isPMApply)
            {
                await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(t => taskIdList.Contains(t.VisitTaskId) && t.AuditState != MedicalReviewAuditState.HaveSigned, u => new TaskMedicalReview() { IsInvalid = true });

            }
            else
            {

                await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(t => taskIdList.Contains(t.VisitTaskId) && t.IsHaveQuestion == false && t.AuditState != MedicalReviewAuditState.HaveSigned, u => new TaskMedicalReview() { IsInvalid = true });
            }
        }

        /// <summary>
        /// PM 申请重阅  被同意  或者 PM 直接退回的时候影响
        /// </summary>
        /// <param name="subjectId"></param>
        /// <returns></returns>
        private async Task SetReReadingOrBackInfluenceAnalysisAsync(Guid subjectId)
        {
            if (await _repository.AnyAsync<VisitTask>(t => t.IsAnalysisCreate && t.SubjectId == subjectId))
            {
                await _repository.UpdatePartialFromQueryAsync<Subject>(t => t.Id == subjectId, u => new Subject() { IsReReadingOrBackInfluenceAnalysis = true });

            }

        }

        public DateTime GetSuggessFinishTime(bool isInOrder, UrgentType urgentType)
        {

            var datetime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 22, 0, 0).AddDays(7);

            return datetime;
        }

        /// <summary>
        /// 确认重阅与否  1同意 2 拒绝
        /// </summary>
        /// <param name="agreeReReadingCommand"></param>
        /// <param name="_visitTaskCommonService"></param>
        /// <returns></returns>
        [HttpPost]
        [UnitOfWork]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]

        public async Task<IResponseOutput> ConfirmReReading(ConfirmReReadingCommand agreeReReadingCommand, [FromServices] IVisitTaskHelpeService _visitTaskCommonService)
        {

            var trialId = agreeReReadingCommand.TrialId;

            foreach (var item in agreeReReadingCommand.ConfirmReReadingList)
            {

                var origenalTask = (await _visitTaskRepository.Where(t => item.OriginalReReadingTaskId == t.Id).FirstOrDefaultAsync()).IfNullThrowException();


                if ((origenalTask.TaskState != TaskState.Effect && origenalTask.TaskState != TaskState.Freeze))
                {
                    //---当前申请重阅任务的状态,已被其他任务重阅已影响,不允许对该状态下的任务进行重阅同意与否操作
                    return ResponseOutput.NotOk(_localizer["VisitTask_ReapplyStatusConflict"]);
                }


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

                //更新申请信息
                var visitTaskReReadingAppply = await _visitTaskReReadingRepository.FirstOrDefaultAsync(t => t.Id == item.Id);
                visitTaskReReadingAppply.RequestReReadingConfirmUserId = _userInfo.Id;
                visitTaskReReadingAppply.RequestReReadingResultEnum = agreeReReadingCommand.RequestReReadingResultEnum;
                visitTaskReReadingAppply.RequestReReadingRejectReason = agreeReReadingCommand.RequestReReadingRejectReason;


                Expression<Func<VisitTask, bool>> filterExpression = t => t.TrialId == trialId && t.SubjectId == origenalTask.SubjectId && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze);

                //是否是一致性分析任务  正常申请 会影响一致性分析任务
                filterExpression = filterExpression.And(t => t.IsAnalysisCreate == origenalTask.IsAnalysisCreate);

                //IR 申请1.1 基线重阅,影响附加评估两个IR所有的任务
                var isIR1Point1AdditionalAssessmentBaseline = false;

                //附加评估  IR  和PM 看到的影响列表不一样

                //1.1 有附加评估,会影响其他标准的任务
                if (criterionConfig.CriterionType == CriterionType.RECIST1Point1 && criterionConfig.IsAdditionalAssessment)
                {
                    // PM申请 SPM / CPM审批
                    if (visitTaskReReadingAppply.RequestReReadingType == RequestReReadingType.TrialGroupApply && (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM))
                    {
                        filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB);
                    }
                    //IR 申请  PM审批
                    else
                    {

                        // 1.1 基线任务影响BM任务
                        if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager && _subjectVisitRepository.Any(t => t.Id == origenalTask.SourceSubjectVisitId && t.IsBaseLine == true))
                        {

                            isIR1Point1AdditionalAssessmentBaseline = true;

                            //filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB);
                        }
                        // 1.1 非基线任务不影响BM任务
                        else
                        {
                            filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId);
                        }
                    }
                }
                else
                {
                    //默认影响的都是该标准的任务
                    filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId);
                }


                if (agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree)
                {

                    //IR申请  PM 审批  注意这里有一致性分析的申请同意  不会回退访视,在此要生成影响的访视任务
                    if (visitTaskReReadingAppply.RequestReReadingType == RequestReReadingType.DocotorApply && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager)
                    {

                        //有序阅片
                        if (criterionConfig.IsReadingTaskViewInOrder)
                        {

                            filterExpression = filterExpression.And(t => t.VisitTaskNum >= origenalTask.VisitTaskNum);



                            #region 这里时影响其他的任务  /*不包括申请的任务  申请的任务,在上面会统一处理*/

                            var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).OrderBy(t => t.VisitTaskNum).ToListAsync();

                            var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault();



                            foreach (var influenceTask in influenceTaskList)
                            {
                                var beforeTaskState = influenceTask.TaskState;

                                //已签名的任务  设置转变后的标志
                                if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1 && influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned)
                                {
                                    var isConvertedTask = _visitTaskRepository.Where(t => t.Id == influenceTask.Id).Select(t => t.IsConvertedTask).FirstOrDefault();

                                    if (isConvertedTask)
                                    {
                                        influenceTask.IsHistoryConvertedTask = true;
                                    }
                                }


                                //处理申请的任务
                                if (influenceTask.Id == origenalTask.Id)
                                {
                                    ReReadingTaskTrackingDeal(influenceTask, agreeReReadingCommand);


                                    await SetMedicalReviewInvalidAsync(influenceTaskList, false);



                                }




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

                                    trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return });
                                }
                                else
                                {
                                    influenceTask.TaskState = TaskState.Adbandon;

                                    trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon });
                                }

                                // 影响的任务 仅仅访视类别的才生成  或者就是IR 申请的任务
                                if (influenceTask.ReadingCategory == ReadingCategory.Visit || influenceTask.Id == origenalTask.Id)
                                {


                                    //   影响的其他标准的附加评估的任务不立即生成 比如1.1基线 重阅  PM 同意仅仅生成1.1任务,不生成BM任务
                                    if (criterionConfig.CriterionType == CriterionType.RECIST1Point1 && criterionConfig.IsAdditionalAssessment && influenceTask.TrialReadingCriterionId != origenalTask.TrialReadingCriterionId)
                                    {
                                        //BM标准的不生成任务
                                        continue;
                                    }


                                    // i1.1标准 当前任务是转变任务,并且影响列表里有转变之前的任务 那么该访视任务就不生成
                                    if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1)
                                    {
                                        //申请的任务是冻结的任务(该任务发生转变)   影响自己 以及转变后的 以及后续任务 但是生成的时候,仅仅生成转变之前的
                                        //申请的是转变之后的任务 (转变生成的任务)  影响自己以及后续任务     生成转变后的任务
                                        if (influenceTask.BeforeConvertedTaskId != null && influenceTaskList.Any(t => t.Id == influenceTask.BeforeConvertedTaskId))
                                        {
                                            //有转化的任务  和转化之前的任务时,转化后的任务时不生成的
                                            continue;

                                        }

                                        //var canGenerateTaskIdList = influenceTaskList.GroupBy(t => new { t.VisitTaskNum, t.DoctorUserId, t.TrialReadingCriterionId, t.SubjectId })
                                        //   .Select(g => g.First().Id);

                                    }

                                    #region 影响的任务生成

                                    await _visitTaskCommonService.AddTaskAsync(new GenerateTaskCommand()
                                    {
                                        TrialId = trialId,

                                        ReadingCategory = GenerateTaskCategory.ReReading,

                                        ReReadingTask = influenceTask,

                                        //同步才可以
                                        Action = (newTask) =>
                                        {
                                            //申请表 设置新任务Id
                                            visitTaskReReadingAppply.NewReReadingTaskId = newTask.Id;

                                            //生成的任务分配给原始医生
                                            newTask.TaskAllocationState = TaskAllocationState.Allocated;
                                            newTask.AllocateTime = DateTime.Now;
                                            newTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);


                                            if (visitTaskReReadingAppply.IsCopyOrigenalForms && influenceTask.Id == origenalTask.Id)
                                            {
                                                if (origenalTask.ReadingCategory == ReadingCategory.Visit)
                                                {
                                                    var list = _readingTaskQuestionAnswerRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();

                                                    foreach (var item in list)
                                                    {
                                                        item.Id = Guid.Empty;
                                                        item.VisitTaskId = newTask.Id;
                                                    }

                                                    _ = _readingTaskQuestionAnswerRepository.AddRangeAsync(list).Result;
                                                }


                                            }

                                            //拷贝后续表单
                                            if (visitTaskReReadingAppply.IsCopyFollowForms && origenalTask.VisitTaskNum != influenceTask.VisitTaskNum)
                                            {
                                                if (origenalTask.ReadingCategory == ReadingCategory.Visit)
                                                {
                                                    var list = _readingTaskQuestionAnswerRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();

                                                    foreach (var item in list)
                                                    {
                                                        item.Id = Guid.Empty;
                                                        item.VisitTaskId = newTask.Id;
                                                    }

                                                    _ = _readingTaskQuestionAnswerRepository.AddRangeAsync(list).Result;
                                                }

                                            }

                                        }
                                    });



                                    #endregion


                                }




                            }

                            #endregion




                        }
                        //无序阅片  只会申请访视类型和裁判类型的任务    注意这里有一致性分析的申请同意
                        else
                        {


                            //1.当前任务及裁判任务
                            //2.影响当前阅片人的任务
                            filterExpression = filterExpression.And(t => t.Id == origenalTask.Id || t.Id == origenalTask.JudgeVisitTaskId);


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

                            var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault();

                            foreach (var influenceTask in influenceTaskList)
                            {
                                //申请原任务处理
                                if (influenceTask.Id == origenalTask.Id)
                                {
                                    ReReadingTaskTrackingDeal(influenceTask, agreeReReadingCommand);

                                    await SetMedicalReviewInvalidAsync(influenceTaskList, false);

                                    trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return });
                                }
                                else
                                {
                                    if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned)
                                    {
                                        influenceTask.TaskState = TaskState.HaveReturned;

                                        trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return });
                                    }
                                    else
                                    {
                                        influenceTask.TaskState = TaskState.Adbandon;

                                        trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon });
                                    }
                                }


                                if (influenceTask.ReadingCategory == ReadingCategory.Visit || influenceTask.Id == origenalTask.Id)
                                {
                                    await _visitTaskCommonService.AddTaskAsync(new GenerateTaskCommand()
                                    {
                                        TrialId = trialId,

                                        ReadingCategory = GenerateTaskCategory.ReReading,

                                        ReReadingTask = origenalTask,

                                        //同步才可以
                                        Action = (newTask) =>
                                        {
                                            //申请表 设置新任务Id
                                            visitTaskReReadingAppply.NewReReadingTaskId = newTask.Id;


                                            newTask.AllocateTime = DateTime.Now;
                                            newTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);


                                            //裁判任务 需要进行特殊处理  在重阅逻辑里面处理


                                            if (visitTaskReReadingAppply.IsCopyOrigenalForms && influenceTask.Id == origenalTask.Id)
                                            {
                                                if (origenalTask.ReadingCategory == ReadingCategory.Visit)
                                                {
                                                    var list = _readingTaskQuestionAnswerRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();

                                                    foreach (var item in list)
                                                    {
                                                        item.Id = Guid.Empty;
                                                        item.VisitTaskId = newTask.Id;
                                                    }

                                                    _ = _readingTaskQuestionAnswerRepository.AddRangeAsync(list).Result;
                                                }

                                            }

                                            //拷贝后续表单
                                            if (visitTaskReReadingAppply.IsCopyFollowForms && origenalTask.VisitTaskNum != influenceTask.VisitTaskNum)
                                            {
                                                if (origenalTask.ReadingCategory == ReadingCategory.Visit)
                                                {
                                                    var list = _readingTaskQuestionAnswerRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();

                                                    foreach (var item in list)
                                                    {
                                                        item.Id = Guid.Empty;
                                                        item.VisitTaskId = newTask.Id;
                                                    }

                                                    _ = _readingTaskQuestionAnswerRepository.AddRangeAsync(list).Result;
                                                }
                                            }


                                        }
                                    });

                                }

                            }

                        }






                    }
                    else
                    {
                        //---不符合  PM申请   SPM / CPM审批 | IR申请  PM 审批 
                        throw new BusinessValidationFailedException(_localizer["VisitTask_ReReadTaskAlreadyAffected"]);
                    }

                }
                else if (agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Reject)
                {

                    if (origenalTask.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || origenalTask.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed)
                    {
                        await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.Id == origenalTask.Id, u => new VisitTask()
                        {
                            ReReadingApplyState = ReReadingApplyState.Reject
                        });
                    }
                    else
                    {
                        //---当前重阅任务状态不为已申请状态,不允许进行处理,请刷新页面
                        throw new BusinessValidationFailedException(_localizer["VisitTask_InvalidReapplyStatus"]);
                    }

                }




            }





            await _visitTaskRepository.SaveChangesAsync();

            return ResponseOutput.Ok();
        }


        /// <summary>
        /// PM  设置任务 退回
        /// </summary>
        /// <returns></returns>
        [HttpPut("{trialId:guid}/{taskId:guid}")]
        [UnitOfWork]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]

        public async Task<IResponseOutput> PMSetTaskBack(Guid trialId, Guid taskId)
        {



            var task = (await _visitTaskRepository.Where(t => t.Id == taskId).FirstOrDefaultAsync()).IfNullThrowException();

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

            if (criterionConfig.IsAutoCreate == false)
            {
                //---手动生成任务的不允许在此入口影像退回
                return ResponseOutput.NotOk(_localizer["VisitTask_NoImageReturn"]);
            }

            if (task.TaskState != TaskState.Effect || task.ReadingCategory != ReadingCategory.Visit /*|| task.ReadingTaskState == ReadingTaskState.HaveSigned*/)
            {
                //---仅仅允许针对生效、未完成的访视任务进行退回操作,请刷新页面数据
                return ResponseOutput.NotOk(_localizer["VisitTask_NonEffectiveTaskCannotBeReturned"]);
            }


            if (await _subjectVisitRepository.AnyAsync(t => t.Id == task.SourceSubjectVisitId && t.CheckState != CheckStateEnum.CVPassed))
            {
                //---当前访视已回退到影像上传,不允许继续回退!
                return ResponseOutput.NotOk(_localizer["VisitTask_NoFurtherReturn"]);
            }


            if (task.IsAnalysisCreate)
            {
                //---一致性分析的任务,不允许设置退回
                return ResponseOutput.NotOk(_localizer["VisitTask_ConsistencyTaskCannotBeReturned"]);
            }

            Expression<Func<VisitTask, bool>> filterExpression = t => t.TrialId == trialId && t.SubjectId == task.SubjectId && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze);



            //PM 才允许操作
            if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager)
            {

                #region 有序 无序公用流程


                //执行类似一致性核查回退流程  回退访视到影像上传流程
                await VisitBackAsync(task.SourceSubjectVisitId);

                #endregion



                //有序
                if (criterionConfig.IsReadingTaskViewInOrder)
                {


                    filterExpression = filterExpression.And(t => t.IsAnalysisCreate == false);



                    //另一个阅片人的任务根据任务进度自动进入PM退回或PM申请重阅
                    filterExpression = filterExpression.And(t => t.VisitTaskNum >= task.VisitTaskNum);


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



                    #region 方式二

                    var origenalTask = influenceTaskList.Where(t => t.Id == task.Id).FirstOrDefault();

                    foreach (var influenceTask in influenceTaskList)
                    {

                        //已签名的任务  设置转变后的标志
                        if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1 && influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned)
                        {
                            var isConvertedTask = _visitTaskRepository.Where(t => t.Id == influenceTask.Id).Select(t => t.IsConvertedTask).FirstOrDefault();

                            if (isConvertedTask)
                            {
                                influenceTask.IsHistoryConvertedTask = true;
                            }
                        }

                        //同意的访视   因为要记录具体的操作,所以废弃
                        if (influenceTask.Id == task.Id)
                        {



                            await SetReReadingOrBackInfluenceAnalysisAsync(influenceTask.SubjectId);

                            await SetMedicalReviewInvalidAsync(influenceTaskList);


                            influenceTask.IsPMSetBack = true;
                        }

                        if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned)
                        {
                            influenceTask.TaskState = TaskState.HaveReturned;
                            origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return });
                        }
                        else
                        {
                            influenceTask.TaskState = TaskState.Adbandon;
                            origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon });
                        }





                    }

                    #endregion



                }

                else
                {
                    //无序   无序阅片没有 全局  肿瘤学

                    // 申请该访视的任务  申请人失效 另外一个人重阅重置或者失效

                    var currentVisitList = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == task.SourceSubjectVisitId && t.ReadingCategory == ReadingCategory.Visit && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) && t.VisitTaskNum == task.VisitTaskNum, true).ToListAsync();

                    await SetMedicalReviewInvalidAsync(currentVisitList);

                    var origenalTask = currentVisitList.Where(t => t.Id == task.Id).First();

                    foreach (var influenceTask in currentVisitList)
                    {
                        if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned)
                        {
                            //另外阅片人完成阅片了 就设置为重阅重置
                            influenceTask.TaskState = TaskState.HaveReturned;

                            origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return });
                        }
                        else
                        {
                            influenceTask.TaskState = TaskState.Adbandon;

                            origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon });
                        }

                    }

                }

            }
            else
            {
                //---仅PM 可以进行回退操作
                return ResponseOutput.NotOk(_localizer["VisitTask_PMOnlyAllowedForReturn"]);
            }

            await _visitTaskRepository.SaveChangesAsync();

            return ResponseOutput.Ok();
        }




        //包括临床数据签名状态
        private async Task VisitBackAsync(Guid? subjectVisitId)
        {
            var sv = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId)).IfNullThrowException();


            //需要重新产生任务  
            sv.IsVisitTaskGenerated = false;
            sv.IsPMBackOrReReading = true;

            sv.AuditState = AuditStateEnum.None;
            sv.SubmitState = SubmitStateEnum.ToSubmit;
            sv.ReadingStatus = ReadingStatusEnum.ImageNotSubmit;

            //回退后,回退状态恢复
            sv.RequestBackState = RequestBackStateEnum.NotRequest;
            sv.IsCheckBack = false;
            sv.CheckBackTime = null;
            sv.CheckState = CheckStateEnum.None;
            sv.CheckChallengeState = CheckChanllengeTypeEnum.None;

            sv.SVENDTC = null;
            sv.SVSTDTC = null;

            sv.PreliminaryAuditTime = null;
            sv.SubmitTime = null;
            sv.ReviewAuditTime = null;
            sv.CurrentActionUserExpireTime = null;


            sv.IsTake = false;
            sv.CurrentActionUserId = null;
            sv.PreliminaryAuditUserId = null;
            sv.ReviewAuditUserId = null;


            if (sv.IsBaseLine)
            {
                await _readingClinicalDataReposiotry.UpdatePartialFromQueryAsync(t => t.ReadingId == sv.Id && (t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject || t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit), c => new ReadingClinicalData() { IsSign = false, ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded });

            }
            else
            {
                await _readingClinicalDataReposiotry.UpdatePartialFromQueryAsync(t => t.ReadingId == sv.Id && t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit, c => new ReadingClinicalData()
                {
                    IsSign = false,
                    ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded,
                    IsBlind = null,
                    IsComplete = null
                });
            }



            //await _repository.AddAsync(new CheckChallengeDialog() { SubjectVisitId = subjectVisitId, TalkContent = "PM/APM同意一致性核查回退。", UserTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt });

            await _repository.BatchDeleteAsync<TrialQCQuestionAnswer>(t => t.SubjectVisitId == subjectVisitId);
            await _repository.BatchDeleteAsync<DicomInstance>(t => t.DicomSerie.IsDeleted);
            await _repository.BatchDeleteAsync<DicomSeries>(t => t.IsDeleted);

            var success = await _subjectVisitRepository.SaveChangesAsync();

        }


        /// <summary>
        /// 影响提示列表  重阅仅仅针对已完成的任务申请   退回针对的是未完成的(退回仅仅针对是访视类型的)
        /// </summary>
        /// <param name="taskId"></param>
        /// <param name="isReReading">  重阅还是直接回退</param>
        /// <param name="applyId"> 申请记录的Id</param>
        /// <returns></returns>
        [HttpGet("{taskId:guid}/{isReReading:bool}")]
        public async Task<(List<InfluenceTaskInfo>, object)> GetReReadingOrBackInfluenceTaskList(Guid taskId, bool isReReading, Guid? applyId)
        {
            var isIRAppyTaskInfluenced = false;

            var filterObj = (await _visitTaskRepository.FirstOrDefaultNoTrackingAsync(t => t.Id == taskId)).IfNullThrowException();
            var trialId = filterObj.TrialId;


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

            Expression<Func<VisitTask, bool>> filterExpression = t => t.TrialId == trialId && t.SubjectId == filterObj.SubjectId && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) /*&& t.TaskAllocationState == TaskAllocationState.Allocated*/;

            //是否是一致性分析任务 (一致性分析的任务 不会产生裁判 肿瘤学  仅仅有生成的访视和全局)

            filterExpression = filterExpression.And(t => t.IsAnalysisCreate == filterObj.IsAnalysisCreate);

            //IR 申请1.1 基线重阅,影响附加评估所有的任务
            var isIR1Point1AdditionalAssessmentBaseline = false;






            //重阅影响  
            if (isReReading)
            {
                //默认影响的都是该标准的任务
                filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId);


                //IR 申请  PM 同意  仅仅影响自己

                if ((_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager && applyId != null && await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && (t.CreateUser.UserTypeEnum == UserTypeEnum.SR || t.CreateUser.UserTypeEnum == UserTypeEnum.PI)))
                    || ((_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI) && applyId == null))
                {

                    //当前任务及其之后的所有访视任务、全局任务、裁判任务、肿瘤学阅片任务

                    //有序
                    if (criterionConfig.IsReadingTaskViewInOrder)
                    {

                        filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum);
                    }
                    //无序
                    else
                    {
                        //1.当前任务及裁判任务
                        //2.影响当前阅片人的任务
                        filterExpression = filterExpression.And(t => t.Id == filterObj.Id || t.Id == filterObj.JudgeVisitTaskId);
                    }

                    //throw new BusinessValidationFailedException("仅允许PM 同意 IR 申请的任务");
                }
                else
                {
                    //---当前用户查看列表未定义
                    throw new BusinessValidationFailedException(_localizer["VisitTask_UndefinedList"]);
                }

            }


            //退回影响  仅仅针对是访视类型的   影响多个标准的任务
            else
            {

                if (filterObj.IsAnalysisCreate)
                {
                    //---不允许退回一致性分析任务
                    throw new BusinessValidationFailedException(_localizer["VisitTask_NoConsistencyReturn"]);
                }

                if (filterObj.ReadingCategory == ReadingCategory.Visit && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager)
                {
                    //有序
                    if (criterionConfig.IsReadingTaskViewInOrder)
                    {
                        // 当前任务及其之后的所有访视任务  两个阅片人的

                        //2.当前任务未完成,不会产生全局任务。后续任务均为访视任务,且均为待阅片,取消分配;
                        filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum);


                        if (await _visitTaskReReadingRepository.AnyAsync(t => t.RequestReReadingType == RequestReReadingType.DocotorApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default &&
                      t.OriginalReReadingTask.VisitTaskNum >= filterObj.VisitTaskNum && t.OriginalReReadingTask.SubjectId == filterObj.SubjectId && t.OriginalReReadingTask.TrialReadingCriterionId == filterObj.TrialReadingCriterionId && t.OriginalReReadingTask.IsAnalysisCreate == filterObj.IsAnalysisCreate))
                        {
                            isIRAppyTaskInfluenced = true;
                        }
                    }
                    //无序
                    else
                    {
                        //自己和另一个人的当前任务    退回针对的是未完成的肯定不会有裁判
                        filterExpression = filterExpression.And(t => t.VisitTaskNum == filterObj.VisitTaskNum);
                    }
                }
                else
                {
                    //---仅仅访视类型的任务支持PM退回
                    throw new BusinessValidationFailedException(_localizer["VisitTask_VisitTypeTaskAllowedForPMOnly"]);
                }

            }

            var list = await _visitTaskRepository.Where(filterExpression)
                //IR 申请的时候,仅仅看到影响自己的
                .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer, t => t.DoctorUserId == _userInfo.Id)
                .OrderBy(t => t.VisitTaskNum).ProjectTo<InfluenceTaskInfo>(_mapper.ConfigurationProvider).ToListAsync();

            #region 影响后的操作

            foreach (var influenceTask in list)
            {
                influenceTask.OptType = influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned ? ReReadingOrBackOptType.Return : ReReadingOrBackOptType.Abandon;

            }
            #endregion


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

        }




        /// <summary>
        /// 获取已影响的列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<InfluenceTaskInfo>> GetInfluencedTaskList(Guid taskId)
        {
            var list = await _repository.Where<TaskInfluence>(t => t.OriginalTaskId == taskId)/*.Select(t => t.InfluenceTask)*/.ProjectTo<InfluenceTaskInfo>(_mapper.ConfigurationProvider).ToListAsync();

            return list;
        }


    }
}