using IRaCIS.Core.Application.Contracts;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.Contracts.DTO;
using IRaCIS.Core.Application.Service;
using Microsoft.AspNetCore.Authorization;
using IRaCIS.Application.Interfaces;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Application.Service.Reading.Dto;

namespace IRaCIS.Core.Application.Image.QA
{
    [ApiExplorerSettings(GroupName = "Image")]
    public class QCListService : BaseService, IQCListService
    {
        private readonly IRepository<SubjectVisit> _subjectVisitRepository;
        private readonly IRepository<Trial> _trialRepository;
        private readonly IRepository<ClinicalDataTrialSet> _clinicalDataTrialSet;
        private readonly IRepository<TrialQCQuestionAnswer> _trialQCQuestionAnswerRepository;
        private readonly IRepository<TrialQCQuestion> _trialQCQuestionRepository;
        private readonly IRepository<ConsistencyCheckFile> _consistencyCheckFileRepository;

        public QCListService(
            IRepository<SubjectVisit> subjectVisitRepository,
           IRepository<Trial> trialRepository,
            IRepository<ClinicalDataTrialSet> clinicalDataTrialSet,
              IRepository<TrialQCQuestionAnswer> trialQCQuestionAnswerRepository,
              IRepository<TrialQCQuestion> trialQCQuestionRepository,
             IRepository<ConsistencyCheckFile> consistencyCheckFileRepository
            )
        {
            _subjectVisitRepository = subjectVisitRepository;
            this._trialQCQuestionAnswerRepository = trialQCQuestionAnswerRepository;
            this._trialQCQuestionRepository = trialQCQuestionRepository;
            this._consistencyCheckFileRepository = consistencyCheckFileRepository;
            _trialRepository = trialRepository;
            this._clinicalDataTrialSet = clinicalDataTrialSet;
        }





