using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.Filter;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Service.WorkLoad.DTO;
using Microsoft.AspNetCore.Authorization;
using IRaCIS.Core.Application.Auth;
using IRaCIS.Core.Application.Service.Reading.Dto;
using MassTransit;
using IRaCIS.Core.Application.Service.Reading;
using IRaCIS.Core.Infra.EFCore.Common;
using Panda.DynamicWebApi.Attributes;
using AutoMapper;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Infrastructure;
using Newtonsoft.Json;
using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Application.ViewModel;

namespace IRaCIS.Application.Services
{
    /// <summary>
    /// IR影像阅片
    /// </summary>
    [ApiExplorerSettings(GroupName = "Reading")]
    public class ReadingImageTaskService : BaseService, IReadingImageTaskService
    {
      
        private readonly IRepository<NoneDicomStudy> _noneDicomStudyRepository;
        private readonly IRepository<VisitTask> _visitTaskRepository;
        private readonly IRepository<Trial> _trialRepository;
        private readonly IVisitTaskHelpeService _visitTaskHelpeService;
        private readonly IRepository<SubjectVisit> _subjectVisitRepository;
        private readonly IRepository<Subject> _subjectRepository;
        private readonly IRepository<ReadingJudgeInfo> _readingJudgeInfoRepository;
        private readonly IRepository<ReadModule> _readModuleRepository;
        private readonly IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository;
        private readonly IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository;
        private readonly IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository;


        public ReadingImageTaskService(
                  IMapper mapper,
                  IRepository<NoneDicomStudy> noneDicomStudyRepository,
                  IRepository<VisitTask> visitTaskRepository,
                  IRepository<Trial> TrialRepository,
                  IVisitTaskHelpeService visitTaskHelpeService,
                  IRepository<SubjectVisit> subjectVisitRepository,
                  IRepository<Subject> subjectRepository,
                  IRepository<ReadingJudgeInfo> readingJudgeInfoRepository,
                  IRepository<ReadModule> readModuleRepository,
                  IRepository<ReadingTaskQuestionAnswer> readingTaskQuestionAnswerRepository,
                  IRepository<ReadingQuestionCriterionTrial> readingQuestionCriterionTrialRepository,
                  IRepository<ReadingQuestionTrial> readingQuestionTrialRepository
          )
        {
            base._mapper = mapper;
            this._noneDicomStudyRepository = noneDicomStudyRepository;
            this._visitTaskRepository = visitTaskRepository;
            this._trialRepository = TrialRepository;
            this._visitTaskHelpeService = visitTaskHelpeService;
            this._subjectVisitRepository = subjectVisitRepository;
            this._subjectRepository = subjectRepository;
            this._readingJudgeInfoRepository = readingJudgeInfoRepository;
            this._readModuleRepository = readModuleRepository;
            this._readingTaskQuestionAnswerRepository = readingTaskQuestionAnswerRepository;
            this._readingQuestionCriterionTrialRepository = readingQuestionCriterionTrialRepository;
            this._readingQuestionTrialRepository = readingQuestionTrialRepository;
        }

