using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Service.Inspection.DTO;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using Microsoft.AspNetCore.Mvc;
using Panda.DynamicWebApi.Attributes;
using System.Linq.Dynamic.Core;

namespace IRaCIS.Core.Application.Service
{
    /// <summary>
    /// 阅片临床数据
    /// </summary>
    [ApiExplorerSettings(GroupName = "Reading")]
    public class ReadingClinicalDataService(IRepository<ReadingClinicalData> _readingClinicalDataRepository,
        IRepository<ReadingConsistentClinicalData> _readingConsistentClinicalDataRepository,
        IRepository<ClinicalDataTrialSet> _clinicalDataTrialSetRepository,
        IRepository<VisitTask> _visitTaskRepository,
        IRepository<PreviousPDF> _previousPDFRepository,
        IRepository<SubjectVisit> _subjectVisitRepository,
        IRepository<PreviousHistory> _previousHistoryRepository,
        IRepository<ReadModuleCriterionFrom> _readModuleCriterionFromRepository,
        IRepository<ClinicalForm> _clinicalFormRepository,
        IRepository<PreviousOther> _previousOtherRepository,
        IRepository<PreviousSurgery> _previousSurgeryRepository,
        IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
        IServiceProvider iServiceProvider,
        IRepository<Subject> _subjectRepository,
        IRepository<ReadModule> _readModuleRepository,
        IRepository<ReadingClinicalDataPDF> _readingClinicalDataPDFRepository,
        IRepository<ReadingConsistentClinicalDataPDF> _readingConsistentClinicalDataPDFRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IReadingClinicalDataService
    {



        #region 临床数据基本增删改



        /// <summary>
        /// 新增或者修改
        /// </summary>
        /// <param name="indto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> AddOrUpdateReadingClinicalData(AddOrUpdateReadingClinicalDataDto indto)
        {
            var existsQuery = _readingClinicalDataRepository
                .WhereIf(indto.Id != null, x => x.Id != indto.Id)
                .Where(x => x.ClinicalDataTrialSetId == indto.ClinicalDataTrialSetId && x.ReadingId == indto.ReadingId && x.StudyId == indto.StudyId);

            if (await existsQuery.AnyAsync())
            {
                //---存在同类型的临床数据,操作失败
                return ResponseOutput.NotOk(_localizer["ReadingClinicalData_DupTypeFail"]);
            }
            var clinicalDataTrialSet = (await _clinicalDataTrialSetRepository.Where(x => x.Id == indto.ClinicalDataTrialSetId).FirstOrDefaultAsync()).IfNullThrowException();

            //subject  或者访视级别的  都是在访视传
            indto.IsVisit = clinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject || clinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit;

            if (indto.Id == null)
            {
                var entity = _mapper.Map<ReadingClinicalData>(indto);
                entity.ReadingClinicalDataPDFList = indto.AddFileList.Select(x => new ReadingClinicalDataPDF()
                {
                    FileName = x.FileName,
                    Path = x.Path,
                    Size = x.Size,
                    Type = x.Type,
                }).ToList();

                entity.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded;
                entity.IsBlind = null;
                entity.IsComplete = null;
                entity.FileCount = entity.ReadingClinicalDataPDFList.Count;
                await _readingClinicalDataRepository.AddAsync(entity, true);
                var success = await _readingClinicalDataRepository.SaveChangesAsync();
                return ResponseOutput.Ok(entity.Id);
            }
            else
            {
                var entity = (await _readingClinicalDataRepository.Where(t => t.Id == indto.Id, true).FirstOrDefaultAsync()).IfNullThrowException();
                await _readingClinicalDataPDFRepository.BatchDeleteNoTrackingAsync(x => indto.DeleteFileIds.Contains(x.Id));

                var addFileList = indto.AddFileList.Select(x => new ReadingClinicalDataPDF()
                {

                    FileName = x.FileName,
                    Path = x.Path,
                    Size = x.Size,
                    Type = x.Type,
                    ReadingClinicalDataId = entity.Id,
                }).ToList();



                _mapper.Map(indto, entity);

                //上传  或者删除了文件 核查状态需要重新确认

                if (indto.AddFileList.Count > 0 || indto.AddFileList.Count > 0)
                {
                    entity.IsComplete = null;
                    entity.IsBlind = null;
                }

                await _readingClinicalDataPDFRepository.AddRangeAsync(addFileList);

                await _readingClinicalDataPDFRepository.SaveChangesAsync();

                var fileCount = await _readingClinicalDataPDFRepository.Where(t => t.ReadingClinicalDataId == indto.Id).CountAsync();
                entity.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded;
                entity.IsSign = false;
                entity.FileCount = fileCount;
                var success = await _readingClinicalDataRepository.SaveChangesAsync();
                return ResponseOutput.Ok(entity.Id);

            }

        }


        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete("{id:guid}")]
        public async Task<IResponseOutput> DeleteReadingClinicalData(Guid id)
        {

            await _readingClinicalDataRepository.DeleteFromQueryAsync(x => x.Id == id, true);
            await _readingClinicalDataPDFRepository.DeleteFromQueryAsync(x => x.ReadingClinicalDataId == id, true);
            return ResponseOutput.Result(true);
        }


        #endregion


        #region 临床数据CRC  相关

        /// <summary>
        /// 获取检查类型临床数据
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        public async Task<List<GetCRCClinicalDataOutDto>> GetStudyClinicalData(GetStudyClinicalDataInDto inDto)
        {

            var cRCClinicalDataList = await _readingClinicalDataRepository.Where(x => x.ReadingId == inDto.SubjectVisitId)
                .Where(x => x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Study).Select(x => new GetCRCClinicalDataOutDto()
                {
                    Id = x.Id,
                    ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us),
                    ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType,
                    ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel,
                    ClinicalDataSetEnName = x.ClinicalDataTrialSet.ClinicalDataSetEnName,
                    ClinicalDataTrialSetId = x.ClinicalDataTrialSet.Id,
                    FileName = x.ClinicalDataTrialSet.FileName,
                    UploadRole = x.ClinicalDataTrialSet.UploadRole,
                    Path = x.ClinicalDataTrialSet.Path,
                    IsBlind = x.IsBlind,
                    IsComplete = x.IsComplete,
                    ClinicalFromList = x.Subject.ClinicalFormList.Where(y => y.ReadingId == x.ReadingId && y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Select(y => new ClinicalFromData()
                    {
                        CheckDate = y.CheckDate,
                        ClinicalFormId = y.Id
                    }).ToList(),
                    PDFFileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto()
                    {
                        Id = y.Id,
                        Size = y.Size,
                        Type = y.Type,
                        FileName = y.FileName,
                        Path = y.Path,
                        CreateTime = y.CreateTime,
                    }).ToList(),

                }).ToListAsync();

            var previousHistoryList = await _previousHistoryRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId).ProjectTo<PreviousHistoryView>(_mapper.ConfigurationProvider).ToListAsync();
            var previousOtherList = await _previousOtherRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId).ProjectTo<PreviousOtherView>(_mapper.ConfigurationProvider).ToListAsync();
            var previousSurgeryList = await _previousSurgeryRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId).ProjectTo<PreviousSurgeryView>(_mapper.ConfigurationProvider).ToListAsync();

            foreach (var item in cRCClinicalDataList)
            {
                item.ClinicalTableData = new ClinicalDataTable()
                {
                    PreviousHistoryList = previousHistoryList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(),
                    PreviousOtherList = previousOtherList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(),
                    PreviousSurgeryList = previousSurgeryList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(),
                };

            }
            return cRCClinicalDataList;
        }

        /// <summary>
        /// 获取CRC上传的文件
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<GetCRCClinicalDataOutDto>> GetCRCClinicalData(GetCRCClinicalDataInDto inDto)
        {

            var query = _readingClinicalDataRepository.AsQueryable();
            if (inDto.StudyId != null)
            {
                query = query.Where(x => x.StudyId == inDto.StudyId.Value && x.ReadingId == inDto.SubjectVisitId);
            }
            else
            {
                query = query.Where(x => x.ReadingId == inDto.SubjectVisitId)
                .WhereIf(inDto.IsBaseline, x => x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject || x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit)
                .WhereIf(!inDto.IsBaseline, x => x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit)
                .Where(x => x.ClinicalDataTrialSet.TrialId == inDto.TrialId && x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC);

            }


            List<GetCRCClinicalDataOutDto> cRCClinicalDataList = await query
                .Select(x => new GetCRCClinicalDataOutDto()
                {
                    Id = x.Id,
                    ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us),
                    ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType,
                    ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel,
                    ClinicalDataSetEnName = x.ClinicalDataTrialSet.ClinicalDataSetEnName,
                    ClinicalDataTrialSetId = x.ClinicalDataTrialSet.Id,
                    FileName = x.ClinicalDataTrialSet.FileName,
                    UploadRole = x.ClinicalDataTrialSet.UploadRole,
                    Path = x.ClinicalDataTrialSet.Path,
                    IsBlind = x.IsBlind,
                    IsComplete = x.IsComplete,
                    ClinicalFromList = x.Subject.ClinicalFormList.Where(y => y.ReadingId == x.ReadingId && y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Select(y => new ClinicalFromData()
                    {
                        CheckDate = y.CheckDate,
                        ClinicalFormId = y.Id
                    }).ToList(),
                    PDFFileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto()
                    {
                        Id = y.Id,
                        FileName = y.FileName,
                        Path = y.Path,
                        Size = y.Size,
                        Type = y.Type,
                        CreateTime = y.CreateTime,
                    }).ToList(),

                }).ToListAsync();

            var previousHistoryList = await _previousHistoryRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId).ProjectTo<PreviousHistoryView>(_mapper.ConfigurationProvider).ToListAsync();
            var previousOtherList = await _previousOtherRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId).ProjectTo<PreviousOtherView>(_mapper.ConfigurationProvider).ToListAsync();
            var previousSurgeryList = await _previousSurgeryRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId).ProjectTo<PreviousSurgeryView>(_mapper.ConfigurationProvider).ToListAsync();

            foreach (var item in cRCClinicalDataList)
            {
                item.ClinicalTableData = new ClinicalDataTable()
                {
                    PreviousHistoryList = previousHistoryList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(),
                    PreviousOtherList = previousOtherList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(),
                    PreviousSurgeryList = previousSurgeryList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(),
                };

            }

            if (inDto.FilterNoneForm)
            {
                cRCClinicalDataList = cRCClinicalDataList.Where(x => !(x.ClinicalFromList.Count() == 0 && x.ClinicalUploadType == ClinicalUploadType.Structuring)).ToList();

            }

            return cRCClinicalDataList;
        }


        /// <summary>
        /// 添加CRC数据类型
        /// </summary>
        /// <returns></returns>
        private async Task AddCRCClinicalData(GetCRCClinicalDataInDto inDto)
        {
            var cRCClinicalDataIds = await _clinicalDataTrialSetRepository.Where(x => x.TrialId == inDto.TrialId && x.UploadRole == UploadRole.CRC && x.IsConfirm)
                .WhereIf(inDto.IsBaseline, x => x.ClinicalDataLevel == ClinicalLevel.Subject || x.ClinicalDataLevel == ClinicalLevel.SubjectVisit)
                  .WhereIf(!inDto.IsBaseline, x => x.ClinicalDataLevel == ClinicalLevel.SubjectVisit)
                .Select(x => x.Id).ToListAsync();

            var needAddIds = cRCClinicalDataIds.Where(x => _readingClinicalDataRepository.Where(y => y.ReadingId == inDto.SubjectVisitId && x == y.ClinicalDataTrialSetId).Count() == 0).ToList();

            List<ReadingClinicalData> readingClinicals = needAddIds.Select(x => new ReadingClinicalData()
            {
                ClinicalDataTrialSetId = x,
                IsVisit = true,
                SubjectId = inDto.SubjectId,
                ReadingId = inDto.SubjectVisitId,
                TrialId = inDto.TrialId
            }).ToList();

            await _readingClinicalDataRepository.AddRangeAsync(readingClinicals);

            await _readingClinicalDataRepository.SaveChangesAsync();

        }

        #endregion


        #region 临床数据签名 和确认

        /// <summary>
        /// 影像阅片临床数据签名
        /// </summary>
        // [HttpPost]

        public async Task<IResponseOutput> ReadClinicalDataSign(ReadingClinicalDataSignIndto inDto)
        {


            var data = await _readingClinicalDataRepository.FirstOrDefaultAsync(t => t.Id == inDto.ReadingClinicalDataId);

            //if (data.ReadingClinicalDataState != ReadingClinicalDataStatus.HaveChecked)
            //{
            //    //---当前临床数据状态不是已核查状态,不允许签名!
            //    throw new BusinessValidationFailedException(_localizer["ReadingClinicalData_Unchecked"]);
            //}

            data.IsBlind = inDto.IsBlind;
            data.IsComplete = inDto.IsComplete;
            data.IsSign = true;
            data.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveSigned;

            //await _readingClinicalDataRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.ReadingClinicalDataId, x => new ReadingClinicalData()
            //{
            //    IsSign = true,
            //    ReadingClinicalDataState = ReadingClinicalDataStatus.HaveSigned
            //});

            var result = await _readingClinicalDataRepository.SaveChangesAsync();


            var readingId = await _readingClinicalDataRepository.Where(x => x.Id == inDto.ReadingClinicalDataId).Select(x => x.ReadingId).FirstOrDefaultAsync();

            //await this.iServiceProvider.GetService<IReadingImageTaskService>().AddOncologyTask(readingId);

            //如果先生成了任务,再签名subject级别 PM 临床数据,那么会导致其他标准的任务签名状态无法得到维护

            if (await _clinicalDataTrialSetRepository.AnyAsync(t => t.Id == data.ClinicalDataTrialSetId && t.UploadRole == UploadRole.PM && (t.ClinicalDataLevel == ClinicalLevel.Subject || t.ClinicalDataLevel == ClinicalLevel.SubjectVisit)))
            {
                var needDealTrialReadingCriterionIdList = _clinicalDataTrialSetRepository.Where(t => t.Id == data.ClinicalDataTrialSetId)
                  .SelectMany(t => t.TrialClinicalDataSetCriteriaList)
                  .Select(u => u.TrialReadingCriterionId).Distinct().ToList();

                foreach (var trialReadingCriterionId in needDealTrialReadingCriterionIdList)
                {
                    await DealVisiTaskClinicalDataSignedAsync(data.TrialId, data.SubjectId, data.ReadingId, data.IsVisit, trialReadingCriterionId);
                }
            }
            else
            {
                await DealVisiTaskClinicalDataSignedAsync(data.TrialId, data.SubjectId, data.ReadingId, data.IsVisit, inDto.TrialReadingCriterionId);

            }



            return ResponseOutput.Result(result);
        }

        ///// <summary>
        ///// 一致性分析的临床数据
        ///// </summary>
        ///// <param name="inDto"></param>
        ///// <returns></returns>
        //public async Task<IResponseOutput> ReadClinicalDataSign(ReadingClinicalDataSignIndto inDto)
        //{


        //    var data = await _readingClinicalDataRepository.FirstOrDefaultAsync(t => t.Id == inDto.ReadingClinicalDataId);

        //    data.IsBlind = inDto.IsBlind;
        //    data.IsComplete = inDto.IsComplete;
        //    data.IsSign = true;
        //    data.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveSigned;
        //    var result = await _readingClinicalDataRepository.SaveChangesAsync();


        //    var readingId = await _readingClinicalDataRepository.Where(x => x.Id == inDto.ReadingClinicalDataId).Select(x => x.ReadingId).FirstOrDefaultAsync();



        //    //如果先生成了任务,再签名subject级别 PM 临床数据,那么会导致其他标准的任务签名状态无法得到维护

        //    if (await _clinicalDataTrialSetRepository.AnyAsync(t => t.Id == data.ClinicalDataTrialSetId && t.UploadRole == UploadRole.PM && t.ClinicalDataLevel == ClinicalLevel.Subject))
        //    {
        //        var needDealTrialReadingCriterionIdList = _clinicalDataTrialSetRepository.Where(t => t.Id == data.ClinicalDataTrialSetId)
        //          .SelectMany(t => t.TrialClinicalDataSetCriteriaList)
        //          .Select(u => u.TrialReadingCriterionId).Distinct().ToList();

        //        foreach (var trialReadingCriterionId in needDealTrialReadingCriterionIdList)
        //        {
        //            await DealVisiTaskClinicalDataSignedAsync(data.TrialId, data.SubjectId, data.ReadingId, data.IsVisit, trialReadingCriterionId);
        //        }
        //    }
        //    else
        //    {
        //        await DealVisiTaskClinicalDataSignedAsync(data.TrialId, data.SubjectId, data.ReadingId, data.IsVisit, inDto.TrialReadingCriterionId);

        //    }



        //    return ResponseOutput.Result(result);
        //}

        //处理 任务  临床数据是否签名
        public async Task DealVisiTaskClinicalDataSignedAsync(Guid trialId, Guid subjectId, Guid readingId, bool isVisit, Guid trialReadingCritrialId)
        {
            //获取确认的临床数据配置
            var trialClinicalDataSetList = _clinicalDataTrialSetRepository.Where(t => t.TrialId == trialId && t.IsConfirm).Include(t => t.TrialClinicalDataSetCriteriaList).ToList();

            //var criterionType = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == trialReadingCritrialId).Select(t => t.CriterionType).FirstOrDefaultAsync();

            // 获取确认的项目标准  废弃   签名的时候 传递标准Id
            //var confirmedCtritrialList = _readingQuestionCriterionTrialRepository.Where(t => t.TrialId == trialId && t.ReadingInfoSignTime != null).Select(t => new { t.Id, t.CriterionType }).ToList();

            var needSignCount = 0;
            var haveSignedCount = _readingClinicalDataRepository.Where(t => t.TrialId == trialId && t.IsSign && t.ReadingClinicalDataState == ReadingClinicalDataStatus.HaveSigned && t.ReadingId == readingId && t.ClinicalDataTrialSet.UploadRole == UploadRole.PM).Count();

            ReadModule readModule = null;

            if (isVisit)
            {
                var isBaseLine = await _subjectVisitRepository.Where(t => t.Id == readingId).Select(t => t.IsBaseLine).FirstOrDefaultAsync();



                //判断是否基线
                if (isBaseLine)
                {
                    //CRC 的自动签名   不用管 只用处理PM 的就好
                    needSignCount = trialClinicalDataSetList.Where(t => t.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCritrialId) && (t.ClinicalDataLevel == ClinicalLevel.Subject || t.ClinicalDataLevel == ClinicalLevel.SubjectVisit) && t.UploadRole == UploadRole.PM).Count();
                }
                else
                {
                    needSignCount = trialClinicalDataSetList.Where(t => t.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCritrialId) && t.ClinicalDataLevel == ClinicalLevel.SubjectVisit && t.UploadRole == UploadRole.PM).Count();
                }

                //可能仅仅CRC 基线   没有PM
                if (needSignCount == haveSignedCount /*&& needSignCount != 0*/)
                {

                    //将该标准  该subject 该访视 任务临床数据状态变更
                    await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCritrialId && t.SourceSubjectVisitId == readingId, u => new VisitTask()
                    {
                        IsClinicalDataSign = true
                    });

                }


            }
            else
            {
                //判断是影像学 还是肿瘤学阅片
                readModule = await _readModuleRepository.Where(t => t.Id == readingId).FirstNotNullAsync();

                //CRC 阅片期自定义结构化录入是否签名
                bool crcReadModuleSign = true;

                //影像学
                if (readModule.ReadingSetType == ReadingSetType.ImageReading)
                {
                    needSignCount = trialClinicalDataSetList.Where(t => t.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCritrialId) && t.ClinicalDataLevel == ClinicalLevel.ImageRead && t.UploadRole == UploadRole.PM).Count();

                    // 不存在需要CRC上传的临床数据 或者 PM已确认
                    crcReadModuleSign =
                    !trialClinicalDataSetList.Any(x =>
                     x.UploadRole == UploadRole.CRC
                    && x.ClinicalDataLevel == ClinicalLevel.ImageRead
                    && x.ClinicalUploadType == ClinicalUploadType.Structuring
                    && x.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCritrialId)) || readModule.IsPMConfirm;

                }
                //肿瘤学
                else
                {
                    needSignCount = trialClinicalDataSetList.Where(t => t.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCritrialId) && t.ClinicalDataLevel == ClinicalLevel.OncologyRead && t.UploadRole == UploadRole.PM).Count();

                    // 不存在需要CRC上传的临床数据 或者 PM已确认
                    crcReadModuleSign =
                    !trialClinicalDataSetList.Any(x =>
                     x.UploadRole == UploadRole.CRC
                    && x.ClinicalDataLevel == ClinicalLevel.OncologyRead
                    && x.ClinicalUploadType == ClinicalUploadType.Structuring
                    && x.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCritrialId)) || readModule.IsPMConfirm;

                }

                //可能仅仅CRC 基线   没有PM
                if (needSignCount == haveSignedCount && crcReadModuleSign/*&& needSignCount != 0*/)
                {
                    //将该标准  该subject 该阅片期|肿瘤学 任务临床数据状态变更
                    await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCritrialId && t.SouceReadModuleId == readingId, u => new VisitTask()
                    {
                        IsClinicalDataSign = true
                    });


                }
                else
                {
                    await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCritrialId && t.SouceReadModuleId == readingId, u => new VisitTask()
                    {
                        IsClinicalDataSign = false
                    });
                }

            }

            //有序阅片才维护 IsFrontTaskNeedSignButNotSign 这个状态 
            if (_readingQuestionCriterionTrialRepository.Any(t => t.Id == trialReadingCritrialId && t.IsReadingTaskViewInOrder == ReadingOrder.InOrder))
            {


                Expression<Func<VisitTask, bool>> visitTaskLambda = x => x.TrialId == trialId && x.SubjectId == subjectId && x.TrialReadingCriterionId == trialReadingCritrialId;

                if (isVisit || (isVisit == false && readModule.ReadingSetType == ReadingSetType.ImageReading))
                {
                    //访视类型的任务 不影响肿瘤学任务的临床数据状态
                    visitTaskLambda = visitTaskLambda.And(x => x.ArmEnum != Arm.TumorArm);
                }
                else
                {
                    visitTaskLambda = visitTaskLambda.And(x => x.ArmEnum == Arm.TumorArm);
                }


                //维护  IsFrontTaskNeedSignButNotSign   在添加任务哪里用触发器也维护了
                var visitTaskIdQueryable = _visitTaskRepository.Where(visitTaskLambda) //该Subject  该标准的任务
                                                                                       //小于自己任务号的任务  存在需要签名  但是没签名
                          .Where(t => t.IsFrontTaskNeedSignButNotSign == false &&

                         (t.Subject.SubjectVisitTaskList.AsQueryable().Where(visitTaskLambda).Any(c => c.IsNeedClinicalDataSign == true && c.IsClinicalDataSign == false && c.VisitTaskNum < t.VisitTaskNum)

                         // 前序存在 未一致性核查未通过的
                         || t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum > sv.VisitNum)

                           ))
                          .Select(t => t.Id);

                await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => visitTaskIdQueryable.Contains(t.Id), u => new VisitTask()
                {
                    IsFrontTaskNeedSignButNotSign = true
                });



                var visitTaskIdQueryable2 = _visitTaskRepository.Where(visitTaskLambda) //该Subject  该标准的任务

                          .Where(t => t.IsFrontTaskNeedSignButNotSign == true &&

                          //前序任务  不存在需要签名  但是没签名
                          !t.Subject.SubjectVisitTaskList.AsQueryable().Where(visitTaskLambda).Any(c => c.IsNeedClinicalDataSign == true && c.IsClinicalDataSign == false && c.VisitTaskNum < t.VisitTaskNum)

                          // 前序  不存在 未一致性核查未通过的
                          && !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum > sv.VisitNum)
                          )
                          .Select(t => t.Id);

                await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => visitTaskIdQueryable2.Contains(t.Id), u => new VisitTask()
                {
                    IsFrontTaskNeedSignButNotSign = false
                });


            }



        }



        // 废弃 接口合并到签名哪里

        [HttpPut]
        public async Task<IResponseOutput> PMClinicalDataConfirm(PMClinicalDataConfirmCommand command)
        {
            await _readingClinicalDataRepository.UpdatePartialFromQueryAsync(t => t.Id == command.Id, u => new ReadingClinicalData()
            {
                IsBlind = command.IsBlind,
                IsComplete = command.IsComplete,
                ReadingClinicalDataState = ReadingClinicalDataStatus.HaveChecked
            });

            await _readingClinicalDataRepository.SaveChangesAsync();

            return ResponseOutput.Ok();


        }
        #endregion


        #region 临床数据相关查询

        /// <summary>
        /// 获取访视临床数据名称
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<GetVisitClinicalDataNameOutDto> GetVisitClinicalDataName(GetVisitClinicalDataNameInDto inDto)
        {
            var clinicalDataNames = await _readingClinicalDataRepository.Where(x => x.ReadingId == inDto.Id).Select(x =>
            _userInfo.IsEn_Us ? x.ClinicalDataTrialSet.ClinicalDataSetEnName : x.ClinicalDataTrialSet.ClinicalDataSetName).Distinct().ToListAsync();

            return new GetVisitClinicalDataNameOutDto()
            {
                ClinicalDataName = string.Join(_userInfo.IsEn_Us? ", ":",", clinicalDataNames),

            };
        }

        /// <summary>
        /// 获取下拉菜单
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<GetTrialClinicalDataSelectOutDto>> GetTrialClinicalDataSelect(GetTrialClinicalDataSelectIndto inDto)
        {
            var userTypes = new List<int>() {
             (int)UserTypeEnum.ProjectManager,
             (int)UserTypeEnum.SPM,
             (int)UserTypeEnum.CPM,
             (int)UserTypeEnum.IndependentReviewer,
             };



            if (userTypes.Contains(_userInfo.UserTypeEnumInt))
            {
                inDto.UploadRole = UploadRole.PM;
            }

            ReadModule? readModule = null;
            if (inDto.IsVisit == false)
            {
                readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadingId).FirstOrDefaultAsync();
            }

            Dictionary<ModuleTypeEnum, ClinicalLevel> keyValuePairs = new Dictionary<ModuleTypeEnum, ClinicalLevel>();
            keyValuePairs.Add(ModuleTypeEnum.Global, ClinicalLevel.ImageRead);
            keyValuePairs.Add(ModuleTypeEnum.Oncology, ClinicalLevel.OncologyRead);





            var usedIdsQuery = _readingClinicalDataRepository.Where(x => x.ReadingId == inDto.ReadingId && x.Id != inDto.ReadingClinicalDataId).Select(x => x.ClinicalDataTrialSetId);

            List<GetTrialClinicalDataSelectOutDto> clinicalList = await _clinicalDataTrialSetRepository.Where(x => x.TrialId == inDto.TrialId && x.IsConfirm)
                .WhereIf(inDto.UploadRole != null, x => x.UploadRole == inDto.UploadRole)
                .Where(x => !usedIdsQuery.Contains(x.Id))



                .WhereIf(inDto.IsVisit && inDto.IsBaseLine, x => x.ClinicalDataLevel == ClinicalLevel.Subject || x.ClinicalDataLevel == ClinicalLevel.SubjectVisit)
                .WhereIf(inDto.IsVisit && !inDto.IsBaseLine, x => x.ClinicalDataLevel == ClinicalLevel.SubjectVisit)
                .WhereIf(!inDto.IsVisit, x => x.ClinicalDataLevel == ClinicalLevel.ImageRead || x.ClinicalDataLevel == ClinicalLevel.OncologyRead)
                .WhereIf(readModule != null, x => x.ClinicalDataLevel == keyValuePairs[readModule!.ModuleType])
                .WhereIf(inDto.TrialReadingCriterionId != null, x => x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == inDto.TrialReadingCriterionId))
                //.WhereIf(criterion!=null,x=>x.CriterionEnumListStr.Contains($"|{(int)criterion.CriterionType}|"))
                .Select(x => new GetTrialClinicalDataSelectOutDto()
                {
                    ClinicalDataLevel = x.ClinicalDataLevel,
                    ClinicalDataSetName = x.ClinicalDataSetName.LanguageName(x.ClinicalDataSetEnName, _userInfo.IsEn_Us),
                    ClinicalDataSetEnName = x.ClinicalDataSetEnName,
                    ClinicalUploadType = x.ClinicalUploadType,
                    FileName = x.FileName,
                    Path = x.Path,
                    Id = x.Id,
                    CriterionEnumList = x.CriterionEnumList,
                }).ToListAsync();

            return clinicalList;
        }


        /// <summary>
        /// 获取访视 阅片或任务临床数据
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<(List<GetReadingClinicalDataListOutDto>, object)> GetReadingOrTaskClinicalDataList(GetReadingOrTaskClinicalDataListInDto inDto)
        {
            var readingNameOrTaskBlindName = string.Empty;
            var subjectCode = string.Empty;
            if (inDto.ReadingId == null)
            {
                var visitTask = await _visitTaskRepository.AsQueryable().Include(x => x.Subject)

                    .FirstOrDefaultAsync(x => x.Id == inDto.VisitTaskId);
                subjectCode = visitTask.BlindSubjectCode.IsNullOrEmpty() ? visitTask.Subject.Code : visitTask.BlindSubjectCode;
                readingNameOrTaskBlindName = visitTask.TaskBlindName;
            }
            inDto.SelectIsSign = false;
            var result = await GetClinicalDataList(inDto);
            if (readingNameOrTaskBlindName.IsNullOrEmpty())
            {
                readingNameOrTaskBlindName = await _subjectVisitRepository.Where(x => x.Id == inDto.ReadingId).Select(x => x.VisitName).FirstOrDefaultAsync();
                if (readingNameOrTaskBlindName.IsNullOrEmpty())
                {
                    readingNameOrTaskBlindName = await _readModuleRepository.Where(x => x.Id == inDto.ReadingId).Select(x => x.ModuleName).FirstOrDefaultAsync();

                }
            }

            Dictionary<ClinicalLevel, int> keys = new Dictionary<ClinicalLevel, int>() {
                {ClinicalLevel.SubjectVisit,0 },
                {ClinicalLevel.ImageRead,2 },
                {ClinicalLevel.OncologyRead,3 },
                {ClinicalLevel.Subject,4 },
                {ClinicalLevel.Study,5 },
            };

            result = result.OrderBy(x => keys[x.ClinicalDataLevel]).ToList();

            return (result, new
            {
                SubjectCode = subjectCode,
                ReadingNameOrTaskBlindName = readingNameOrTaskBlindName,
            });
        }


        /// <summary>
        /// 获取阅片临床数据列表
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<(List<GetReadingClinicalDataListOutDto>, object)> GetReadingClinicalDataList(GetReadingClinicalDataListIndto inDto)
        {
            var getTrialClinicalDataSelectIndto = new GetTrialClinicalDataSelectIndto()
            {
                ReadingId = inDto.ReadingId,
                TrialId = inDto.TrialId,
                IsBaseLine = inDto.IsBaseLine,
                SubjectId = inDto.SubjectId,
                IsVisit = inDto.IsVisit,
                TrialReadingCriterionId = inDto.TrialReadingCriterionId
            };

            var clinicalDataList = await this.GetTrialClinicalDataSelect(getTrialClinicalDataSelectIndto);

            var isBaseLine = await _subjectVisitRepository.AnyAsync(x => x.Id == inDto.ReadingId && x.IsBaseLine);


            var result = await this.GetClinicalDataList(new GetReadingOrTaskClinicalDataListInDto()
            {
                ClinicalDataTrialSetId = inDto.ClinicalDataTrialSetId,
                GetClinicalType = inDto.GetClinicalType,
                SubjectId = inDto.SubjectId,
                TrialId = inDto.TrialId,
                SelectIsSign = false,
                ReadingId = inDto.ReadingId,
                TrialReadingCriterionId = inDto.TrialReadingCriterionId,
            });
            var readingIds = result.Select(x => x.ReadingId).ToList();

            var previousHistoryList = await _previousHistoryRepository.Where(x => readingIds.Contains(x.SubjectVisitId)).ProjectTo<PreviousHistoryView>(_mapper.ConfigurationProvider).ToListAsync();
            var previousOtherList = await _previousOtherRepository.Where(x => readingIds.Contains(x.SubjectVisitId)).ProjectTo<PreviousOtherView>(_mapper.ConfigurationProvider).ToListAsync();
            var previousSurgeryList = await _previousSurgeryRepository.Where(x => readingIds.Contains(x.SubjectVisitId)).ProjectTo<PreviousSurgeryView>(_mapper.ConfigurationProvider).ToListAsync();
            foreach (var item in result)
            {
                item.ClinicalTableData = new ClinicalDataTable()
                {
                    PreviousHistoryList = previousHistoryList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(),
                    PreviousOtherList = previousOtherList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(),
                    PreviousSurgeryList = previousSurgeryList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(),
                };

            }

            return (result, new
            {
                IsCanAddClinicalData = clinicalDataList.Count > 0,
            });
        }

        [NonDynamicMethod]
        public async Task<List<GetReadingClinicalDataListOutDto>> GetClinicalDataList(GetReadingOrTaskClinicalDataListInDto inDto)
        {

            var resultQuery = _readingClinicalDataRepository.Where(x => 1 == 1).Select(x => new GetReadingClinicalDataListOutDto() { });
            bool isSelfAnalysis = false;
            var otherIsSelfAnalysisList = new List<GetReadingClinicalDataListOutDto>();
            if (inDto.ReadingId == null)
            {
                var visitTask = await _visitTaskRepository.FirstOrDefaultAsync(x => x.Id == inDto.VisitTaskId);
                inDto.ReadingId = visitTask.SouceReadModuleId ?? visitTask.SourceSubjectVisitId;
                inDto.TrialReadingCriterionId = visitTask.TrialReadingCriterionId;

                if (visitTask.IsAnalysisCreate && visitTask.IsSelfAnalysis == true)
                {
                    isSelfAnalysis = true;
                }
            }

            //下面改用readingIdList筛选 不然
            List<Guid> readingIdList = new List<Guid>() {};
            if (inDto.VisitTaskId!=null)
            {
                var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == inDto.ReadingId.Value).FirstOrDefaultAsync();
                if (subjectVisit != null && !subjectVisit.IsBaseLine)
                {
                    var baseId = await _subjectVisitRepository.Where(x => x.SubjectId == subjectVisit.SubjectId && x.IsBaseLine).Select(x => x.Id).FirstOrDefaultAsync();
                    readingIdList.Add(baseId);
                }

                var readModuleInfo = await _readModuleRepository.Where(x => x.Id == inDto.ReadingId.Value).FirstOrDefaultAsync();
                if (readModuleInfo != null && readModuleInfo.ReadingSetType == ReadingSetType.ImageReading)
                {
                    var baseId = await _subjectVisitRepository.Where(x => x.SubjectId == readModuleInfo.SubjectId && x.IsBaseLine).Select(x => x.Id).FirstOrDefaultAsync();
                    readingIdList.Add(baseId);
                }

            }

            //  一致性分析
            if (isSelfAnalysis)
            {
                // 一致性分析的
                resultQuery = _readingConsistentClinicalDataRepository.Where(x => x.SubjectId == inDto.SubjectId)
               .WhereIf(inDto.ReadingClinicalDataId != null, x => x.Id == inDto.ReadingClinicalDataId)
               .WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalDataTrialSetId == inDto.ClinicalDataTrialSetId)
               .WhereIf(inDto.SelectIsSign, x => x.IsSign == true)
               .Where(x => x.ReadingId == inDto.ReadingId||(readingIdList.Contains(x.ReadingId)&&x.ClinicalDataTrialSet.ClinicalDataLevel== ClinicalLevel.Subject))
               .WhereIf(inDto.TrialReadingCriterionId != null, x => x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == inDto.TrialReadingCriterionId))
               .Select(x => new GetReadingClinicalDataListOutDto()
               {
                   ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel,
                   SubjectId = x.SubjectId,
                   ReadingId = x.ReadingId,
                   ClinicalDataSetEnName = x.ClinicalDataTrialSet.ClinicalDataSetEnName,
                   ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us),
                   ClinicalDataTrialSetId = x.ClinicalDataTrialSetId,
                   IsSign = x.IsSign,
                   ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType,
                   CriterionEnumList = x.ClinicalDataTrialSet.CriterionEnumList,
                   TrialClinicalDataSetCriteriaList = x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList,
                   Id = x.Id,
                   // 这里现在都是PM上传的 前端会判断是否可以上传
                   UploadRole = UploadRole.PM,
                   IsCRCUpload = false,
                   IsBlind = x.IsBlind,
                   IsComplete = x.IsComplete,
                   FileCount = x.FileCount,
                   ReadingClinicalDataState = x.ReadingClinicalDataState,
                   FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto()
                   {
                       Id = y.Id,
                       FileName = y.FileName,
                       Path = y.Path,
                       Size = y.Size,
                       Type = y.Type,
                       CreateTime = y.CreateTime,
                   }).ToList(),
               });

                // 是否获取所有一致性分析的数据
                if (inDto.IsGetAllConsistencyAnalysis)
                {
                    // 原来的非PDF
                    otherIsSelfAnalysisList = await _readingClinicalDataRepository.Where(x => x.SubjectId == inDto.SubjectId)
                  .WhereIf(inDto.ReadingClinicalDataId != null, x => x.Id == inDto.ReadingClinicalDataId)
                      .WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalDataTrialSetId == inDto.ClinicalDataTrialSetId)
                  .WhereIf(inDto.SelectIsSign, x => x.IsSign == true)
                  .Where(x => x.ReadingId == inDto.ReadingId || (readingIdList.Contains(x.ReadingId) && x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject))
                  .WhereIf(inDto.TrialReadingCriterionId != null, x => x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == inDto.TrialReadingCriterionId))
                  .Where(x => x.ClinicalDataTrialSet.ClinicalUploadType != ClinicalUploadType.PDF || x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Study)
                  .Select(x => new GetReadingClinicalDataListOutDto()
                  {
                      ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel,
                      SubjectId = x.SubjectId,
                      ReadingId = x.ReadingId,
                      ClinicalDataSetEnName = x.ClinicalDataTrialSet.ClinicalDataSetEnName,
                      ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us),
                      ClinicalDataTrialSetId = x.ClinicalDataTrialSetId,
                      IsSign = x.IsSign,
                      ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType,
                      CriterionEnumList = x.ClinicalDataTrialSet.CriterionEnumList,
                      TrialClinicalDataSetCriteriaList = x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList,
                      Id = x.Id,
                      UploadRole = x.ClinicalDataTrialSet.UploadRole,
                      IsCRCUpload = x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC,
                      IsBlind = x.IsBlind,
                      IsComplete = x.IsComplete,
                      FileCount = x.FileCount,
                      ReadingClinicalDataState = x.ReadingClinicalDataState,
                      FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto()
                      {
                          Id = y.Id,
                          FileName = y.FileName,
                          Path = y.Path,
                          Size = y.Size,
                          Type = y.Type,
                          CreateTime = y.CreateTime,
                      }).ToList(),
                  }).ToListAsync();


                }

            }
            else
            {
                resultQuery = _readingClinicalDataRepository.Where(x => x.SubjectId == inDto.SubjectId)
             .WhereIf(inDto.ReadingClinicalDataId != null, x => x.Id == inDto.ReadingClinicalDataId)
                 .WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalDataTrialSetId == inDto.ClinicalDataTrialSetId)
             .WhereIf(inDto.SelectIsSign, x => x.IsSign == true)
             .Where(x => x.ReadingId == inDto.ReadingId || (readingIdList.Contains(x.ReadingId) && x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject))
             .WhereIf(inDto.TrialReadingCriterionId != null, x => x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == inDto.TrialReadingCriterionId))
             .Select(x => new GetReadingClinicalDataListOutDto()
             {
                 ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel,
                 SubjectId = x.SubjectId,
                 ReadingId = x.ReadingId,
                 ClinicalDataSetEnName = x.ClinicalDataTrialSet.ClinicalDataSetEnName,
                 ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us),
                 ClinicalDataTrialSetId = x.ClinicalDataTrialSetId,
                 IsSign = x.IsSign,
                 ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType,
                 CriterionEnumList = x.ClinicalDataTrialSet.CriterionEnumList,
                 TrialClinicalDataSetCriteriaList = x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList,
                 Id = x.Id,
                 UploadRole = x.ClinicalDataTrialSet.UploadRole,
                 IsCRCUpload = x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC,
                 IsBlind = x.IsBlind,
                 IsComplete = x.IsComplete,
                 FileCount = x.FileCount,
                 ReadingClinicalDataState = x.ReadingClinicalDataState,
                 FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto()
                 {
                     Id = y.Id,
                     FileName = y.FileName,
                     Path = y.Path,
                     Size = y.Size,
                     Type = y.Type,
                     CreateTime = y.CreateTime,
                 }).ToList(),

             });
            }




            var result = new List<GetReadingClinicalDataListOutDto>();
            if (!inDto.IsOnlyGetCRCReadModule)
            {
                result = await resultQuery.ToListAsync();
                result.AddRange(otherIsSelfAnalysisList);
            }

            var readingIds = result.Select(x => x.ReadingId).ToList();
            var clinical = await _clinicalFormRepository.Where(x => readingIds.Contains(x.ReadingId ?? default(Guid))).ToListAsync();
            result.Where(x => x.ClinicalUploadType == ClinicalUploadType.Structuring).ForEach(x =>
            {

                x.ClinicalFromList = clinical.Where(y => y.ReadingId == x.ReadingId && y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Select(y => new ClinicalFromData()
                {
                    CheckDate = y.CheckDate,
                    ClinicalFormId = y.Id
                }).ToList();
                x.FileCount = x.ClinicalFromList.Count;
            });


            // 这里处理CRC上传 阅片期的临床数据
            var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadingId)
                //.Where(x=>x.IsCRCConfirm)
                .WhereIf(inDto.SelectIsSign, x => x.IsPMConfirm)
                 .WhereIf(!inDto.SelectIsSign, x => x.IsCRCConfirm)
                .FirstOrDefaultAsync();
            if (readModule != null)
            {
                var moduleCriterionFromList = await _readModuleCriterionFromRepository
                    .WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalForm.ClinicalDataTrialSetId == inDto.ClinicalDataTrialSetId)
                    .Where(x => x.ReadModuleId == readModule.Id).Select(x => new
                    {
                        ClinicalFormId = x.ClinicalFormId,
                        CheckDate = x.ClinicalForm.CheckDate,
                        ClinicalDataTrialSetId = x.ClinicalForm.ClinicalDataTrialSetId


                    }).ToListAsync();


                var clinicalresult = await _clinicalDataTrialSetRepository.Where(x => x.UploadRole == UploadRole.CRC && x.ClinicalUploadType == ClinicalUploadType.Structuring)
                    .WhereIf(readModule.ReadingSetType == ReadingSetType.ImageReading, x => x.ClinicalDataLevel == ClinicalLevel.ImageRead)
                       .WhereIf(readModule.ReadingSetType == ReadingSetType.TumorReading, x => x.ClinicalDataLevel == ClinicalLevel.OncologyRead)
                       .Where(x => x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == readModule.TrialReadingCriterionId))
                  .Select(x => new GetReadingClinicalDataListOutDto()
                  {

                      ClinicalDataLevel = x.ClinicalDataLevel,
                      SubjectId = inDto.SubjectId,
                      ReadingId = default(Guid),
                      IsCRCApplicationRevoke = readModule.IsCRCApplicationRevoke,
                      IsCRCConfirm = readModule.IsCRCConfirm,
                      IsPMConfirm = readModule.IsPMConfirm,
                      ClinicalDataSetName = x.ClinicalDataSetName.LanguageName(x.ClinicalDataSetEnName, _userInfo.IsEn_Us),
                      ClinicalDataSetEnName = x.ClinicalDataSetEnName,
                      ClinicalDataTrialSetId = x.Id,
                      IsSign = readModule.IsPMConfirm,
                      ClinicalUploadType = x.ClinicalUploadType,
                      Id = default(Guid),
                      UploadRole = x.UploadRole,
                      IsCRCUpload = x.UploadRole == UploadRole.CRC,
                      IsNeedMerge = true,
                      ReadModuleId = readModule.Id,
                      TrialClinicalDataSetCriteriaList = x.TrialClinicalDataSetCriteriaList,
                      //FileCount = x.FileCount,

                      //ReadingClinicalDataState = x.ReadingClinicalDataState,

                      //FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto()
                      //{
                      //    Id = y.Id,
                      //    FileName = y.FileName,
                      //    Path = y.Path,
                      //    CreateTime = y.CreateTime,
                      //}).ToList()

                  }).ToListAsync();

                clinicalresult.ForEach(x =>
                {
                    x.FileCount = moduleCriterionFromList.Where(y => y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Count();
                    x.ClinicalFromList = moduleCriterionFromList.Where(y => y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).OrderBy(y => y.CheckDate).Select(x => new ClinicalFromData
                    {
                        CheckDate = x.CheckDate,
                        ClinicalFormId = x.ClinicalFormId

                    }).ToList();
                    x.IsSign = readModule.IsPMConfirm ? true : false;
                    x.ReadingClinicalDataState = readModule.IsPMConfirm ? ReadingClinicalDataStatus.HaveSigned : ReadingClinicalDataStatus.HaveChecked;

                });

                result.AddRange(clinicalresult);
            }



            // 根据标准
            if (inDto.VisitTaskId != null)
            {
                var visitTaskInfo = await _visitTaskRepository.FirstOrDefaultAsync(x => x.Id == inDto.VisitTaskId);

                result = result.Where(x => x.TrialClinicalDataSetCriteriaList.Any(z => z.TrialReadingCriterionId == visitTaskInfo.TrialReadingCriterionId)).ToList();
            }


            if (inDto.GetClinicalType != null)
            {
                switch (inDto.GetClinicalType)
                {
                    case GetClinicalType.PMUpload:
                        result = result.Where(x => x.UploadRole == UploadRole.PM).ToList();
                        break;
                    case GetClinicalType.CRCConfirm:
                        result = result.Where(x => x.UploadRole == UploadRole.CRC && x.IsCRCConfirm && !x.IsPMConfirm).ToList();
                        break;
                    case GetClinicalType.HasSign:
                        result = result.Where(x => x.IsSign).ToList();
                        break;
                }
            }

            var previousHistoryList = await _previousHistoryRepository.Where(x => x.SubjectVisitId == inDto.ReadingId || (readingIdList.Contains(x.SubjectVisitId) && x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject)).ProjectTo<PreviousHistoryView>(_mapper.ConfigurationProvider).ToListAsync();
            var previousOtherList = await _previousOtherRepository.Where(x => x.SubjectVisitId == inDto.ReadingId || (readingIdList.Contains(x.SubjectVisitId) && x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject)).ProjectTo<PreviousOtherView>(_mapper.ConfigurationProvider).ToListAsync();
            var previousSurgeryList = await _previousSurgeryRepository.Where(x => x.SubjectVisitId == inDto.ReadingId || (readingIdList.Contains(x.SubjectVisitId) && x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject)).ProjectTo<PreviousSurgeryView>(_mapper.ConfigurationProvider).ToListAsync();

            foreach (var item in result)
            {
                item.ClinicalTableData = new ClinicalDataTable()
                {
                    PreviousHistoryList = previousHistoryList.Where(x => x.SubjectVisitId == item.ReadingId).ToList(),
                    PreviousOtherList = previousOtherList.Where(x => x.SubjectVisitId == item.ReadingId).ToList(),
                    PreviousSurgeryList = previousSurgeryList.Where(x => x.SubjectVisitId == item.ReadingId).ToList(),
                };

            }

            return result;
        }

        #endregion


        #region 一致性分析临床数据
        /// <summary>
        /// 获取阅片临床数据列表 (在任务列表)
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<(List<GetReadingClinicalDataListOutDto>, object)> GetConsistencyAnalysisReadingClinicalDataList(GetConsistencyAnalysisReadingClinicalDataListInDto inDto)
        {
            var result = await this.GetClinicalDataList(new GetReadingOrTaskClinicalDataListInDto()
            {
                SubjectId = inDto.SubjectId,
                TrialId = inDto.TrialId,
                SelectIsSign = false,
                IsGetAllConsistencyAnalysis = false,
                VisitTaskId = inDto.VisitTaskId,
            });

            return (result, true);
        }



        /// <summary>
        /// 新增或修改一致性分析临床数据
        /// </summary>
        /// <param name="indto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> AddOrUpdateConsistencyAnalysisReadingClinicalData(AddOrUpdateReadingClinicalDataDto indto)
        {
            var existsQuery = _readingConsistentClinicalDataRepository
                .WhereIf(indto.Id != null, x => x.Id != indto.Id)
                .Where(x => x.ClinicalDataTrialSetId == indto.ClinicalDataTrialSetId && x.ReadingId == indto.ReadingId && x.StudyId == indto.StudyId);

            if (await existsQuery.AnyAsync())
            {
                //---存在同类型的临床数据,操作失败
                return ResponseOutput.NotOk(_localizer["ReadingClinicalData_DupTypeFail"]);
            }
            var clinicalDataTrialSet = (await _clinicalDataTrialSetRepository.Where(x => x.Id == indto.ClinicalDataTrialSetId).FirstOrDefaultAsync()).IfNullThrowException();

            //subject  或者访视级别的  都是在访视传
            indto.IsVisit = clinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject || clinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit;

            if (indto.Id == null)
            {
                var entity = _mapper.Map<ReadingConsistentClinicalData>(indto);
                entity.ReadingClinicalDataPDFList = indto.AddFileList.Select(x => new ReadingConsistentClinicalDataPDF()
                {
                    FileName = x.FileName,
                    Path = x.Path,
                    Size = x.Size,
                    Type = x.Type,
                }).ToList();

                entity.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded;
                entity.IsBlind = false;
                entity.IsComplete = true;
                entity.FileCount = entity.ReadingClinicalDataPDFList.Count;
                await _readingConsistentClinicalDataRepository.AddAsync(entity, true);
                var success = await _readingConsistentClinicalDataRepository.SaveChangesAsync();
                return ResponseOutput.Ok(entity.Id);
            }
            else
            {
                var entity = (await _readingConsistentClinicalDataRepository.Where(t => t.Id == indto.Id, true).FirstOrDefaultAsync()).IfNullThrowException();
                await _readingConsistentClinicalDataPDFRepository.BatchDeleteNoTrackingAsync(x => indto.DeleteFileIds.Contains(x.Id));

                var addFileList = indto.AddFileList.Select(x => new ReadingConsistentClinicalDataPDF()
                {

                    FileName = x.FileName,
                    Path = x.Path,
                    Size = x.Size,
                    Type = x.Type,
                    ReadingConsistentClinicalDataId = entity.Id,
                }).ToList();



                _mapper.Map(indto, entity);

                //上传  或者删除了文件 核查状态需要重新确认

                if (indto.AddFileList.Count > 0 || indto.AddFileList.Count > 0)
                {
                    entity.IsComplete = true;
                    entity.IsBlind = false;
                }

                await _readingConsistentClinicalDataPDFRepository.AddRangeAsync(addFileList);

                await _readingConsistentClinicalDataPDFRepository.SaveChangesAsync();

                var fileCount = await _readingConsistentClinicalDataPDFRepository.Where(t => t.ReadingConsistentClinicalDataId == indto.Id).CountAsync();
                entity.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded;
                entity.IsSign = false;
                entity.FileCount = fileCount;
                entity.CreateTime = DateTime.Now;
                var success = await _readingConsistentClinicalDataRepository.SaveChangesAsync();
                return ResponseOutput.Ok(entity.Id);

            }

        }


        /// <summary>
        /// 一致性分析临床数据签名
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> SignConsistencyAnalysisReadingClinicalData(SignConsistencyAnalysisReadingClinicalDataInDto inDto)
        {
            var pdfCount = await _readingConsistentClinicalDataPDFRepository.Where(x => x.ReadingConsistentClinicalDataId == inDto.ConsistentClinicalDataId).CountAsync();
            if (pdfCount == 0)
            {
                return ResponseOutput.NotOk(_localizer["ReadingClinicalData_NoHavePDF"]);
            }
            await _readingConsistentClinicalDataRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.ConsistentClinicalDataId, x => new ReadingConsistentClinicalData()
            {
                IsSign = true,
                IsBlind = inDto.IsBlind,
                IsComplete = inDto.IsComplete,
                ReadingClinicalDataState = ReadingClinicalDataStatus.HaveSigned,
            });
            await _readingClinicalDataPDFRepository.SaveChangesAsync();
            return ResponseOutput.Ok(pdfCount);
        }

        /// <summary>
        /// 一致性分析临床数据签名完设置任务为有效
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> SetTaskValid(SetTaskValidInDto inDto)
        {
            var visittask = await _visitTaskRepository.AsQueryable().Include(x => x.TrialReadingCriterion).Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
            var readingId = visittask.SouceReadModuleId == null ? visittask.SourceSubjectVisitId : visittask.SouceReadModuleId;

            if (await _readingConsistentClinicalDataRepository.AnyAsync(x => x.ReadingId == readingId

            && x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == visittask.TrialReadingCriterionId) && x.IsSign == false))
            {
                return ResponseOutput.NotOk(_localizer["ReadingClinicalData_HaveUnsignedClinicalData"]);
            }
            if (visittask.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
            {
                if (await _visitTaskRepository.Where(x => x.SubjectId == visittask.SubjectId
                && x.TrialReadingCriterionId == visittask.TrialReadingCriterionId
                && x.VisitTaskNum < visittask.VisitTaskNum && x.IsAnalysisCreate == visittask.IsAnalysisCreate
                && x.IsSelfAnalysis == visittask.IsSelfAnalysis && x.ArmEnum == visittask.ArmEnum && x.TaskState == TaskState.NotEffect).AnyAsync()
                )
                {
                    return ResponseOutput.NotOk(_localizer["ReadingClinicalData_NeedSetBeforeTaskEffect"]);
                }
            }

            await _visitTaskRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.VisitTaskId, x => new VisitTask()
            {

                TaskState = TaskState.Effect
            });
            await _visitTaskRepository.SaveChangesAsync();
            return ResponseOutput.Ok();

        }
        #endregion

        #region 阅片临床数据PDF

        /// <summary>
        /// 获取单个阅片临床数据的所有文件
        /// </summary>
        /// <param name="inQuery"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageOutput<GetReadingClinicalDataPDFListOutDto>> GetReadingClinicalDataPDFList(GetReadingClinicalDataPDFListIndto inQuery)
        {

            var result = await _readingClinicalDataPDFRepository.Where(x => x.ReadingClinicalDataId == inQuery.ReadingClinicalDataId).ProjectTo<GetReadingClinicalDataPDFListOutDto>(_mapper.ConfigurationProvider)
                .ToPagedListAsync(inQuery, nameof(GetReadingClinicalDataPDFListOutDto.FileName));
            return result;
        }

        /// <summary>
        /// 删除PDF单个文件
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete("{id:guid}")]
        public async Task<IResponseOutput> DeleteReadingClinicalDataPDF(Guid id)
        {
            var pdf = await _readingClinicalDataPDFRepository.FirstOrDefaultAsync(t => t.Id == id);

            await _readingClinicalDataPDFRepository.DeleteAsync(pdf, true);

            var fileCount = await _readingClinicalDataPDFRepository.Where(t => t.ReadingClinicalDataId == pdf.ReadingClinicalDataId).CountAsync();

            await _readingClinicalDataRepository.UpdatePartialFromQueryAsync(pdf.ReadingClinicalDataId, c => new ReadingClinicalData() { FileCount = fileCount }, true);

            return ResponseOutput.Result(true);
        }

        #endregion


        ///// <summary>
        ///// 设置临床数据是否盲化
        ///// </summary>
        ///// <returns></returns>
        //[HttpPost]
        //public async Task<IResponseOutput> SetReadingClinicalDataIsBlind(SetReadingClinicalDataIsBlind inDto)
        //{
        //    await _readingClinicalDataRepository.UpdatePartialFromQueryAsync(inDto.Id, x=>new ReadingClinicalData() { 
        //         IsBlind=inDto.IsBlind,
        //    });
        //    return ResponseOutput.Ok(await _readingClinicalDataRepository.SaveChangesAsync());
        //}

    }
}