        #region IC上传、质疑页面
        /// <summary>
        /// IC 检查批次上传列表
        /// </summary>
        /// <param name="visitSearchDTO"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<(PageOutput<QCCRCVisitViewModel>, TrialSubjectAndSVConfig)> GetCRCVisitList(CRCVisitSearchDTO visitSearchDTO)
        {
            var svExpression = QCCommon.GetSubjectVisitFilter(visitSearchDTO.VisitPlanArray);

            var query = _subjectVisitRepository.Where(x => x.TrialId == visitSearchDTO.TrialId)
                       .Where(t => t.Subject.FinalSubjectVisitId != null ? t.VisitNum <= t.Subject.FinalSubjectVisit.VisitNum : true)
                       .WhereIf(visitSearchDTO.SiteId != null, t => t.SiteId == visitSearchDTO.SiteId)
                       .WhereIf(visitSearchDTO.SubjectId != null, t => t.Subject.Id == visitSearchDTO.SubjectId)
                       .WhereIf(!string.IsNullOrEmpty(visitSearchDTO.SubjectInfo), t => t.Subject.Code.Contains(visitSearchDTO.SubjectInfo))

                       .WhereIf(visitSearchDTO.VisitPlanArray != null && visitSearchDTO.VisitPlanArray?.Length > 0, svExpression)
                       //.WhereIf(!string.IsNullOrEmpty(visitSearchDTO.VisitPlanInfo), visitSearchDTO.VisitPlanInfo.Contains('.') ? t => t.InPlan == false : t => t.VisitNum == decimal.Parse(visitSearchDTO.VisitPlanInfo))
                       .WhereIf(visitSearchDTO.AuditStateArray != null && visitSearchDTO.AuditStateArray?.Length > 0, t => visitSearchDTO.AuditStateArray!.Contains(t.AuditState))
                       .WhereIf(visitSearchDTO.SubmitState != null, t => t.SubmitState == visitSearchDTO.SubmitState)
                        .WhereIf(visitSearchDTO.BeginSubmitTime != null, t => t.SubmitTime >= visitSearchDTO.BeginSubmitTime)
                        .WhereIf(visitSearchDTO.EndSubmitTime != null, t => t.SubmitTime <= visitSearchDTO.EndSubmitTime)
                       .WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState)
                       .WhereIf(visitSearchDTO.IsUrgent != null, t => t.IsUrgent == visitSearchDTO.IsUrgent)
                       .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))
                       .ProjectTo<QCCRCVisitViewModel>(_mapper.ConfigurationProvider);


            var defalutSortArray = new string[] { nameof(SubjectVisit.IsUrgent) + " desc", nameof(SubjectVisit.SubjectId), nameof(SubjectVisit.VisitNum) };
            var pageList = await query.ToPagedListAsync(visitSearchDTO.PageIndex, visitSearchDTO.PageSize, visitSearchDTO.SortField, visitSearchDTO.Asc, string.IsNullOrWhiteSpace(visitSearchDTO.SortField), defalutSortArray);

            var config = await _repository.Where<Trial>(t => t.Id == visitSearchDTO.TrialId).ProjectTo<TrialSubjectAndSVConfig>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
            config.IsHaveSubjectClinicalData = await _clinicalDataTrialSet.AnyAsync(x => x.TrialId == visitSearchDTO.TrialId && x.IsConfirm && x.ClinicalDataLevel == ClinicalLevel.Subject && x.UploadRole == UploadRole.CRC);
            config.IsHaveVisitClinicalData = await _clinicalDataTrialSet.AnyAsync(x => x.TrialId == visitSearchDTO.TrialId && x.IsConfirm && x.ClinicalDataLevel == ClinicalLevel.SubjectVisit && x.UploadRole == UploadRole.CRC);
            return (pageList, config);

        }



        /// <summary>
        /// IC 质疑列表
        /// </summary>
        /// <param name="challengeQuery"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<(PageOutput<QCCRCChallengeViewModel>, TrialSubjectAndSVConfig)> GetCRCChallengeList(ChallengeQuery challengeQuery)
        {

            #region IC 质疑列表  join连表方式
            //var query = from qcChanllenge in _qcChallengeRepository.Find(qcChallengeLambda)
            //            join subjectVisit in _subjectVisitRepository.Find() on qcChanllenge.SubjectVisitId equals subjectVisit.Id
            //            join trialSite in _trialSiteRepository.Find(t => t.TrialId == challengeQuery.TrialId) on subjectVisit.SiteId equals trialSite.SiteId
            //            join subject in _subjectRepository.Find() on subjectVisit.SubjectId equals subject.Id
            //            select new QCCRCChallengeViewModel()
            //            {
            //                Id = qcChanllenge.Id,
            //                SubjectVisitId = qcChanllenge.SubjectVisitId,
            //                ChallengeCode = qcChanllenge.ChallengeCode,
            //                ChallengeType = qcChanllenge.ChallengeType,
            //                Note = qcChanllenge.Note,
            //                Content = qcChanllenge.Content,
            //                UserTypeEnum = qcChanllenge.UserTypeEnum,
            //                CreateTime = qcChanllenge.CreateTime,
            //                CreateUser = qcChanllenge.CreateUser,
            //                CreateUserId = qcChanllenge.CreateUserId,

            //                DeadlineTime = qcChanllenge.DeadlineTime,
            //                IsClosed = qcChanllenge.IsClosed,
            //                ClosedTime = qcChanllenge.ClosedTime,
            //                ClosedUser = qcChanllenge.ClosedUser,
            //                NeedReUpload = qcChanllenge.NeedReUpload,

            //                VisitName = subjectVisit.VisitName,
            //                VisitNum = subjectVisit.VisitNum,
            //                SubjectCode = subject.Code,
            //                TrialSiteCode = trialSite.TrialSiteCode,

            //                LatestMsgTime = qcChanllenge.LatestMsgTime,
            //                LatestReplyUser = qcChanllenge.LatestReplyUser,
            //            };
            #endregion

            var svExpression = QCCommon.GetQCChallengeFilter(challengeQuery.VisitPlanArray);

            var query2 = _repository.Where<QCChallenge>(x => x.TrialId == challengeQuery.TrialId)
                //.WhereIf(challengeQuery.ChallengeState != null, t => t.SubjectVisit.ChallengeState == challengeQuery.ChallengeState)
                .WhereIf(challengeQuery.ReuploadEnum != null, t => t.ReuploadEnum == challengeQuery.ReuploadEnum)
                .WhereIf(challengeQuery.IsClosed != null, t => t.IsClosed == challengeQuery.IsClosed)
                .WhereIf(challengeQuery.SiteId != null, t => t.SubjectVisit.SiteId == challengeQuery.SiteId)
                .WhereIf(challengeQuery.SubjectId != null, t => t.SubjectVisit.SubjectId == challengeQuery.SubjectId)
                .WhereIf(challengeQuery.CreateUserId != null, t => t.CreateUserId == challengeQuery.CreateUserId)
                .WhereIf(challengeQuery.SubjectCode != null, t => t.SubjectVisit.Subject.Code.Contains(challengeQuery.SubjectCode!))
                .WhereIf(challengeQuery.VisitPlanArray != null && challengeQuery.VisitPlanArray?.Length > 0, svExpression)
                 //.WhereIf(!string.IsNullOrEmpty(challengeQuery.VisitPlanInfo), challengeQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(challengeQuery.VisitPlanInfo))
                 .WhereIf(challengeQuery.IsOverTime != null && challengeQuery.IsOverTime == true, t => t.IsClosed ? t.ClosedTime > t.DeadlineTime : DateTime.Now > t.DeadlineTime)
                .WhereIf(challengeQuery.IsOverTime != null && challengeQuery.IsOverTime == false, t => t.IsClosed ? t.ClosedTime < t.DeadlineTime : DateTime.Now < t.DeadlineTime)
                .WhereIf(challengeQuery.IsUrgent != null, t => t.SubjectVisit.IsUrgent == challengeQuery.IsUrgent)
                .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.SubjectVisit.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))
              .ProjectTo<QCCRCChallengeViewModel>(_mapper.ConfigurationProvider);

            var pageList = await query2.ToPagedListAsync(challengeQuery.PageIndex, challengeQuery.PageSize, challengeQuery.SortField, challengeQuery.Asc, string.IsNullOrWhiteSpace(challengeQuery.SortField), new string[] { "IsUrgent desc", "IsClosed asc" });

            var config = await _repository.Where<Trial>(t => t.Id == challengeQuery.TrialId).ProjectTo<TrialSubjectAndSVConfig>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
            return (pageList, config);

        }

        #endregion


        #region QC 质疑 质控页面

        /// <summary>
        /// QC 质疑列表   分页
        /// </summary>
        /// <param name="challengeQuery"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<(PageOutput<QCCRCChallengeViewModel>, TrialSubjectAndSVConfig)> GetQCChallengeList(ChallengeQuery challengeQuery)
        {
            #region linq方式 + Expression 拼接

            //Expression<Func<QCChallenge, bool>> qcChallengeLambda = x => x.TrialId == challengeQuery.TrialId;

            //if (challengeQuery.ReuploadEnum != null)
            //{
            //    qcChallengeLambda = qcChallengeLambda.And(t => t.ReuploadEnum == challengeQuery.ReuploadEnum);
            //}
            //if (challengeQuery.IsClosed != null)
            //{
            //    qcChallengeLambda = qcChallengeLambda.And(t => t.IsClosed == challengeQuery.IsClosed);
            //}
            //if (challengeQuery.SiteId != null)
            //{
            //    qcChallengeLambda = qcChallengeLambda.And(t => t.SubjectVisit.SiteId == challengeQuery.SiteId.Value);
            //}
            //if (challengeQuery.SubjectId != null)
            //{
            //    qcChallengeLambda = qcChallengeLambda.And(t => t.SubjectVisit.Subject.Id == challengeQuery.SubjectId.Value);
            //}

            //var query = from qcChanllenge in _qcChallengeRepository.Find(qcChallengeLambda)
            //            join subjectVisit in _subjectVisitRepository.Find(subjectVisitLambda) on qcChanllenge.SubjectVisitId equals subjectVisit.Id
            //            join trialSite in _trialSiteRepository.Find(t => t.TrialId == challengeQuery.TrialId) on subjectVisit.SiteId equals trialSite.SiteId
            //            join subject in _subjectRepository.Find() on subjectVisit.SubjectId equals subject.Id
            //            select new QCChallengeViewModel()
            //            {
            //                Id = qcChanllenge.Id,
            //                SubjectVisitId = qcChanllenge.SubjectVisitId,
            //                ChallengeCode = qcChanllenge.ChallengeCode.ToString(),
            //                ChallengeType = qcChanllenge.ChallengeType,
            //                Note = qcChanllenge.Note,
            //                UserTypeEnum = qcChanllenge.UserTypeEnum,
            //                Content = qcChanllenge.Content,
            //                CreateTime = qcChanllenge.CreateTime,
            //                CreateUserId = qcChanllenge.CreateUserId,
            //                CreateUser = qcChanllenge.CreateUser,
            //                SubjectCode = subject.Code,
            //                TrialSiteCode = trialSite.TrialSiteCode,
            //                DeadlineTime = qcChanllenge.DeadlineTime,
            //                IsClosed = qcChanllenge.IsClosed,
            //                ClosedTime = qcChanllenge.ClosedTime,
            //                ClosedUser = qcChanllenge.ClosedUser,
            //                NeedReUpload = qcChanllenge.NeedReUpload,
            //                VisitName = subjectVisit.VisitName,
            //                VisitNum = subjectVisit.VisitNum,
            //                LatestMsgTime = qcChanllenge.LatestMsgTime,
            //                LatestReplyUser = qcChanllenge.LatestReplyUser,

            //            };
            #endregion

            var svExpression = QCCommon.GetQCChallengeFilter(challengeQuery.VisitPlanArray);

            var query = _repository.Where<QCChallenge>(x => x.TrialId == challengeQuery.TrialId)
                //.WhereIf(challengeQuery.ChallengeState != null, t => t.SubjectVisit.ChallengeState == challengeQuery.ChallengeState)
                .WhereIf(challengeQuery.ReuploadEnum != null, t => t.ReuploadEnum == challengeQuery.ReuploadEnum)
                .WhereIf(challengeQuery.IsClosed != null, t => t.IsClosed == challengeQuery.IsClosed)
                .WhereIf(challengeQuery.SiteId != null, t => t.SubjectVisit.SiteId == challengeQuery.SiteId)
                .WhereIf(challengeQuery.SubjectId != null, t => t.SubjectVisit.SubjectId == challengeQuery.SubjectId)
                .WhereIf(challengeQuery.CreateUserId != null, t => t.CreateUserId == challengeQuery.CreateUserId)
                .WhereIf(!string.IsNullOrEmpty(challengeQuery.SubjectCode), t => t.SubjectVisit.Subject.Code.Contains(challengeQuery.SubjectCode))
                .WhereIf(challengeQuery.VisitPlanArray != null && challengeQuery.VisitPlanArray?.Length > 0, svExpression)
                //.WhereIf(!string.IsNullOrEmpty(challengeQuery.VisitPlanInfo), challengeQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.InPlan == false : t => t.SubjectVisit.VisitNum == decimal.Parse(challengeQuery.VisitPlanInfo))
                .WhereIf(challengeQuery.IsUrgent != null, t => t.SubjectVisit.IsUrgent == challengeQuery.IsUrgent)
                .WhereIf(challengeQuery.IsOverTime != null && challengeQuery.IsOverTime == true, t => t.IsClosed ? t.ClosedTime > t.DeadlineTime : DateTime.Now > t.DeadlineTime)
                .WhereIf(challengeQuery.IsOverTime != null && challengeQuery.IsOverTime == false, t => t.IsClosed ? t.ClosedTime < t.DeadlineTime : DateTime.Now < t.DeadlineTime)
                .ProjectTo<QCCRCChallengeViewModel>(_mapper.ConfigurationProvider);

            var pageList = await query.ToPagedListAsync(challengeQuery.PageIndex, challengeQuery.PageSize, challengeQuery.SortField, challengeQuery.Asc, string.IsNullOrWhiteSpace(challengeQuery.SortField), new string[] { "IsUrgent desc", "IsClosed asc" });

            var config = await _repository.Where<Trial>(t => t.Id == challengeQuery.TrialId).ProjectTo<TrialSubjectAndSVConfig>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
            return (pageList, config);
        }


        /// <summary>
        /// 获取下一个Qc信息
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<QCVisitViewModel?> GetNextQCInfo(GetNextQCInfoInDto inDto)
        {
         var result=   await GetQCVisitList(new QCVisitSearchDTO()
            {

                TrialId = inDto.TrialId,
                CurrentActionUserId=_userInfo.Id,
                PageIndex=1,
                PageSize=1,
            });

           return result.Item1.CurrentPageData.Count > 0 ? result.Item1.CurrentPageData[0] : null;
        }

        /// <summary>
        /// QC 检查批次列表
        /// </summary>
        /// <param name="visitSearchDTO"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<(PageOutput<QCVisitViewModel>, TrialSubjectAndSVConfig)> GetQCVisitList(QCVisitSearchDTO visitSearchDTO)
        {

            #region 经典 linq
            //Expression<Func<Subject, bool>> subjectLambda = x => true;

            //Expression<Func<SubjectVisit, bool>> subjectVisitLambda = x => x.TrialId == visitSearchDTO.TrialId;
            //Expression<Func<DicomStudy, bool>> studyLambda = x => x.TrialId == visitSearchDTO.TrialId;
            ////Expression<Func<VisitStage, bool>> visitPlanLambda = x => x.TrialId == subjectVisitSearch.TrialId;

            //if (visitSearchDTO.SiteId != null && visitSearchDTO.SiteId != Guid.Empty)
            //{
            //    subjectVisitLambda = subjectVisitLambda.And(t => t.SiteId == visitSearchDTO.SiteId.Value);
            //    studyLambda = studyLambda.And(t => t.SiteId == visitSearchDTO.SiteId.Value);
            //}

            //if (visitSearchDTO.SubjectId != null && visitSearchDTO.SubjectId != Guid.Empty)
            //{
            //    subjectLambda = subjectLambda.And(t => t.Id == visitSearchDTO.SubjectId.Value);

            //    studyLambda = studyLambda.And(t => t.SubjectId == visitSearchDTO.SubjectId.Value);
            //}

            //if (!string.IsNullOrEmpty(visitSearchDTO.SubjectInfo))
            //{
            //    var search = visitSearchDTO.SubjectInfo.Trim();
            //    subjectLambda = subjectLambda.And(t => t.FirstName.Contains(search) || t.LastName.Contains(search) || t.Code.Contains(search));
            //}

            //if (!string.IsNullOrWhiteSpace(visitSearchDTO.VisitPlanInfo))
            //{
            //    var visitInfo = visitSearchDTO.VisitPlanInfo.Trim();

            //    if (visitInfo.Contains('.')) // 包含小数点的是计划外检查批次
            //    {
            //        subjectVisitLambda = subjectVisitLambda.And(t => t.VisitNum.ToString().Contains("."));
            //    }
            //    else
            //    {
            //        if (int.TryParse(visitInfo, out var visitNum))
            //        {
            //            subjectVisitLambda = subjectVisitLambda.And(t => t.VisitNum == visitNum);
            //        }
            //    }
            //}

            //var query = from subjectVisit in _subjectVisitRepository.Where(subjectVisitLambda)
            //            join subject in _subjectRepository.Where(subjectLambda) on subjectVisit.SubjectId equals subject.Id
            //            join trialSite in _trialSiteRepository.Where(t => t.TrialId == visitSearchDTO.TrialId) on subjectVisit.SiteId equals trialSite.SiteId
            //            join study in _studyRepository.Where(studyLambda).GroupBy(t => t.SubjectVisitId).Select(g => new { SubjectVisitId = g.Key, StudyCount = g.Count() }) on subjectVisit.Id equals study.SubjectVisitId into d
            //            from study in d.DefaultIfEmpty()
            //            join trial in _trialRepository.AsQueryable() on subjectVisit.TrialId equals trial.Id

            //            select new QCVisitViewModel()
            //            {
            //                Id = subjectVisit.Id,
            //                //VisitPlanId = visitStage.Id,
            //                SubjectId = subjectVisit.SubjectId,
            //                TrialId = subjectVisit.TrialId,
            //                SiteId = subjectVisit.SiteId,

            //                VisitDay = subjectVisit.VisitDay,
            //                VisitNum = subjectVisit.VisitNum,
            //                VisitName = subjectVisit.VisitName,
            //                SVENDTC = subjectVisit.SVENDTC,
            //                SVSTDTC = subjectVisit.SVSTDTC,
            //                SVUPDES = subjectVisit.SVUPDES,
            //                InPlan = subjectVisit.InPlan,
            //                VisitExecuted = subjectVisit.VisitExecuted,


            //                StudyCount = study.StudyCount,
            //                SubjectStatus = subject.Status,

            //                SubjectCode = subject.Code,

            //                IsUrgent = subjectVisit.IsUrgent,

            //                TrialSiteCode = trialSite.TrialSiteCode,

            //                EarliestScanDate = subjectVisit.EarliestScanDate,
            //                LatestScanDate = subjectVisit.LatestScanDate,

            //                QCProcessEnum = trial.QCProcessEnum,
            //                CurrentActionUserId = subjectVisit.CurrentActionUserId,
            //                CurrentActionUser = subjectVisit.CurrentActionUser,
            //                CurrentActionUserExpireTime = subjectVisit.CurrentActionUserExpireTime,
            //                PreliminaryAuditTime = subjectVisit.PreliminaryAuditTime,
            //                PreliminaryAuitUser = subjectVisit.PreliminaryAuitUser,
            //                ReviewAuitTime = subjectVisit.ReviewAuitTime,
            //                ReviewAuitUser = subjectVisit.ReviewAuitUser,

            //                AuditState = subjectVisit.AuditState,
            //                SubmitTime = subjectVisit.SubmitTime,
            //                IsTake = subjectVisit.IsTake,

            //            };
            #endregion

            #region  WhereIf + ling 统计
            //var query = from subjectVisit in _subjectVisitRepository.Where(x => x.TrialId == visitSearchDTO.TrialId)
            //           .WhereIf(visitSearchDTO.SiteId != null, t => t.SiteId == visitSearchDTO.SiteId)
            //           .WhereIf(visitSearchDTO.SubjectId != null, t => t.Subject.Id == visitSearchDTO.SubjectId)
            //           .WhereIf(!string.IsNullOrEmpty(subjectInfo), t => /*t.Subject.FirstName.Contains(subjectInfo) || t.Subject.LastName.Contains(subjectInfo) ||*/ t.Subject.Code.Contains(subjectInfo))
            //           .WhereIf(!string.IsNullOrEmpty(visitInfo), visitInfo.Contains('.') ? t => t.VisitNum.ToString().Contains(".") : t => t.VisitNum.ToString() == visitInfo)
            //           .WhereIf(visitSearchDTO.AuditState != null, t => t.AuditState == visitSearchDTO.AuditState)
            //           .WhereIf(visitSearchDTO.HandleUser != null, t => t.PreliminaryAuitUser.Contains(visitSearchDTO.HandleUser) || t.ReviewAuitUser.Contains(visitSearchDTO.HandleUser))
            //           .WhereIf(visitSearchDTO.IsUrgent != null, t => t.IsUrgent == visitSearchDTO.IsUrgent)
            //                //.WhereIf(visitSearchDTO.SubmitState != null, t => t.SubmitState == visitSearchDTO.SubmitState)
            //                //.WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState)
            //            join subject in _subjectRepository.AsQueryable() on subjectVisit.SubjectId equals subject.Id
            //            join trialSite in _trialSiteRepository.Where(t => t.TrialId == visitSearchDTO.TrialId) on subjectVisit.SiteId equals trialSite.SiteId
            //            join study in _studyRepository.AsQueryable().GroupBy(t => t.SubjectVisitId).Select(g => new { SubjectVisitId = g.Key, StudyCount = g.Count() }) on subjectVisit.Id equals study.SubjectVisitId into d
            //            from study in d.DefaultIfEmpty()
            //            join trial in _trialRepository.AsQueryable() on subjectVisit.TrialId equals trial.Id

            //            select new QCVisitViewModel()
            //            {
            //                Id = subjectVisit.Id,
            //                //VisitPlanId = visitStage.Id,
            //                SubjectId = subjectVisit.SubjectId,
            //                TrialId = subjectVisit.TrialId,
            //                SiteId = subjectVisit.SiteId,

            //                VisitDay = subjectVisit.VisitDay,
            //                VisitNum = subjectVisit.VisitNum,
            //                VisitName = subjectVisit.VisitName,
            //                SVENDTC = subjectVisit.SVENDTC,
            //                SVSTDTC = subjectVisit.SVSTDTC,
            //                SVUPDES = subjectVisit.SVUPDES,
            //                InPlan = subjectVisit.InPlan,
            //                VisitExecuted = subjectVisit.VisitExecuted,
            //                IsUrgent = subjectVisit.IsUrgent,
            //                EarliestScanDate = subjectVisit.EarliestScanDate,
            //                LatestScanDate = subjectVisit.LatestScanDate,

            //                CurrentActionUserId = subjectVisit.CurrentActionUserId,
            //                CurrentActionUser = subjectVisit.CurrentActionUser,
            //                CurrentActionUserExpireTime = subjectVisit.CurrentActionUserExpireTime,
            //                PreliminaryAuditTime = subjectVisit.PreliminaryAuditTime,
            //                PreliminaryAuitUser = subjectVisit.PreliminaryAuitUser,
            //                ReviewAuitTime = subjectVisit.ReviewAuitTime,
            //                ReviewAuitUser = subjectVisit.ReviewAuitUser,

            //                AuditState = subjectVisit.AuditState,
            //                SubmitTime = subjectVisit.SubmitTime,
            //                IsTake = subjectVisit.IsTake,

            //                QCProcessEnum = trial.QCProcessEnum,

            //                TrialSiteCode = trialSite.TrialSiteCode,

            //                SubjectStatus = subject.Status,
            //                SubjectCode = subject.Code,

            //                StudyCount = study.StudyCount,

            //            };

            #endregion

            var svExpression = QCCommon.GetSubjectVisitFilter(visitSearchDTO.VisitPlanArray);
            var query = _subjectVisitRepository.Where(x => x.TrialId == visitSearchDTO.TrialId)
                           .WhereIf(visitSearchDTO.CurrentActionUserId != null, t => t.CurrentActionUserId == visitSearchDTO.CurrentActionUserId)
                         .WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState)
                        .WhereIf(visitSearchDTO.SiteId != null, t => t.SiteId == visitSearchDTO.SiteId)
                        .WhereIf(visitSearchDTO.SubjectId != null, t => t.Subject.Id == visitSearchDTO.SubjectId)
                        .WhereIf(!string.IsNullOrEmpty(visitSearchDTO.SubjectInfo), t => /*t.Subject.FirstName.Contains(subjectInfo) || t.Subject.LastName.Contains(subjectInfo) ||*/ t.Subject.Code.Contains(visitSearchDTO.SubjectInfo))
                        .WhereIf(visitSearchDTO.VisitPlanArray != null && visitSearchDTO.VisitPlanArray?.Length > 0, svExpression)
                        //.WhereIf(!string.IsNullOrEmpty(visitSearchDTO.VisitPlanInfo), visitSearchDTO.VisitPlanInfo.Contains('.') ? t => t.VisitNum.ToString().Contains(".") : t => t.VisitNum == decimal.Parse(visitSearchDTO.VisitPlanInfo))
                        //.WhereIf(visitSearchDTO.AuditState != null, t => t.AuditState == visitSearchDTO.AuditState)
                        .WhereIf(visitSearchDTO.AuditStateArray != null && visitSearchDTO.AuditStateArray?.Length > 0, t => visitSearchDTO.AuditStateArray!.Contains(t.AuditState))

                        .WhereIf(visitSearchDTO.HandleUserId != null, t => t.PreliminaryAuditUserId == visitSearchDTO.HandleUserId || t.CurrentActionUserId == visitSearchDTO.HandleUserId
                        || t.ReviewAuditUserId == visitSearchDTO.HandleUserId
                        || t.QCChallengeList.Any(t => t.CreateUserId == visitSearchDTO.HandleUserId)
                        || t.QCChallengeDialogList.Any(t => t.CreateUserId == visitSearchDTO.HandleUserId))
                        .WhereIf(visitSearchDTO.IsUrgent != null, t => t.IsUrgent == visitSearchDTO.IsUrgent)
                        .Where(t => t.SubmitState != SubmitStateEnum.None)
                        //.WhereIf(visitSearchDTO.SubmitState != null, t => t.SubmitState == visitSearchDTO.SubmitState)
                        //.WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState)
                        .ProjectTo<QCVisitViewModel>(_mapper.ConfigurationProvider);

            var defalutSortArray = new string[] { nameof(SubjectVisit.IsUrgent) + " desc", nameof(SubjectVisit.SubjectId), nameof(SubjectVisit.VisitNum) };
            var pageList = await query.ToPagedListAsync(visitSearchDTO.PageIndex, visitSearchDTO.PageSize, visitSearchDTO.SortField, visitSearchDTO.Asc, string.IsNullOrWhiteSpace(visitSearchDTO.SortField), defalutSortArray);




            var config = await _repository.Where<Trial>(t => t.Id == visitSearchDTO.TrialId).ProjectTo<TrialSubjectAndSVConfig>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();

            return (pageList, config);

        }

        #endregion


        #region 一致性核查 转发页面
        /// <summary>
        /// 获取一致性核查列表  IC/PM 公用
        /// </summary>
        /// <param name="checkQuery"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<(PageOutput<QCCheckWithModalityView>, TrialSubjectAndSVConfig)> GetConsistencyVerificationList(CheckQuery checkQuery)
        {
            #region linq 废弃 byzhouhang  2021 11 30
            //Expression<Func<Subject, bool>> subjectLambda = x => true;
            //Expression<Func<SubjectVisit, bool>> subjectVisitLambda = x => x.TrialId == checkQuery.TrialId && x.AuditState == AuditStateEnum.QCPassed;
            //Expression<Func<DicomStudy, bool>> studyLambda = x => x.TrialId == checkQuery.TrialId;
            //if (checkQuery.SiteId != null && checkQuery.SiteId != Guid.Empty)
            //{
            //    subjectVisitLambda = subjectVisitLambda.And(t => t.SiteId == checkQuery.SiteId.Value);
            //}
            //if (checkQuery.SubjectId != null && checkQuery.SubjectId != Guid.Empty)
            //{
            //    subjectLambda = subjectLambda.And(t => t.Id == checkQuery.SubjectId.Value);
            //}

            //if (_userInfo.UserTypeEnumInt == (int)UserType.ClinicalResearchCoordinator)
            //{
            //    var siteQuery = _userTrialSiteRepository.Where(t => t.UserId == _userInfo.Id && t.TrialId == checkQuery.TrialId).Select(t => t.SiteId);

            //    subjectVisitLambda = subjectVisitLambda.And(t => siteQuery.Contains(t.SiteId));
            //}

            //var query =
            //            from subjectVisit in _subjectVisitRepository.Where(subjectVisitLambda)
            //            join trialSite in _trialSiteRepository.Where(t => t.TrialId == checkQuery.TrialId) on subjectVisit.SiteId equals trialSite.SiteId
            //            join subject in _subjectRepository.Where() on subjectVisit.SubjectId equals subject.Id

            //            select new QCCheckViewModel()
            //            {
            //                Id = subjectVisit.Id,
            //                AuditState = subjectVisit.AuditState,

            //                CheckTime = subjectVisit.CheckTime,
            //                CheckState = subjectVisit.CheckState,

            //                CheckChallengeState = subjectVisit.CheckChallengeState,

            //                CheckResult = subjectVisit.CheckResult,

            //                VisitName = subjectVisit.VisitName,
            //                VisitNum = subjectVisit.VisitNum,

            //                SubjectCode = subject.Code,

            //                //Modality=study.Modalities,
            //                //StudyTime = subjectVisit.sv,
            //                TrialSiteCode = trialSite.TrialSiteCode,
            //            };
            #endregion

            var svExpression = QCCommon.GetSubjectVisitFilter(checkQuery.VisitPlanArray);

            var query = _subjectVisitRepository.Where(x => x.TrialId == checkQuery.TrialId)
                        .Where(x => x.AuditState == AuditStateEnum.QCPassed) //一致性核查中的，或者还没一致性核查的                                                                                                                 
                        .WhereIf(checkQuery.CheckState != null, t => t.CheckState == checkQuery.CheckState)
                        .WhereIf(checkQuery.SiteId != null, t => t.SiteId == checkQuery.SiteId)
                        .WhereIf(!string.IsNullOrEmpty(checkQuery.SubjectInfo), t => t.Subject.Code.Contains(checkQuery.SubjectInfo))
                        .WhereIf(checkQuery.VisitPlanArray != null && checkQuery.VisitPlanArray?.Length > 0, svExpression)
                        //.WhereIf(!string.IsNullOrEmpty(checkQuery.VisitPlanInfo), checkQuery.VisitPlanInfo.Contains('.') ? t => t.InPlan == false : t => t.VisitNum == decimal.Parse(checkQuery.VisitPlanInfo))
                        .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))//IC 过滤负责的site
                        .ProjectTo<QCCheckWithModalityView>(_mapper.ConfigurationProvider);

            var pageList = await query.ToPagedListAsync(checkQuery.PageIndex, checkQuery.PageSize, checkQuery.SortField, checkQuery.Asc);
            var config = await _repository.Where<Trial>(t => t.Id == checkQuery.TrialId).ProjectTo<TrialSubjectAndSVConfig>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
            return (pageList, config);
        }

        /// <summary>
        /// 一致性核查 聊天记录列表
        /// </summary>
        /// <param name="subjectVisitId"></param>
        /// <returns></returns>
        /// 

        [HttpGet("{subjectVisitId:guid}")]
        public async Task<CheckDialogDTO> GetCheckChallengeDialogList(Guid subjectVisitId)
        {

            var sv = (await _subjectVisitRepository.Where(t => t.Id == subjectVisitId)
                  .ProjectTo<CheckDialogDTO>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();

            sv.DialogList.ForEach(t => t.IsCurrentUser = _userInfo.Id == t.CreateUserId);

            return sv;
        }

        /// <summary>
        /// 转发列表  查询一致性核查通过的，针对不一致性核查的 要维护CV状态
        /// </summary>
        /// <param name="forwardQuery"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageOutput<ForWardViewModel>> GetForwardList(ForwardQuery forwardQuery)
        {
            //var trialConfig = _trialReposioty.Select(t => new { TrialId = t.Id, t.QCProcessEnum, t.IsImageConsistencyVerification }).FirstOrDefault(t => t.TrialId == forwardQuery.TrialId);

            var svExpression = QCCommon.GetSubjectVisitFilter(forwardQuery.VisitPlanArray);

            var query = _subjectVisitRepository.Where(x => x.TrialId == forwardQuery.TrialId)
                        .Where(t => t.CheckState == CheckStateEnum.CVPassed)
                       .WhereIf(forwardQuery.ForwardState != null, t => t.ForwardState == forwardQuery.ForwardState)
                        .WhereIf(forwardQuery.SiteId != null, t => t.SiteId == forwardQuery.SiteId)
                       .WhereIf(!string.IsNullOrEmpty(forwardQuery.SubjectInfo), t => t.Subject.Code.Contains(forwardQuery.SubjectInfo))
                        .WhereIf(forwardQuery.VisitPlanArray != null && forwardQuery.VisitPlanArray?.Length > 0, svExpression)
                       //.WhereIf(!string.IsNullOrEmpty(forwardQuery.VisitPlanInfo), forwardQuery.VisitPlanInfo.Contains('.') ? t => t.InPlan == false : t => t.VisitNum == decimal.Parse(forwardQuery.VisitPlanInfo))
                       //.WhereIf(_userInfo.UserTypeEnumInt == (int)UserType.ClinicalResearchCoordinator, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))//IC 过滤负责的site
                       .ProjectTo<ForWardViewModel>(_mapper.ConfigurationProvider);

            return await query.ToPagedListAsync(forwardQuery.PageIndex, forwardQuery.PageSize, forwardQuery.SortField, forwardQuery.Asc);

        }

        #endregion



        #region QC 具体质控页面 各种列表
        /// <summary>
        /// 获取某次检查批次 QA界面所有信息  单独每一项都有接口（往下看），这里是一个大接口，方便第一次获取完整的所有的数据
        /// </summary>
        /// <param name="subjectVisitId"></param>
        /// <param name="trialQCProcess">项目配置的针对检查批次检查是那种审核，0 不审，1 单审，2双审</param>
        /// <param name="currentQCType">当前 QC进入的是那种审核 1 单审，2复审</param>

        [HttpGet("{subjectVisitId:guid}/{trialQCProcess:int}/{currentQCType:int}")]
        public async Task<TrialVisitQADTO> GetVisitQCInfo(Guid subjectVisitId, [FromRoute] TrialQCProcess trialQCProcess, [FromRoute] CurrentQC currentQCType)
        {
            var sv = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId)).IfNullThrowException();

            var temp = await GetVisitQCStudyAndSeriesList(subjectVisitId);

            var qacheckList = await GetQCQuestionAnswerList(subjectVisitId, sv.TrialId, trialQCProcess, currentQCType);

            return new TrialVisitQADTO
            {
                QCQuestionAnswerList = qacheckList,
                StudyList = temp.StudyList,
                SeriesList = temp.SeriesList,
                RelationInfo = await GetVisitQCSubjectInfo(subjectVisitId),
                NoneDicomStudyList = await _repository.Where<NoneDicomStudy>(t => t.SubjectVisitId == subjectVisitId).ProjectTo<NoneDicomStudyView>(_mapper.ConfigurationProvider).ToListAsync(),
                SubjectClinicalData = await _subjectVisitRepository.Where(t => t.Id == subjectVisitId)
                .ProjectTo<SubjectClinicalDataDto>(_mapper.ConfigurationProvider, new { subjectVisitId = subjectVisitId, token = _userInfo.UserToken }).FirstOrDefaultAsync()
            };
        }

        /// <summary>
        /// 获取质控问题答案
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<QCQuestionAnswer>> GetQCQuestionAnswer(GetQCQuestionAnswerInDto inDto)
        {
            var questionAnswerlist = await (from data in _trialQCQuestionRepository.Where(x => x.TrialId == inDto.TrialId && x.IsEnable)
                                            join answer in _trialQCQuestionAnswerRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId && x.QCProcessEnum == inDto.QCProcessEnum && x.CurrentQCEnum == inDto.CurrentQCEnum).AsQueryable() on data.Id equals answer.TrialQCQuestionConfigureId into answertemp
                                            from leftanswer in answertemp.DefaultIfEmpty()
                                            select new QCQuestionAnswer()
                                            {
                                                Answer = leftanswer.Answer,
                                                ShowOrder = data.ShowOrder,
                                                QuestionName = data.QuestionName,
                                                Id = data.Id,
                                                IsRequired = data.IsRequired,
                                                ParentId = data.ParentId,
                                                ParentTriggerValue = data.ParentTriggerValue,
                                                Type = data.Type,
                                                TypeValue = data.TypeValue
                                            }).ToListAsync();

            var result = questionAnswerlist.Where(x => x.ParentId == null).ToList();
            result.ForEach(x =>
            {
                GetQuestionChild(x, questionAnswerlist);
            });

            return result;
        }


        private void GetQuestionChild(QCQuestionAnswer parent, List<QCQuestionAnswer> dataList)
        {
            parent.Childrens = dataList.Where(x => x.ParentId == parent.Id).ToList();

            if (parent.Childrens.Count != 0)
            {
                parent.Childrens.ForEach(x =>
                {
                    GetQuestionChild(x, dataList);
                });
            }


        }

        /// <summary>
        /// 获取某次检查批次 QC 问题核对答案 列表  初始化进去的时候是模板项，QC填写了就是对应的内容
        /// </summary>
        /// <param name="subjectVisitId"></param>
        /// <param name="trialId"></param>
        /// <param name="trialQCProcess">项目配置的针对检查批次检查是那种审核，0 不审，1 单审，2双审</param>
        /// <param name="currentQCType">当前 QC进入的是那种审核 1 单审，2复审</param>

        [HttpGet("{trialId:guid}/{subjectVisitId:guid}/{trialQCProcess:int}/{currentQCType:int}")]
        public async Task<List<QCQuestionAnswerItemDto>> GetQCQuestionAnswerList(Guid subjectVisitId, Guid trialId, [FromRoute] TrialQCProcess trialQCProcess, [FromRoute] CurrentQC currentQCType)
        {

            //https://github.com/dotnet/efcore/issues/26833  ef core 导航属性不支持右连接   

            // 直接用ProjectTo的方式   多做一次查询 代码简洁很多 特别是连表多，字段多的情况
            if (await _repository.AnyAsync<TrialQCQuestionAnswer>(t => t.SubjectVisitId == subjectVisitId && t.QCProcessEnum == trialQCProcess && t.CurrentQCEnum == currentQCType))
            {
                var list = await _repository.Where<TrialQCQuestionAnswer>(t => t.SubjectVisitId == subjectVisitId && t.QCProcessEnum == trialQCProcess && t.CurrentQCEnum == currentQCType).OrderBy(t => t.TrialQCQuestionConfigure.ShowOrder)
                       .ProjectTo<QCQuestionAnswerItemDto>(_mapper.ConfigurationProvider).ToListAsync();

                return list;
            }
            else
            {
                return await _repository.Where<TrialQCQuestion>(t => t.IsEnable == true && t.TrialId == trialId).OrderBy(t => t.ShowOrder).ProjectTo<QCQuestionAnswerItemDto>(_mapper.ConfigurationProvider).ToListAsync();
            }

        }


        /// <summary>
        /// 获次QC 历史质疑列表  不分页
        /// </summary>
        /// <param name="subjectVisitId"></param>
        /// <param name="trialQCProcess">项目配置的针对检查批次检查是那种审核，0 不审，1 单审，2双审</param>
        /// <param name="currentQCType">当前 QC进入的是那种审核 1 单审，2复审</param>

        [HttpGet("{subjectVisitId:guid}/{trialQCProcess:int}/{currentQCType:int}")]
        public async Task<List<QCChallengeWithUser>> GetHistoryChallengeList(Guid subjectVisitId, [FromRoute] TrialQCProcess trialQCProcess, [FromRoute] CurrentQC currentQCType)
        {
            var qaChallengeQuery = _repository.Where<QCChallenge>(t => t.SubjectVisitId == subjectVisitId && t.QCProcessEnum == trialQCProcess)
                .WhereIf(currentQCType == CurrentQC.First, t => t.CurrentQCEnum == currentQCType)//复审的时候可以看到初审的质疑
                .ProjectTo<QCChallengeWithUser>(_mapper.ConfigurationProvider);
            var qaChallenges = await qaChallengeQuery.ToListAsync();

            return qaChallenges;
        }


        /// <summary>
        /// 获取检查批次下的患者检查批次、患者、site信息
        /// </summary>
        /// <param name="subjectVisitId"></param>
        /// <returns></returns>
        public async Task<QARelationInfo> GetVisitQCSubjectInfo(Guid subjectVisitId)
        {

            // automapper  Explicit expansion  ProjectTo 
            return await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).ProjectTo<QARelationInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();

        }



        /// <summary>
        ///   检查批次下的Study 和Series列表
        /// </summary>
        /// <param name="subjectVisitId"></param>
        /// <returns></returns>
        [HttpGet("{subjectVisitId:guid}")]
        public async Task<QAStudySeriesInfo> GetVisitQCStudyAndSeriesList(Guid subjectVisitId)
        {
            var studyList = await _repository.Where<DicomStudy>(s => s.SubjectVisitId == subjectVisitId).IgnoreQueryFilters().ProjectTo<QAStudyInfoDTO>(_mapper.ConfigurationProvider).ToListAsync();
            var studyIds = studyList.Select(t => t.StudyId).ToList();

            var seriesList = await _repository.Where<DicomSeries>(t => studyIds.Contains(t.StudyId)).IgnoreQueryFilters().ProjectTo<QASeriesInfoDto>(_mapper.ConfigurationProvider)
                .OrderBy(t => t.StudyCode).ThenBy(t => t.SeriesNumber).ToListAsync();

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

        }

        /// <summary>
        /// 检查批次下的检查列表  
        /// </summary>
        /// <param name="subjectVisitId"></param>
        /// <returns></returns>
        [HttpGet("{subjectVisitId:guid}")]
        public async Task<(List<QAStudyInfoDTO>,object)> GetSubjectVisitUploadedStudyList(Guid subjectVisitId)
        {
            var list= await _repository.Where<DicomStudy>(s => s.SubjectVisitId == subjectVisitId).IgnoreQueryFilters().ProjectTo<QAStudyInfoDTO>(_mapper.ConfigurationProvider).ToListAsync();


            var config = await _repository.Where<SubjectVisit>(t => t.Id == subjectVisitId).Select(t=>t.Trial).ProjectTo<TrialSubjectAndSVConfig>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();

            return (list, config);
        }


        /// <summary>
        /// 展开 某一QC质疑 下得 聊天记录 
        /// </summary>
        /// <param name="qaChallengeId"></param>
        /// <returns></returns>
        [HttpGet("{qaChallengeId:guid}")]
        public async Task<List<ChallengeAndDialog>> GetQCChallengeDialogList(Guid qaChallengeId)
        {

            var list = await _repository.Where<QCChallenge>(t => t.Id == qaChallengeId)
                  .ProjectTo<ChallengeAndDialog>(_mapper.ConfigurationProvider, new { currentUserId = _userInfo.Id }).ToListAsync();

            //利用automapper 运行时映射
            //list.ForEach(t => t.IsCurrentUser = _userInfo.Id == t.CreateUserId);

            return list;
        }

        #endregion


        /// <summary>
        /// IC/PM  看到某次检查批次下的所有质疑和聊天内容  包括初审和复审的 。
        /// </summary>
        /// <param name="subjectVisitId"></param>
        /// <param name="trialQCProcess"></param>
        /// <returns></returns>
        [HttpGet("{subjectVisitId:guid}/{trialQCProcess:int}")]
        public async Task<List<ChallengeAndDialog>> GetCRCVisitChallengeAndDialog(Guid subjectVisitId, [FromRoute] TrialQCProcess trialQCProcess)
        {

            var qaChallengeQuery = _repository.Where<QCChallenge>(t => t.SubjectVisitId == subjectVisitId && t.QCProcessEnum == trialQCProcess)
                .ProjectTo<ChallengeAndDialog>(_mapper.ConfigurationProvider, new { currentUserId = _userInfo.Id });

            var list = await qaChallengeQuery.ToListAsync();

            //list.ForEach(t => t.DialogList.ToList().ForEach(u => u.IsCurrentUser = _userInfo.Id == u.CreateUserId));

            return list;
        }

        /// <summary>
        ///  质询发起人
        /// </summary>
        /// <param name="trialId"></param>
        /// <returns></returns>
        [HttpGet("{trialId:guid}")]
        public async Task<List<QCChanllengeCreatorDto>> GetQCChallengeCreatorList(Guid trialId)
        {

            return await _repository.Where<TrialUser>(t => t.TrialId == trialId && t.User.UserTypeEnum == UserTypeEnum.IQC).Select(t => new QCChanllengeCreatorDto()
            {
                CreatorRealName = t.User.FullName,
                Creator = t.User.UserName,
                CreateUserId = t.UserId
            }).ToListAsync();

        }

        /// <summary>
        ///  QC  质疑页面  处理用户 下拉框
        /// </summary>
        /// <param name="trialId"></param>
        /// <returns></returns>
        [HttpGet("{trialId:guid}")]
        public async Task<List<ParticipantDTO>> GetQCParticipantList(Guid trialId)
        {
            return await _repository.Where<TrialUser>(t => t.TrialId == trialId && (t.User.UserTypeEnum == UserTypeEnum.IQC || t.User.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator)).Select(t => new ParticipantDTO()
            {
                HandleUserRealName = t.User.FullName,
                HandleUser = t.User.UserName,
                HandleUserId = t.UserId
            }).ToListAsync();
        }



        /// <summary>
        /// 获取一致性核查文件上传记录
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageOutput<GetConsistencyCheckFileDto>> GetConsistencyCheckFile(GetConsistencyCheckFileInDto indto)
        {
            var query = _repository.Where<ConsistencyCheckFile>(t => t.TrialId == indto.TrialId)
             .ProjectTo<GetConsistencyCheckFileDto>(_mapper.ConfigurationProvider);

            return await query.ToPagedListAsync(indto.PageIndex, indto.PageSize, "CreateTime", false);
        }


        /// <summary>
        ///  添加计划外检查批次 下拉框 选择上一次检查批次
        /// </summary>
        /// <param name="subjectId"></param>
        /// <returns></returns>
        [HttpGet("{subjectId:guid}")]
        public async Task<List<SubjectVisitSelectItem>> GetSubjectVisitSelectList(Guid subjectId)
        {
            return await _subjectVisitRepository.Where(t => t.SubjectId == subjectId).OrderBy(T => T.VisitNum).ProjectTo<SubjectVisitSelectItem>(_mapper.ConfigurationProvider).ToListAsync();
        }



        /// <summary>
        /// 上传界面 患者 检查批次、site 基本信息
        /// </summary>
        /// <param name="subjectVisitId"></param>
        /// <returns></returns>
        [HttpGet("{subjectVisitId:guid}/{trialQCProcess:int}")]
        [Obsolete]
        public async Task<UploadViewInitDto> GetUploadInitInfo(Guid subjectVisitId)
        {
            return await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).ProjectTo<UploadViewInitDto>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
        }


    }
}