        /// <summary>
        /// 获取下一个阅片任务
        /// </summary>
        /// <param name="subjectId"></param>
        /// <param name="trialId"></param>
        /// <returns></returns>
        private async Task<GetReadingTaskDto> GetNextTask(Guid? subjectId,Guid trialId,Guid? visistTaskId)
        {
            GetReadingTaskDto? task = new GetReadingTaskDto();

            if (visistTaskId != null)
            {
                task = await _visitTaskRepository.Where(x => x.Id==visistTaskId).Select(x => new GetReadingTaskDto()
                {
                    VisitTaskId = x.Id,
                    TaskBlindName = x.TaskBlindName,
                    SubjectId=x.SubjectId,
                    ReadingCategory = x.ReadingCategory,
                    VisistId = x.SourceSubjectVisitId != null ? x.SourceSubjectVisitId.Value : x.ReadModule.SubjectVisitId,
                    VisitNum = x.SourceSubjectVisitId != null ? x.SubjectVisit.VisitNum : x.ReadModule.VisitNum,

                }).FirstOrDefaultAsync();
              
            }
            else if (subjectId != null)
            {
                var subjectList =await  _subjectRepository.Where(t => t.TrialId == trialId)
                 .Where(t => t.SubjectDoctorList.Any(t => t.DoctorUserId == _userInfo.Id))
                 .Select(s => new SubjectTask()
                 {
                     SubjectId = s.Id,
                     UnReadTaskCount = s.SubjectVisitTaskList.Count(t => t.ReadingTaskState != ReadingTaskState.HaveSigned && t.DoctorUserId == _userInfo.Id),
                 }).ToListAsync();
                subjectList = subjectList.Select((x, index) => new SubjectTask()
                {
                    Index = index,
                    SubjectId = x.SubjectId,
                    UnReadTaskCount = x.UnReadTaskCount,
                }).ToList();


               var subjectIndex = subjectList.Where(x => x.SubjectId == subjectId).Select(x=>x.Index).FirstOrDefault();
                var newSubjectId = subjectList.Where(x => x.Index >= subjectIndex && x.UnReadTaskCount != 0).Select(x=>x.SubjectId).FirstOrDefault();

                var taskquery = _visitTaskRepository.Where(x => x.TrialId == trialId && x.ReadingTaskState != ReadingTaskState.HaveSigned && x.SubjectId == newSubjectId && x.DoctorUserId == _userInfo.Id).Select(x => new GetReadingTaskDto()
                {
                    VisitTaskId = x.Id,
                    TaskBlindName=x.TaskBlindName,
                    ReadingCategory = x.ReadingCategory,
                    VisistId = x.SourceSubjectVisitId != null ? x.SourceSubjectVisitId.Value : x.ReadModule.SubjectVisitId,
                    VisitNum = x.SourceSubjectVisitId != null ? x.SubjectVisit.VisitNum : x.ReadModule.VisitNum,
                }).OrderBy(x => x.VisitNum).ThenBy(x => x.ReadingCategory);

                task =await taskquery.FirstOrDefaultAsync();
                if (task == null)
                {
                    throw new BusinessValidationFailedException("任务都已经完成");
                }
                task.SubjectId = subjectId.Value;


            }
            else
            {
                task = await _visitTaskRepository.Where(x => x.TrialId == trialId && x.ReadingTaskState != ReadingTaskState.HaveSigned && x.DoctorUserId == _userInfo.Id).Select(x => new GetReadingTaskDto()
                {
                    VisitTaskId = x.Id,
                    TaskBlindName = x.TaskBlindName,
                    ReadingCategory = x.ReadingCategory,
                    VisistId = x.SourceSubjectVisitId != null ? x.SourceSubjectVisitId.Value : x.ReadModule.SubjectVisitId,
                    VisitNum = x.SourceSubjectVisitId != null ? x.SubjectVisit.VisitNum : x.ReadModule.VisitNum,
                    SubjectId=x.SubjectId,
                    SubjectCode=x.Subject.Code,
                }).FirstOrDefaultAsync();
                if (task == null)
                {
                    throw new BusinessValidationFailedException("任务都已经完成");
                }
            }
            return task;



        

          
        }

        /// <summary>
        /// 获取阅片非Dicom文件
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<(List<NoneDicomStudyView>,object)> GetReadingImageFile(GetReadingImgInDto inDto)
        {
            var task=await GetNextTask(inDto.SubjectId, inDto.TrialId,inDto.VisistTaskId);
            List<Guid> visitIds = new List<Guid>();
            if (task.ReadingCategory == ReadingCategory.Visit)
            {
                visitIds.Add(task.VisistId);
            }
            else
            {
                // 阅片期取前面所有的图像
                visitIds.AddRange(await _subjectVisitRepository.Where(x => x.VisitNum <= task.VisitNum && x.SubjectId == task.SubjectId).Select(x => x.Id).ToListAsync());
            }
            List<NoneDicomStudyView> result=await _noneDicomStudyRepository.Where(t => visitIds.Contains(t.SubjectVisitId))
                .ProjectTo<NoneDicomStudyView>(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken }).ToListAsync();

            var trialInfo = await _trialRepository.Where(x => x.Id == inDto.TrialId).Select(x => new
            {
                x.IsReadingShowPreviousResults,
                x.IsReadingShowSubjectInfo,
            }).FirstOrDefaultAsync();
            return (result, new  { 
            VisitTaskId= task.VisitTaskId,
            SubjectId=task.SubjectId,
            SubjectCode=task.SubjectCode,
            ReadingCategory= task.ReadingCategory,
            TaskBlindName=task.TaskBlindName,
            IsReadingShowPreviousResults = trialInfo.IsReadingShowPreviousResults,
            IsReadingShowSubjectInfo=trialInfo.IsReadingShowSubjectInfo,
            });
        }

        /// <summary>
        /// 获取项目已确认的标准
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<GetTrialConfirmCriterionListOutDto>> GetTrialConfirmCriterionList(GetConfirmCriterionInDto inDto)
        {
            var result= await _readingQuestionCriterionTrialRepository.Where(x => x.TrialId == inDto.TrialId&&x.IsConfirm&&x.IsCompleteConfig)
               .Select(x => new GetTrialConfirmCriterionListOutDto()
               {
                   ReadingQuestionCriterionTrialId = x.Id,
                   ReadingQuestionCriterionTrialName = x.CriterionName
               }).ToListAsync();
            return result;
        }

        /// <summary>
        /// 获取项目标准的裁判问题
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<GetTrialCriterionJudgeQuestionListOutDto>> GetTrialCriterionJudgeQuestionList(GetTrialCriterionJudgeQuestionListInDto inDto)
        {
            var result = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == inDto.ReadingQuestionCriterionTrialId && x.IsJudgeQuestion)
                .Select(x => new GetTrialCriterionJudgeQuestionListOutDto()
                {
                    AnswerGroup = JsonConvert.DeserializeObject<List<string>>(x.AnswerGroup.IsNullOrEmpty()?"[]": x.AnswerGroup),
                    AnswerCombination = JsonConvert.DeserializeObject<List<AnswerCombinationDto>>(x.AnswerCombination.IsNullOrEmpty() ? "[]" : x.AnswerCombination),
                    QuestionName = x.QuestionName,
                    TypeValue =x.TypeValue,
                    JudgeType=x.JudgeType,
                    ReadingQuestionTrialId = x.Id
                }).ToListAsync();
            return result;
        }

        /// <summary>
        /// 设置裁判问题的答案分组
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> SetTrialCriterionJudgeQuestionAnswerGroup(SetTrialCriterionJudgeQuestionAnswerGroupInDto inDto)
        {
            await _readingQuestionTrialRepository.UpdatePartialFromQueryAsync(inDto.ReadingQuestionTrialId, x => new ReadingQuestionTrial()
            {
                AnswerGroup = JsonConvert.SerializeObject(inDto.AnswerGroup),
                AnswerCombination = JsonConvert.SerializeObject(inDto.AnswerCombination),
                JudgeType= inDto.JudgeType,
            }) ;

            var result = await _readingQuestionTrialRepository.SaveChangesAsync();

            return ResponseOutput.Ok(result);
        }

        /// <summary>
        /// 获取项目的阅片问题
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<(List<GetTrialReadingQuestionOutDto>, object)> GetTrialReadingQuestion(GetTrialReadingQuestionInDto inDto)
        {

         var readingTaskState = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.ReadingTaskState).FirstOrDefaultAsync();
         var query=  from data in _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId==inDto.ReadingQuestionCriterionTrialId)
                     join questionAnswer in _readingTaskQuestionAnswerRepository.Where(x=>x.VisitTaskId==inDto.VisitTaskId) on data.Id equals questionAnswer.ReadingQuestionTrialId into questionAnswerTemp
                     from leftquestionAnswer in questionAnswerTemp.DefaultIfEmpty()
                     select new GetTrialReadingQuestionOutDto()
                     {
                        ReadingQuestionTrialId=data.Id,
                       ReadingQuestionCriterionTrialId=data.ReadingQuestionCriterionTrialId,
                       TrialId=data.TrialId,
                       Type=data.Type,
                       ParentTriggerValue=data.ParentTriggerValue,
                       GroupName=data.GroupName,
                       QuestionName=data.QuestionName,
                       IsRequired=data.IsRequired,
                       ShowOrder=data.ShowOrder,
                       ParentId=data.ParentId,
                       TypeValue=data.TypeValue,
                       Answer= leftquestionAnswer.Answer
                     };

            var qusetionList =await query.OrderBy(x=>x.ShowOrder).ToListAsync();
            List<GetTrialReadingQuestionOutDto> groupList = qusetionList.Where(x => x.ParentId == null).ToList();
            groupList.ForEach(x =>
            {
                this.FindChildQuestion(x, qusetionList);
            });
            return (groupList, new
            {
                readingTaskState = readingTaskState
            });
        }

        /// <summary>
        /// 获取阅片任务和答案
        /// </summary>
        /// <returns></returns>
        private async Task<List<GetTrialReadingQuestionOutDto>> GetTaskAndAnswer(Guid visitTaskId)
        {
            var taskQuery=from questionAnswer in _readingTaskQuestionAnswerRepository.Where(x=>x.VisitTaskId== visitTaskId)
                          join trialQuestion in _readingQuestionTrialRepository.AsQueryable() on questionAnswer.ReadingQuestionTrialId equals trialQuestion.Id 
                          select new GetTrialReadingQuestionOutDto()
                          {
                              ReadingQuestionTrialId = trialQuestion.Id,
                              ReadingQuestionCriterionTrialId = trialQuestion.ReadingQuestionCriterionTrialId,
                              TrialId = trialQuestion.TrialId,
                              Type = trialQuestion.Type,
                              ParentTriggerValue = trialQuestion.ParentTriggerValue,
                              GroupName = trialQuestion.GroupName,
                              QuestionName = trialQuestion.QuestionName,
                              IsRequired = trialQuestion.IsRequired,
                              ShowOrder = trialQuestion.ShowOrder,
                              ParentId = trialQuestion.ParentId,
                              TypeValue = trialQuestion.TypeValue,
                              Answer = questionAnswer.Answer
                          };
            var qusetionList = await taskQuery.OrderBy(x => x.ShowOrder).ToListAsync();
            List<GetTrialReadingQuestionOutDto> groupList = qusetionList.Where(x => x.ParentId == null).ToList();
            groupList.ForEach(x =>
            {
                this.FindChildQuestion(x, qusetionList);
            });

            return groupList;
        }

        /// <summary>
        /// 获取裁判阅片任务信息
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<GetJudgeReadingInfoOutDto> GetJudgeReadingInfo(GetJudgeReadingInfo inDto)
        {
            var visitTask = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => new
            {
                x.ReadingTaskState,
                x.JudgeResultTaskId,
                x.JudgeResultRemark,
            }).FirstOrDefaultAsync();
            GetJudgeReadingInfoOutDto judgeInfo = new GetJudgeReadingInfoOutDto()
            {
                ReadingTaskState = visitTask.ReadingTaskState,
                JudgeResultTaskId = visitTask.JudgeResultTaskId,
                JudgeResultRemark=visitTask.JudgeResultRemark,
                VisitTaskInfoList = new List<JudgeReadingInfoDto>()
            };
            var visitIds = await _visitTaskRepository.Where(x => x.JudgeVisitTaskId == inDto.VisitTaskId).Select(x => new 
            { 
              x.Id,
              x.ArmEnum,
            }).ToListAsync();
            foreach (var item in visitIds)
            {
                var taskReadingQuestionList = await this.GetTaskAndAnswer(item.Id);
                judgeInfo.VisitTaskInfoList.Add(
                    new JudgeReadingInfoDto()
                    {
                        VisitTaskId = item.Id,
                        ArmEnum = item.ArmEnum,
                        TaskReadingQuestionList = taskReadingQuestionList,
                    });
            }
            return judgeInfo;
        }

        /// <summary>
        /// 保存裁判问题
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> SaveJudgeVisitTaskResult(SaveJudgeVisitTaskResult inDto)
        {
            await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask()
            {
                JudgeResultTaskId = inDto.JudgeResultTaskId,
                JudgeResultRemark = inDto.JudgeResultRemark,
            });
            var result=await _visitTaskRepository.SaveChangesAsync();
            return ResponseOutput.Ok(result);
        }

        /// <summary>
        /// 提交裁判问题
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [NonDynamicMethod]
        public async Task<IResponseOutput> SubmitJudgeVisitTaskResult(SaveJudgeVisitTaskResult inDto)
        {
            await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask()
            {
                JudgeResultTaskId = inDto.JudgeResultTaskId,
                ReadingTaskState = ReadingTaskState.HaveSigned,
                JudgeResultRemark = inDto.JudgeResultRemark,
                SignTime = DateTime.Now,
            });
            var result = await _visitTaskRepository.SaveChangesAsync();
            return ResponseOutput.Ok(result);
        }

        /// <summary>
        /// 获取既往结果
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<GetReadingPastResultListOutDto>> GetReadingPastResultList(GetReadingPastResultListInDto inDto)
        {
            var readingPastResultList =await _visitTaskRepository.Where(x => x.TrialId == inDto.TrialId&&x.SubjectId==inDto.SubjectId && x.DoctorUserId == _userInfo.Id
            &&x.Id!=inDto.VisitTaskId&&x.ReadingTaskState== ReadingTaskState.HaveSigned).ProjectTo<GetReadingPastResultListOutDto>(_mapper.ConfigurationProvider).ToListAsync();
                return readingPastResultList;
        }

        /// <summary>
        /// 找子问题
        /// </summary>
        /// <param name="trialReadingQuestion"></param>
        /// <param name="questionlists"></param>
        [NonDynamicMethod]
        public void FindChildQuestion(GetTrialReadingQuestionOutDto trialReadingQuestion, List<GetTrialReadingQuestionOutDto> questionlists)
        {
            trialReadingQuestion.Childrens = questionlists.Where(x => x.ParentId == trialReadingQuestion.ReadingQuestionTrialId).ToList();
            if (trialReadingQuestion.Childrens != null && trialReadingQuestion.Childrens.Count != 0)
            {
                trialReadingQuestion.Childrens.ForEach(x =>
                {
                    this.FindChildQuestion(x, questionlists);
                });
            }
        }

        /// <summary>
        /// 保存任务问题
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> SaveVisitTaskQuestions(SubmitVisitTaskQuestionsInDto inDto)
        {
            var subjectId = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.SubjectId).FirstOrDefaultAsync();
            await _readingTaskQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.ReadingQuestionCriterionTrialId == inDto.ReadingQuestionCriterionTrialId);
            List<ReadingTaskQuestionAnswer> readingTaskAnswerList = inDto.AnswerList.Select(x => new ReadingTaskQuestionAnswer()
            {
                Id = NewId.NextGuid(),
                SubjectId = subjectId,
                Answer = x.Answer,
                ReadingQuestionCriterionTrialId = inDto.ReadingQuestionCriterionTrialId,
                ReadingQuestionTrialId = x.ReadingQuestionTrialId,
                VisitTaskId = inDto.VisitTaskId,
                TrialId = inDto.TrialId
            }).ToList();
            await _readingTaskQuestionAnswerRepository.AddRangeAsync(readingTaskAnswerList);
            var result = await _visitTaskRepository.SaveChangesAsync();
            return ResponseOutput.Ok(result);
        }



        /// <summary>
        /// 提交问题
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [NonDynamicMethod]
        public async Task<IResponseOutput> SubmitVisitTaskQuestions(SubmitVisitTaskQuestionsInDto inDto)
        {
            await this.SaveVisitTaskQuestions(inDto);
            await _visitTaskRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.VisitTaskId, x => new VisitTask()
            {
                ReadingTaskState = ReadingTaskState.HaveSigned,
                SignTime=DateTime.Now,
            });
            var result = await _visitTaskRepository.SaveChangesAsync();
            // 触裁判任务
            await this.TriggerJudgeQuestion(inDto.VisitTaskId);
            // 添加阅片期任务
            await this.AddReadingTask(inDto.VisitTaskId);
            // 完成阅片修改状态
            await this.FinishReadUpdateState(inDto.VisitTaskId);
            return ResponseOutput.Ok(result);
        }

        /// <summary>
        /// 完成阅片修改状态
        /// </summary>
        /// <returns></returns>
        private async Task FinishReadUpdateState(Guid visitTaskId)
        {
            var taskInfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstOrDefaultAsync();
            if (!await _visitTaskRepository.AnyAsync(x => x.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && x.SouceReadModuleId == taskInfo.SouceReadModuleId && x.ReadingTaskState != ReadingTaskState.HaveSigned))
            {
                if (taskInfo.SouceReadModuleId != null)
                {
                    await _readModuleRepository.UpdatePartialFromQueryAsync(taskInfo.SouceReadModuleId.Value, x => new ReadModule
                    {
                        ReadingStatus = ReadingStatusEnum.ReadCompleted
                    });
                }
                else if (taskInfo.SourceSubjectVisitId != null)
                {
                    await _subjectVisitRepository.UpdatePartialFromQueryAsync(taskInfo.SourceSubjectVisitId.Value, x => new SubjectVisit
                    {
                        ReadingStatus = ReadingStatusEnum.ReadCompleted
                    });
                }
                await _subjectVisitRepository.SaveChangesAsync();
            }
         }

        /// <summary>
        /// 添加阅片期任务
        /// </summary>
        /// <returns></returns>
        private async Task AddReadingTask(Guid visitTaskId)
        {
            // ****** 先生成阅片期  阅片期任务阅片完成之后生成肿瘤学的  如果没有阅片期 直接生成肿瘤学 *********////
            #region 建立关系
            Dictionary<ModuleTypeEnum, ReadingCategory> typeChangeDic = new Dictionary<ModuleTypeEnum, ReadingCategory>();
            typeChangeDic.Add(ModuleTypeEnum.InPlanSubjectVisit, ReadingCategory.Visit);
            typeChangeDic.Add(ModuleTypeEnum.OutPlanSubjectVisit, ReadingCategory.Visit);
            //typeChange.Add(ModuleTypeEnum.Read, ReadingCategory.ReadingPeriod);
            typeChangeDic.Add(ModuleTypeEnum.Global, ReadingCategory.Global);
            typeChangeDic.Add(ModuleTypeEnum.Referee, ReadingCategory.Judge);
            typeChangeDic.Add(ModuleTypeEnum.Oncology, ReadingCategory.Oncology);
            #endregion
            var taskInfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstOrDefaultAsync();
            List<ReadingGenerataTaskDTO> needReadList = new List<ReadingGenerataTaskDTO>();
            if (!await _visitTaskRepository.AnyAsync(x => x.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId&&x.SouceReadModuleId== taskInfo.SouceReadModuleId && x.ReadingTaskState != ReadingTaskState.HaveSigned))
            {
                // 任务类型
                switch (taskInfo.ReadingCategory)
                {
                    case ReadingCategory.Visit:
                            needReadList = await _readModuleRepository.Where(x => x.SubjectVisitId == taskInfo.SourceSubjectVisitId)
                             .Select(x => new ReadingGenerataTaskDTO
                             {
                                 IsUrgent = x.IsUrgent ?? false,
                                 SubjectId = x.SubjectId,
                                 ReadingName = x.ModuleName,
                                 ReadModuleId = x.Id,
                                 ReadingCategory = typeChangeDic[x.ModuleType],
                             }).ToListAsync();
                            if (needReadList.Any(x => x.ReadingCategory == ReadingCategory.Global))
                            {
                                needReadList = needReadList.Where(x => x.ReadingCategory != ReadingCategory.Oncology).ToList();
                            }
                        needReadList = needReadList.Where(x => _visitTaskRepository.Where(y => y.SouceReadModuleId == x.ReadModuleId).Count() == 0).ToList();
                        await _visitTaskHelpeService.AddTaskAsync(new GenerateTaskCommand()
                        {

                            ReadingCategory = ReadingCategory.Global,
                            TrialId = taskInfo.TrialId,
                            ReadingGenerataTaskList = needReadList
                        }) ;
                        break;
                        // 肿瘤学
                    case ReadingCategory.Global:
                        var subjectId = await _readModuleRepository.Where(x => x.Id == taskInfo.SouceReadModuleId).Select(x => x.SubjectVisitId).FirstOrDefaultAsync();
                        needReadList=await _readModuleRepository.Where(x => x.SubjectVisitId == subjectId&&x.ModuleType==ModuleTypeEnum.Oncology)
                              .Select(x => new ReadingGenerataTaskDTO
                              {
                                  IsUrgent = x.IsUrgent ?? false,
                                  SubjectId = x.SubjectId,
                                  ReadingName = x.ModuleName,
                                  ReadModuleId = x.Id,
                                  ReadingCategory = typeChangeDic[x.ModuleType],
                              }).ToListAsync();
                        needReadList = needReadList.Where(x => _visitTaskRepository.Where(y => y.SouceReadModuleId == x.ReadModuleId).Count() == 0).ToList();
                        await _visitTaskHelpeService.AddTaskAsync(new GenerateTaskCommand()
                        {

                            ReadingCategory = ReadingCategory.Oncology,
                            TrialId = taskInfo.TrialId,
                            ReadingGenerataTaskList = needReadList
                        });
                        break;
                }
            }

          



        }

        /// <summary>
        /// 触发裁判任务(新)
        /// </summary>
        /// <param name="visitTaskId"></param>
        /// <returns></returns>
        private async Task TriggerJudgeQuestion(Guid visitTaskId)
        {

            //x.ReReadingApplyState!=ReReadingApplyState.Agree  排除重阅的
            var visitTask = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstOrDefaultAsync();
            var visitTaskids = await _visitTaskRepository.Where(x => x.ReadingTaskState == ReadingTaskState.HaveSigned &&x.ReadingCategory!= ReadingCategory.Judge && x.ReReadingApplyState!=ReReadingApplyState.Agree && x.SourceSubjectVisitId == visitTask.SourceSubjectVisitId && x.SouceReadModuleId == visitTask.SouceReadModuleId).Select(x => x.Id).ToListAsync();

            if (visitTaskids.Count == 2)
            {
                var query = from questionAnswet in _readingTaskQuestionAnswerRepository.Where(x => visitTaskids.Contains(x.VisitTaskId))
                            join question in _readingQuestionTrialRepository.Where(x => x.IsJudgeQuestion) on new { ReadingQuestionTrialId = questionAnswet.ReadingQuestionTrialId } equals new { ReadingQuestionTrialId = question.Id }
                            select new TaskAnswerDto()
                            {
                                Answer = questionAnswet.Answer,
                                AnswerGroup = question.AnswerGroup,
                                AnswerCombination=question.AnswerCombination,
                                JudgeType=question.JudgeType,
                                QuestionId = question.Id,
                                VisitTaskId = questionAnswet.VisitTaskId,
                            };

                var questionAnswerlist = await query.ToListAsync();
                List<GroupTaskAnswerDto> groupTasks = questionAnswerlist.GroupBy(x => new { x.QuestionId, x.AnswerGroup,x.JudgeType,x.AnswerCombination }).Select(x => new GroupTaskAnswerDto
                {
                    QuestionId = x.Key.QuestionId,
                    AnswerGroup = x.Key.AnswerGroup,
                    AnswerCombination=x.Key.AnswerCombination,
                    JudgeType=x.Key.JudgeType,
                    TaskAnswerList = x.ToList(),
                }).ToList();

                var noteEqual = false;
                foreach (var item in groupTasks)
                {
                    if (item.TaskAnswerList.Count() != 2)
                    {
                        noteEqual = true;
                        break;
                    }
                    else
                    {
                        var taskAnswer1 = item.TaskAnswerList[0];
                        var taskAnswer2 = item.TaskAnswerList[1];
                        if (taskAnswer1.Answer != taskAnswer2.Answer)
                        {

                            switch (item.JudgeType)
                            {
                                case JudgeTypeEnum.AnswerDisaffinity:
                                    noteEqual = true;
                                    break;
                                case JudgeTypeEnum.AnswerGroup:
                                    var answerGroupList = JsonConvert.DeserializeObject<List<string>>(item.AnswerGroup).Select(x => new AnswerGroup()
                                    {
                                        GroupId = NewId.NextGuid(),
                                        GroupValue = x
                                    }).ToList();
                                    var itemAnswerGroupsitem1 = answerGroupList.Where(x => x.GroupValue.Contains($"|{taskAnswer1.Answer}|"));
                                    var itemAnswerGroupsitem2 = answerGroupList.Where(x => x.GroupValue.Contains($"|{taskAnswer2.Answer}|"));
                                    var unionList = itemAnswerGroupsitem1.Intersect(itemAnswerGroupsitem2).ToList();
                                    if (unionList.Count < 1)
                                    {
                                        noteEqual =true;
                                    }
                                    break;
                                case JudgeTypeEnum.AnswerCombination:
                                    var answerCombinationList = JsonConvert.DeserializeObject<List<AnswerCombinationDto>>(item.AnswerCombination == string.Empty ? "[]" : item.AnswerCombination).ToList();
                                    answerCombinationList.ForEach(x =>
                                    {
                                        if (x.AnswerGroupA.Contains(taskAnswer1.Answer) && x.AnswerGroupB.Contains(taskAnswer2.Answer))
                                        {
                                            noteEqual = true;
                                        }
                                        if (x.AnswerGroupB.Contains(taskAnswer1.Answer) && x.AnswerGroupA.Contains(taskAnswer2.Answer))
                                        {
                                            noteEqual = true;
                                        }
                                    });
                                    break;
                            }
                        }
                    }
                }
                if (noteEqual)
                {
                    await this.SaveJudgeTask(new SaveJudgeTaskDto()
                    {
                        VisitTaskIds = visitTaskids,
                    });
                }
            }
        }

        /// <summary>
        /// 触发裁判任务(老)
        /// </summary>
        /// <param name="visitTaskId"></param>
        /// <returns></returns>
        private async Task TriggerJudgeQuestionOld(Guid visitTaskId)
        {
            var visitTask = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstOrDefaultAsync();
            var visitTaskids = await _visitTaskRepository.Where(x => x.ReadingTaskState == ReadingTaskState.HaveSigned && x.ReadingCategory != ReadingCategory.Judge && x.SourceSubjectVisitId == visitTask.SourceSubjectVisitId && x.SouceReadModuleId == visitTask.SouceReadModuleId).Select(x => x.Id).ToListAsync();
            if (visitTaskids.Count == 2)
            {
                var query =  from questionAnswet  in _readingTaskQuestionAnswerRepository.Where(x=> visitTaskids.Contains(x.VisitTaskId))
                             join question in _readingQuestionTrialRepository.Where(x=>x.IsJudgeQuestion) on  new { ReadingQuestionTrialId= questionAnswet.ReadingQuestionTrialId } equals  new { ReadingQuestionTrialId= question.Id }
                             select new TaskAnswerDto()
                             {
                                Answer= questionAnswet.Answer,
                                AnswerGroup= question.AnswerGroup,
                                QuestionId= question.Id,
                                VisitTaskId= questionAnswet.VisitTaskId,
                             };
                var questionAnswerlist =await query.ToListAsync();
                List<GroupTaskAnswerDto> groupTasks = questionAnswerlist.GroupBy(x => new { x.QuestionId, x.AnswerGroup }).Select(x => new GroupTaskAnswerDto
                {
                    QuestionId = x.Key.QuestionId,
                    AnswerGroup = x.Key.AnswerGroup,
                    TaskAnswerList = x.ToList(),
                }).ToList();
                var verificationResults = true;
                foreach (var item in groupTasks)
                {
                    if (item.TaskAnswerList.Count() != 2|| item.AnswerGroup==string.Empty)
                    {
                        verificationResults = false;
                        break;
                    }
                    else
                    {
                        var item1= item.TaskAnswerList[0];
                        var item2= item.TaskAnswerList[1];
                        if (item1.Answer != item2.Answer)
                        {
                            var answerGroup = JsonConvert.DeserializeObject<List<string>>(item.AnswerGroup).Select(x => new AnswerGroup()
                            {
                                GroupId = NewId.NextGuid(),
                                GroupValue = x
                            }).ToList();
                            var itemAnswerGroupsitem1 = answerGroup.Where(x => x.GroupValue.Contains($"|{item1.Answer}|"));
                            var itemAnswerGroupsitem2 = answerGroup.Where(x => x.GroupValue.Contains($"|{item2.Answer}|"));
                            var unionList = itemAnswerGroupsitem1.Intersect(itemAnswerGroupsitem2).ToList();
                            if (unionList.Count < 1)
                            {
                                verificationResults = false;
                                break;
                            }
                        }
                    }
                }

                if (!verificationResults)
                {
                    await this.SaveJudgeTask(new SaveJudgeTaskDto() { 
                       VisitTaskIds= visitTaskids,
                    });
                }
            }
        }

        /// <summary>
        /// 添加裁判任务
        /// </summary>
        /// <returns></returns>
        private async Task SaveJudgeTask(SaveJudgeTaskDto inDto)
        {
            var trialId = await _visitTaskRepository.Where(x => inDto.VisitTaskIds.Contains(x.Id)).Select(x => x.TrialId).FirstOrDefaultAsync();

         

            await _visitTaskHelpeService.AddTaskAsync(new GenerateTaskCommand()
            {
                JudgeVisitTaskIdList= inDto.VisitTaskIds,
                ReadingCategory= ReadingCategory.Judge,
                TrialId= trialId
            });
        }

    }
}
