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

namespace IRaCIS.Core.Application.Service
{	
	/// <summary>
	/// 阅片医学审核
	/// </summary>	
	[ ApiExplorerSettings(GroupName = "Reading")]
	public class ReadingMedicalReviewService : BaseService, IReadingMedicalReviewService
    {

	    private readonly IRepository<ReadingMedicineTrialQuestion> _readingMedicineTrialQuestionRepository;
        private readonly IRepository<Trial> _trialRepository;
        private readonly IRepository<VisitTask> _visitTaskRepository;
        private readonly IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository;
        private readonly IRepository<ReadingGlobalTaskInfo> _readingGlobalTaskInfoRepository;
        private readonly IRepository<ReadingOncologyTaskInfo> _readingOncologyTaskInfoRepository;
        private readonly IRepository<ReadingSystemCriterionDictionary> _readingCriterionDictionaryRepository;

        private readonly IReadingImageTaskService _iReadingImageTaskService;
        private readonly IRepository<User> _userTaskRepository;
        private readonly IVisitTaskService _visitTaskService;
        private readonly IRepository<TaskMedicalReview> _taskMedicalReviewRepository;
        private readonly IRepository<ReadingMedicalReviewDialog> _readingMedicalReviewDialogRepository;
        private readonly IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrial;
        private readonly IRepository<ReadingMedicineQuestionAnswer> _readingMedicineQuestionAnswerRepository;
        private readonly IRepository<ReadingMedicineSystemQuestion> _readingMedicineSystemQuestionRepository;

        private readonly ITrialEmailNoticeConfigService _trialEmailNoticeConfigService;

        public ReadingMedicalReviewService(
            IRepository<ReadingMedicineTrialQuestion> readingMedicineTrialQuestionRepository,
            IRepository<Trial> trialRepository,
            IRepository<VisitTask> visitTaskRepository,
            IReadingImageTaskService readingImageTaskService,
            IRepository<ReadingTaskQuestionAnswer> readingTaskQuestionAnswerRepository,
             IRepository<ReadingGlobalTaskInfo> readingGlobalTaskInfoRepository,
               IRepository<ReadingOncologyTaskInfo> readingOncologyTaskInfoRepository,
              IRepository<ReadingSystemCriterionDictionary> readingCriterionDictionaryRepository,
            IRepository<User> userTaskRepository,
            IVisitTaskService visitTaskService,
            IRepository<TaskMedicalReview> taskMedicalReviewRepository,
            IRepository<ReadingMedicalReviewDialog> readingMedicalReviewDialogRepository,
            IRepository<ReadingQuestionCriterionTrial> readingQuestionCriterionTrial,
            IRepository<ReadingMedicineQuestionAnswer> readingMedicineQuestionAnswerRepository,
            IRepository<ReadingMedicineSystemQuestion> readingMedicineSystemQuestionRepository,
            ITrialEmailNoticeConfigService trialEmailNoticeConfigService

			)
		{
            this._readingMedicineTrialQuestionRepository = readingMedicineTrialQuestionRepository;
            this._trialRepository = trialRepository;
            this._iReadingImageTaskService = readingImageTaskService;
            this._visitTaskRepository = visitTaskRepository;
            this._readingTaskQuestionAnswerRepository = readingTaskQuestionAnswerRepository;
            this._readingGlobalTaskInfoRepository = readingGlobalTaskInfoRepository;
            this._readingOncologyTaskInfoRepository = readingOncologyTaskInfoRepository;
            this._readingCriterionDictionaryRepository = readingCriterionDictionaryRepository;
            this._userTaskRepository = userTaskRepository;
            this._visitTaskService = visitTaskService;
            this._taskMedicalReviewRepository = taskMedicalReviewRepository;
            this._readingMedicalReviewDialogRepository = readingMedicalReviewDialogRepository;
            this._readingQuestionCriterionTrial = readingQuestionCriterionTrial;
            this._readingMedicineQuestionAnswerRepository = readingMedicineQuestionAnswerRepository;
            this._readingMedicineSystemQuestionRepository = readingMedicineSystemQuestionRepository;
            _trialEmailNoticeConfigService = trialEmailNoticeConfigService;
        }

		/// <summary>
		/// 获取医学审核任务信息
		/// </summary>
		/// <param name="inDto"></param>
		/// <returns></returns>
        [HttpPost]
		public async Task<GetMedicalReviewReadingTaskOutDto> GetMedicalReviewReadingTask(GetMedicalReviewReadingTaskInDto inDto)
		{
            MedicalReviewInfo reviewInfo= await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId)
                 .ProjectTo<MedicalReviewInfo>(_mapper.ConfigurationProvider).FirstNotNullAsync();

            var taskInfo = await _visitTaskRepository.Where(x => x.Id == reviewInfo.VisitTaskId).Include(x=>x.DoctorUser).Include(x => x.Subject).FirstNotNullAsync();

            //if (taskInfo.TaskState != TaskState.Effect)
            //{
            //    throw new BusinessValidationFailedException("当前医学审核已失效！");
            //}
            inDto.TrialReadingCriterionId = taskInfo.TrialReadingCriterionId;
            var medicalReviewInfo = await _readingQuestionCriterionTrial.Where(x => x.Id == taskInfo.TrialReadingCriterionId).Select(x => new GetMedicalReviewReadingTaskOutDto()
			{
				ReadingType=x.ReadingType,
				IsReadingTaskViewInOrder=x.IsReadingTaskViewInOrder,
              
			}).FirstNotNullAsync();

            medicalReviewInfo.MedicalReviewInfo = reviewInfo;

         

            medicalReviewInfo.VisitTaskId = taskInfo.Id;
            medicalReviewInfo.ArmEnum = taskInfo.ArmEnum;
            medicalReviewInfo.SubjectCode = taskInfo.IsAnalysisCreate?taskInfo.BlindSubjectCode: taskInfo.Subject.Code;
            medicalReviewInfo.TaskBlindName = taskInfo.TaskBlindName;
            medicalReviewInfo.ReadingUser = taskInfo.DoctorUser.FirstName + taskInfo.DoctorUser.LastName;

            medicalReviewInfo.IsClosedDialog = medicalReviewInfo.MedicalReviewInfo.IsClosedDialog;
            medicalReviewInfo.AuditState = medicalReviewInfo.MedicalReviewInfo.AuditState;
            medicalReviewInfo.IsSendMessage = medicalReviewInfo.MedicalReviewInfo.IsSendMessage;


            medicalReviewInfo.QuestionAnswerList = await this.GetMedicalQuestionAnswer(inDto);


          
            var result = await _readingMedicineQuestionAnswerRepository.SaveChangesAsync();

            #region 取任务


            switch (taskInfo.ReadingCategory)
            {
                case ReadingCategory.Oncology:
                    medicalReviewInfo.OncologyInfo = await _iReadingImageTaskService.GetOncologyReadingInfo(new GetOncologyReadingInfoInDto()
                    {
                        VisitTaskId= taskInfo.Id
                    });
                    break;
                case ReadingCategory.Judge:
                    medicalReviewInfo.JudgeInfo = await _iReadingImageTaskService.GetJudgeReadingInfo(new GetJudgeReadingInfo()
                    {
                        VisitTaskId = taskInfo.Id
                    });
                    break;

                case ReadingCategory.Global:
                    medicalReviewInfo.GlobalInfo = await _iReadingImageTaskService.GetGlobalReadingInfo(new GetGlobalReadingInfoInDto()
                    {
                        VisitTaskId = taskInfo.Id
                    });
                    break;
                case ReadingCategory.Visit:
                    // 有序
                    if (medicalReviewInfo.IsReadingTaskViewInOrder)
                    {
                        medicalReviewInfo.TaskList = await _visitTaskRepository
                          
                            .Where(x => x.IsAnalysisCreate == taskInfo.IsAnalysisCreate)
                            .Where(x => x.TaskState == TaskState.Effect || x.Id == taskInfo.Id)
                            .Where(x => x.SubjectId == taskInfo.SubjectId
                            && x.ArmEnum == taskInfo.ArmEnum
                            &&x.ReadingCategory== ReadingCategory.Visit
                            && x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId

                                    && x.DoctorUserId == taskInfo.DoctorUserId &&
                                    x.ReadingTaskState == ReadingTaskState.HaveSigned &&
                                    x.ReReadingApplyState != ReReadingApplyState.Agree
                                   ).OrderBy(x => x.VisitTaskNum).Select(x => new TaskInfo()
                                   {
                                       TaskId = x.Id,
                                       VisitTaskNum=x.VisitTaskNum,
                                       //JudgeTaskId=x.JudgeVisitTaskId, // 在下面赋值  要去已完成的
                                       IsCurrentTask = x.Id == taskInfo.Id,
                                       ReadingCategory = x.ReadingCategory,
                                       TaskBlindName = x.TaskBlindName,
                                       ArmEnum = x.ArmEnum,
                                       TaskName = x.TaskName,
                                       SouceReadModuleId = x.SouceReadModuleId,
                                       SourceSubjectVisitId = x.SourceSubjectVisitId,
                                       //JudgeVisitTaskId = x.JudgeVisitTaskId,
                                       JudgeResultArm = x.JudgeResultTask.ArmEnum,
                                       SubjectId = x.SubjectId,

                                       UserTypeEnum=x.DoctorUser.UserTypeEnum
                                   }).ToListAsync();


                        List<TaskInfo> otherTask = await _visitTaskRepository.Where(x =>  
                           x.SubjectId == taskInfo.SubjectId
                         && x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId
                         && x.TaskState == TaskState.Effect
                         &&x.ReadingCategory == ReadingCategory.Visit
                        && x.IsAnalysisCreate == taskInfo.IsAnalysisCreate
                        && x.IsSelfAnalysis == taskInfo.IsSelfAnalysis
                        && x.DoctorUserId != taskInfo.DoctorUserId 
                        && x.ReadingTaskState == ReadingTaskState.HaveSigned 
                        && x.ReReadingApplyState != ReReadingApplyState.Agree)
                            .OrderBy(x => x.VisitTaskNum).Select(x => new TaskInfo()
                            {
                                TaskId = x.Id,

                                IsCurrentTask = x.Id == taskInfo.Id,
                                ReadingCategory = x.ReadingCategory,
                                TaskBlindName = x.TaskBlindName,
                                ArmEnum = x.ArmEnum,
                                TaskName = x.TaskName,
                                SouceReadModuleId = x.SouceReadModuleId,
                                SourceSubjectVisitId = x.SourceSubjectVisitId,

                                UserTypeEnum = x.DoctorUser.UserTypeEnum
                            }).ToListAsync();

                        medicalReviewInfo.TaskList.ForEach(x =>
                        {

                            var otherTaskInfo = otherTask.Where(y => y.SouceReadModuleId == x.SouceReadModuleId && y.SourceSubjectVisitId == x.SourceSubjectVisitId).FirstOrDefault();
                            if (otherTaskInfo != null)
                            {
                                x.OtherTaskId = otherTaskInfo.TaskId;
                                x.OtherArmEnum = otherTaskInfo.ArmEnum;
                            }

                        });
                    }
                    // 无序
                    else
                    {
                        medicalReviewInfo.TaskList = await _visitTaskRepository.Where(x => x.Id == taskInfo.Id).Select(x => new TaskInfo()
                        {
                            TaskId = x.Id,
                            VisitTaskNum = x.VisitTaskNum,
                            //JudgeTaskId = x.JudgeVisitTaskId,  // 在下面赋值  要去已完成的
                            IsCurrentTask = x.Id == taskInfo.Id,
                            ReadingCategory = x.ReadingCategory,
                            TaskBlindName = x.TaskBlindName,
                            ArmEnum = x.ArmEnum,
                            TaskName = x.TaskName,
                            SouceReadModuleId = x.SouceReadModuleId,
                            SourceSubjectVisitId = x.SourceSubjectVisitId,
                            SubjectId = x.SubjectId,

                            UserTypeEnum = x.DoctorUser.UserTypeEnum
                        }).ToListAsync();

                        List<TaskInfo> otherTask = await _visitTaskRepository.Where(x =>
                        x.SouceReadModuleId == taskInfo.SouceReadModuleId 
                        && x.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId
                        && x.DoctorUserId != taskInfo.DoctorUserId
                          && x.IsAnalysisCreate == taskInfo.IsAnalysisCreate
                        && x.IsSelfAnalysis == taskInfo.IsSelfAnalysis
                        && x.ReadingTaskState == ReadingTaskState.HaveSigned 
                        && x.ReReadingApplyState != ReReadingApplyState.Agree
                         && x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId
                        && x.TaskState == TaskState.Effect
                                   )
                             
                            .OrderBy(x => x.VisitTaskNum).Select(x => new TaskInfo()
                            {
                                TaskId = x.Id,
                                IsCurrentTask = x.Id == taskInfo.Id,
                                ReadingCategory = x.ReadingCategory,
                                TaskBlindName = x.TaskBlindName,
                                ArmEnum = x.ArmEnum,
                                TaskName = x.TaskName,
                                SouceReadModuleId = x.SouceReadModuleId,
                                SourceSubjectVisitId = x.SourceSubjectVisitId,

                                UserTypeEnum = x.DoctorUser.UserTypeEnum
                            }).ToListAsync();

                        medicalReviewInfo.TaskList.ForEach(x =>
                        {
                            var otherTaskInfo = otherTask.Where(y => y.SouceReadModuleId == x.SouceReadModuleId && y.SourceSubjectVisitId == x.SourceSubjectVisitId).FirstOrDefault();
                            if (otherTaskInfo != null)
                            {
                                x.OtherTaskId = otherTaskInfo.TaskId;
                                x.OtherArmEnum = otherTaskInfo.ArmEnum;
                            }

                        });
                    }

                        var taskIds = medicalReviewInfo.TaskList.Select(x => x.TaskId).ToList();

                        // 找访视
                        var visitTaskAnswer = await _readingTaskQuestionAnswerRepository.Where(x => taskIds.Contains(x.VisitTaskId) && x.ReadingQuestionTrial.IsJudgeQuestion).Select(x => new JudgeQuestionAnswerInfo
                        {
                            Answer = x.Answer,
                            VisitTaskId = x.VisitTaskId,
                            DictionaryCode = x.ReadingQuestionTrial.DictionaryCode,
                            ShowOrder = x.ReadingQuestionTrial.ShowOrder,
                            QuestionGenre = x.ReadingQuestionTrial.QuestionGenre,
                            QuestionName = x.ReadingQuestionTrial.QuestionName.LanguageName(x.ReadingQuestionTrial.QuestionEnName,_userInfo.IsEn_Us)
                        }).ToListAsync();
                        var globalChangeAnswer = await _readingGlobalTaskInfoRepository.Where(x => taskIds.Contains(x.GlobalTaskId) && x.Answer != string.Empty && x.GlobalAnswerType == GlobalAnswerType.Question && x.GlobalVisitTask.TaskState == TaskState.Effect).ToListAsync();
                    // 找全局阅片 和裁判
                    var globalTask = await _visitTaskRepository.Where(x =>
                           x.SubjectId == taskInfo.SubjectId
                         && x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId
                         && x.TaskState == TaskState.Effect
                         && x.ArmEnum== taskInfo.ArmEnum
                         && (x.ReadingCategory == ReadingCategory.Global||x.ReadingCategory==ReadingCategory.Judge)
                        && x.IsAnalysisCreate == taskInfo.IsAnalysisCreate
                        && x.IsSelfAnalysis == taskInfo.IsSelfAnalysis
                        && x.DoctorUserId == taskInfo.DoctorUserId
                        && x.ReadingTaskState == ReadingTaskState.HaveSigned
                        && x.ReReadingApplyState != ReReadingApplyState.Agree)
                       .Select(x => new
                       {
                           x.VisitTaskNum,
                           x.TaskBlindName,
                           x.Id
                       }).ToListAsync();


                        medicalReviewInfo.TaskList.ForEach(x =>
                        {

                            var visitGlobalInfo = globalTask.Where(y => y.VisitTaskNum == x.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global]).FirstOrDefault();
                            if (visitGlobalInfo != null)
                            {
                                x.GlobalTaskId = visitGlobalInfo.Id;
                                x.GlobalTaskName = visitGlobalInfo.TaskBlindName;
                            }

                            var visitJudgeInfo = globalTask.Where(y => y.VisitTaskNum == x.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Judge]).FirstOrDefault();
                            if (visitJudgeInfo != null)
                            {
                                x.JudgeTaskId = visitJudgeInfo.Id;
                                x.JudgeTaskName = visitJudgeInfo.TaskBlindName;
                            }

                        
                            x.IsGlobalChange = globalChangeAnswer.Any(y => y.TaskId == x.TaskId);
                            x.JudgeQuestionAnswerInfoList = visitTaskAnswer.Where(y => y.VisitTaskId == x.TaskId).OrderBy(y => y.ShowOrder).ToList();
                        });

                    medicalReviewInfo.TaskList.ForEach(x =>
                    {

                        x.IsCurrentTask = x.TaskId == taskInfo.Id;
                    });
                    break;
            }

        

         
            #endregion
            return medicalReviewInfo;

        }

        #region 问题

        private async Task<List<ReadingMedicineQuestion>> GetMedicalQuestionAnswer(GetMedicalReviewReadingTaskInDto inDto)
        {
            var medicalReview = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).FirstNotNullAsync();
            var taskInfo = await _visitTaskRepository.Where(x => x.Id == medicalReview.VisitTaskId).FirstNotNullAsync();

            var questionQuery = from data in _readingMedicineTrialQuestionRepository.Where(x => x.TrialId == inDto.TrialId && x.IsConfirm && x.IsEnable&&x.ReadingCategory==taskInfo.ReadingCategory&&x.TrialReadingCriterionId==inDto.TrialReadingCriterionId)
                                join questionAnswer in _readingMedicineQuestionAnswerRepository.Where(x => x.TaskMedicalReviewId == inDto.TaskMedicalReviewId) on data.Id equals questionAnswer.ReadingMedicineQuestionId into questionAnswerTemp
                                from leftquestionAnswer in questionAnswerTemp.DefaultIfEmpty()
                                select new ReadingMedicineQuestion()
                                {
									Id = data.Id,
									Type = data.Type,
									ParentTriggerValue = data.ParentTriggerValue,
									LanguageType = data.LanguageType,
									IsEnable = data.IsEnable,
									IsConfirm = data.IsConfirm,
									QuestionName = data.QuestionName,
									IsRequired = data.IsRequired,
									ShowOrder = data.ShowOrder,
									ParentId = data.ParentId,
									TypeValue = data.TypeValue,
									Answer = leftquestionAnswer.Answer
								};

            var questionList = await questionQuery.OrderBy(x=>x.ShowOrder).ToListAsync();

            List<ReadingMedicineQuestion> medicineQuestionList = questionList.Where(x => x.ParentId == null).ToList();
            medicineQuestionList.ForEach(x =>
            {
                FindChildQuestion(x, questionList);
            });

            return medicineQuestionList;
        }


        private void FindChildQuestion(ReadingMedicineQuestion medicineQuestionList, List<ReadingMedicineQuestion> questionlists)
        {
            medicineQuestionList.Childrens = questionlists.Where(x => x.ParentId == medicineQuestionList.Id).ToList();
            if (medicineQuestionList.Childrens != null && medicineQuestionList.Childrens.Count != 0)
            {
                medicineQuestionList.Childrens.ForEach(x =>
                {
                    this.FindChildQuestion(x, questionlists);
                });
            }
        }

        #endregion



        /// <summary>
        /// 保存医学审核问题 答案
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
        public async Task<IResponseOutput> SaveMedicineQuestion(SaveMedicineQuestionInDto inDto)
        {
            var medicalReviewInfo = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).FirstNotNullAsync();
            if (medicalReviewInfo.IsInvalid)
            {
                throw new BusinessValidationFailedException(_localizer["MedicalReview_invalid"]);
            }
            await _readingMedicineQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.TaskMedicalReviewId == inDto.TaskMedicalReviewId);

            List<ReadingMedicineQuestionAnswer> questionAnswerList = inDto.QuestionAnswerList.Select(x => new ReadingMedicineQuestionAnswer()
            {
                Answer = x.Answer,
                ReadingMedicineQuestionId = x.Id,
                TaskMedicalReviewId = inDto.TaskMedicalReviewId,
                VisitTaskId = medicalReviewInfo.VisitTaskId,

            }).ToList();

            await _readingMedicineQuestionAnswerRepository.AddRangeAsync(questionAnswerList);

            await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(inDto.TaskMedicalReviewId, x => new TaskMedicalReview()
            {

                SaveQuestionTime = DateTime.Now,
                AuditState = MedicalReviewAuditState.Auditing,

            });



          

            var result = await _readingMedicineQuestionAnswerRepository.SaveChangesAsync();

           return  ResponseOutput.Result(result);

        }

        /// <summary>
        /// 保存医学审核 结论
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
        public async Task<IResponseOutput> SaveMedicalReviewInfo(SaveMedicalReviewInfoInDto inDto)
        {
            var medicalReviewInfo = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).FirstNotNullAsync();
            if (medicalReviewInfo.IsInvalid)
            {
                throw new BusinessValidationFailedException(_localizer["MedicalReview_invalid"]);
            }
            if ((await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).Select(x => x.SaveQuestionTime).FirstOrDefaultAsync()) == null)
            {
                throw new BusinessValidationFailedException(_localizer["MedicalReview_SaveQuestion"]);
            }
            await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(inDto.TaskMedicalReviewId, x => new TaskMedicalReview()
            {
                IsHaveQuestion = inDto.IsHaveQuestion,
                Questioning = inDto.Questioning,
                IsSendMessage = inDto.IsSendDialog && inDto.IsHaveQuestion,
                ImagePath = JsonConvert.SerializeObject(inDto.FileList),

                AuditAdviceEnum = inDto.AuditAdviceEnum,
                SaveConclusionTime = DateTime.Now,

            }); 

            var medicalReview = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).FirstNotNullAsync();
            if (inDto.IsSendDialog&& !medicalReview.IsSendMessage && inDto.IsHaveQuestion)
            {
              
                await _readingMedicalReviewDialogRepository.AddAsync(new ReadingMedicalReviewDialog()
                {
                    AuditAdviceEnum = inDto.AuditAdviceEnum,
                    TaskMedicalReviewId = inDto.TaskMedicalReviewId,
                    UserTypeShortName = _userInfo.UserTypeShortName,
                    IsHaveQuestion=inDto.IsHaveQuestion,
                    Questioning=inDto.Questioning,
                    VisitTaskId= medicalReview.VisitTaskId,
                 
                    UserTypeEnumInt = _userInfo.UserTypeEnumInt,
                    ImagePath = JsonConvert.SerializeObject(inDto.FileList),
                });
            }

            var result = await _taskMedicalReviewRepository.SaveChangesAsync();
            return ResponseOutput.Result(result);
        }


        /// <summary>
        /// 关闭医学审核对话
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
        public async Task<IResponseOutput> ClosedMedicalReviewDialog(ClosedMedicalReviewDialogInDto inDto)
        {
            await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(inDto.TaskMedicalReviewId, x => new TaskMedicalReview()
            {
                IsClosedDialog = inDto.IsClosedDialog,
                MedicalDialogCloseEnum=inDto.MedicalDialogCloseEnum,
                DialogCloseReason=inDto.DialogCloseReason,
            });

            var taskMedical = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).FirstNotNullAsync();

            ReadingMedicalReviewDialog dialog = new ReadingMedicalReviewDialog()
            {
                TaskMedicalReviewId = inDto.TaskMedicalReviewId,
                VisitTaskId= taskMedical.VisitTaskId,
                UserTypeShortName = _userInfo.UserTypeShortName,
                MedicalDialogCloseEnum= inDto.MedicalDialogCloseEnum,
                Content = inDto.DialogCloseReason,
                UserTypeEnumInt = _userInfo.UserTypeEnumInt,
            };

            await _readingMedicalReviewDialogRepository.AddAsync(dialog);
            var result = await _taskMedicalReviewRepository.SaveChangesAsync();
            return ResponseOutput.Result(result);
        }

        /// <summary>
        /// 发送对话消息
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
        public  async Task<IResponseOutput> SendMedicalReviewDialog(SendMedicalReviewDialogInDto inDto)
        {
            var medicalReviewInfo = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).FirstNotNullAsync();
            if (medicalReviewInfo.IsInvalid)
            {
                throw new BusinessValidationFailedException(_localizer["MedicalReview_invalid"]);
            }

            var visitTaskId = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).Select(x => x.VisitTaskId).FirstOrDefaultAsync();
            ReadingMedicalReviewDialog dialog = new ReadingMedicalReviewDialog()
            {
                TaskMedicalReviewId = inDto.TaskMedicalReviewId,
                UserTypeShortName = _userInfo.UserTypeShortName,
                Content = inDto.Content,
                UserTypeEnumInt = _userInfo.UserTypeEnumInt,
                VisitTaskId = visitTaskId,
                AuditAdviceEnum=inDto.AuditAdviceEnum,
              
                IsHaveQuestion=inDto.IsHaveQuestion,
                Questioning=inDto.Questioning,
            };

            await _readingMedicalReviewDialogRepository.AddAsync(dialog);

            var result=await _readingMedicalReviewDialogRepository.SaveChangesAsync();
            return ResponseOutput.Result(result);
        }

        /// <summary>
        /// IR发送消息
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [UnitOfWork]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
        public async Task<IResponseOutput> IRSendMedicalReviewDialog(IRSendMedicalReviewDialogInDto inDto)
        {
            var medicalReviewInfo = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).FirstNotNullAsync();
            if (medicalReviewInfo.IsInvalid)
            {
                throw new BusinessValidationFailedException(_localizer["MedicalReview_invalid"]);
            }
            var visitTaskId = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).Select(x => x.VisitTaskId).FirstOrDefaultAsync();
            if (inDto.IsApplyHeavyReading??false)
            {
                await _visitTaskService.ApplyReReading(new ApplyReReadingCommand()
                {
                    IsCopyOrigenalForms = inDto.IsCopyOrigenalForms??false,
                    IsCopyFollowForms=inDto.IsCopyFollowForms ?? false,
                    RequestReReadingReason = inDto.RequestReReadingReason,
                    RequestReReadingType = RequestReReadingType.DocotorApply,
                    TrialId = inDto.TrialId,
                    TaskIdList = new List<Guid>()
                 {
                     visitTaskId              
                 }
                });


                await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(x => !x.IsClosedDialog && x.Id == inDto.TaskMedicalReviewId, x => new TaskMedicalReview()
                {
                    IsClosedDialog = true,
                    MedicalDialogCloseEnum = MedicalDialogClose.IRApplyReReading,


                    IsApplyHeavyReading = true,
                    FileName = inDto.FileName,
                    ImagePath = JsonConvert.SerializeObject(inDto.FileList),
                    DisagreeReason = inDto.DisagreeReason,                
                });
            }

            await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(inDto.TaskMedicalReviewId, x => new TaskMedicalReview()
            {
                DoctorUserIdeaEnum = inDto.DoctorUserIdeaEnum,
            });
            ReadingMedicalReviewDialog dialog = new ReadingMedicalReviewDialog()
            {
                TaskMedicalReviewId = inDto.TaskMedicalReviewId,
                UserTypeShortName = _userInfo.UserTypeShortName,
                Content = inDto.Content,
                ImagePath=JsonConvert.SerializeObject(inDto.FileList),
                UserTypeEnumInt = _userInfo.UserTypeEnumInt,
                VisitTaskId = visitTaskId,
                FileName=inDto.FileName,
                DisagreeReason = inDto.DisagreeReason,
                DoctorUserIdeaEnum = inDto.DoctorUserIdeaEnum,
                IsApplyHeavyReading = inDto.IsApplyHeavyReading,
            };

            await _readingMedicalReviewDialogRepository.AddAsync(dialog);
            var result = await _readingMedicalReviewDialogRepository.SaveChangesAsync();
            return ResponseOutput.Result(result);
        }


        /// <summary>
        /// 获取医学审核对话
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<(List<GetMedicalReviewDialogOutDto>,object)> GetMedicalReviewDialog(GetMedicalReviewDialogInDto inDto)
        {
            var taskMedicalReview = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).FirstNotNullAsync();
            List<GetMedicalReviewDialogOutDto> result = await _readingMedicalReviewDialogRepository.Where(x => x.TaskMedicalReviewId == inDto.TaskMedicalReviewId)
                .ProjectTo<GetMedicalReviewDialogOutDto>(_mapper.ConfigurationProvider)
                .OrderBy(x => x.CreateTime).ToListAsync();
            result.ForEach(x => {
                x.IsCurrentUser = x.CreateUserId == _userInfo.Id;
            });
            return (result,new  {

            IsIRReply= result.Any(x=>x.UserTypeEnumInt== (int)UserTypeEnum.IndependentReviewer),
            taskMedicalReview.IsClosedDialog,
            taskMedicalReview.IsHaveQuestion,
            });
        }

        /// <summary>
        /// 完成医学审核
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [NonDynamicMethod]
        public async Task<IResponseOutput> FinishMedicalReview(FinishMedicalReviewInDto inDto)
        {
            var medicalReviewInfo = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).FirstNotNullAsync();
            if (medicalReviewInfo.IsInvalid)
            {
                throw new BusinessValidationFailedException(_localizer["MedicalReview_invalid"]);
            }

            var taskmedicalReview = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).Select(x => new
            {
                x.SaveConclusionTime,
                x.SaveQuestionTime,
                x.IsClosedDialog,
                x.IsHaveQuestion

            }).FirstNotNullAsync();

            if (taskmedicalReview.SaveQuestionTime == null || taskmedicalReview.SaveConclusionTime==null)
            {
                throw new BusinessValidationFailedException(_localizer["MedicalReview_NeedSave"]);

            }

            if (taskmedicalReview.IsHaveQuestion&&!taskmedicalReview.IsClosedDialog)
            {
                throw new BusinessValidationFailedException(_localizer["MedicalReview_NotClosed"]);

            }

            await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(inDto.TaskMedicalReviewId, x => new TaskMedicalReview()
            {
                AuditState = MedicalReviewAuditState.HaveSigned,
                AuditSignTime=DateTime.Now,
            });

            var result = await _taskMedicalReviewRepository.SaveChangesAsync();

            ////自动发送邮件逻辑
            //if (medicalReviewInfo.IsAutoGenerate)
            //{

            //    var allMedicalAuditList=  await _taskMedicalReviewRepository.Where(x => medicalReviewInfo.PDRelationTaskIdList.Contains(x.VisitTaskId) && x.IsAutoGenerate && x.IsInvalid==false).ToListAsync();

            //    if (allMedicalAuditList.All(t => t.IsApplyHeavyReading == false && t.AuditSignTime!=null && t.AuditState == MedicalReviewAuditState.HaveSigned))
            //    {
            //        //自动发送
            //        await _trialEmailNoticeConfigService.BaseBusinessScenarioSendEmailAsync(medicalReviewInfo.VisitTaskId, false);
            //    }


            //}




            return ResponseOutput.Result(result);
        }

        /// <summary>
        /// IR回复确认医学审核
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        [UnitOfWork]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
        public async Task<IResponseOutput> IRConfirmMedicalReview(IRConfirmMedicalReviewInDto inDto)
        {
            var medicalReviewInfo = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).FirstNotNullAsync();
            if (medicalReviewInfo.IsInvalid)
            {
                throw new BusinessValidationFailedException(_localizer["MedicalReview_invalid"]);
            }

            await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(inDto.TaskMedicalReviewId, x => new TaskMedicalReview()
            {
                DoctorUserIdeaEnum = inDto.DoctorUserIdeaEnum,
                DisagreeReason = inDto.DisagreeReason,
                IsApplyHeavyReading=inDto.IsApplyHeavyReading,
            });

            var visitTaskId = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).Select(x => x.VisitTaskId).FirstOrDefaultAsync();
            await _readingMedicalReviewDialogRepository.AddAsync(new ReadingMedicalReviewDialog()
            {
                
                TaskMedicalReviewId = inDto.TaskMedicalReviewId,
                UserTypeShortName = _userInfo.UserTypeShortName,
                DoctorUserIdeaEnum = inDto.DoctorUserIdeaEnum,
                DisagreeReason = inDto.DisagreeReason,
                IsApplyHeavyReading = inDto.IsApplyHeavyReading,
                VisitTaskId = visitTaskId,
                UserTypeEnumInt = _userInfo.UserTypeEnumInt,
            });

            var result = await _taskMedicalReviewRepository.SaveChangesAsync();
            return ResponseOutput.Result(result);
        }


        /// <summary>
        /// 获取IR医学审核信息
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageOutput<GetIRMedicalFeedbackListOutDto>> GetIRMedicalFeedbackList(GetIRMedicalFeedbackListInDto inDto)
        {
            var taskMedicalReviewquery = _taskMedicalReviewRepository.Where(x => x.TrialId == inDto.TrialId).Include(x => x.VisitTask)
                .Where(x => x.VisitTask.DoctorUserId == _userInfo.Id)
                .Where(x => x.IsHaveQuestion)
                .WhereIf(!inDto.TaskBlindName.IsNullOrEmpty(), x => x.VisitTask.TaskBlindName == inDto.TaskBlindName)
                 .WhereIf(inDto.IsUrgent != null, x => x.VisitTask.IsUrgent == inDto.IsUrgent!)
                 .WhereIf(inDto.AuditState != null, x => x.AuditState == inDto.AuditState!)
                 .WhereIf(inDto.ReadingCategory != null, x => x.VisitTask.ReadingCategory == inDto.ReadingCategory!)
                 .WhereIf(inDto.AuditAdviceEnum != null, x => x.AuditAdviceEnum == inDto.AuditAdviceEnum!)
                 .WhereIf(inDto.DoctorUserIdeaEnum != null, x => x.DoctorUserIdeaEnum == inDto.DoctorUserIdeaEnum!)
                 .WhereIf(inDto.IsClosedDialog != null, x => x.IsClosedDialog == inDto.IsClosedDialog!)
                 .WhereIf(inDto.IsHaveQuestion != null, x => x.IsHaveQuestion == inDto.IsHaveQuestion!)
                 .WhereIf(inDto.MedicalDialogCloseEnum != null, x => x.MedicalDialogCloseEnum == inDto.MedicalDialogCloseEnum!)
                 .WhereIf(inDto.IsInvalid != null, x => x.IsInvalid == inDto.IsInvalid!)
                 .WhereIf(inDto.TrialReadingCriterionId != null, x => x.VisitTask.TrialReadingCriterionId == inDto.TrialReadingCriterionId!)
                .Select(x => new GetIRMedicalFeedbackListOutDto
                {
                    TaskState=x.VisitTask.TaskState,
                    Id = x.Id,
                    VisitTaskId=x.VisitTaskId,
                    IsUrgent = x.VisitTask.IsUrgent,
                    AuditState = x.AuditState,
                    SubjectCode = x.VisitTask.BlindSubjectCode == string.Empty ? x.VisitTask.Subject.Code : x.VisitTask.BlindSubjectCode,
                    TaskBlindName = x.VisitTask.TaskBlindName,
                    TaskName=x.VisitTask.TaskName,
                    UserTypeEnum=x.VisitTask.DoctorUser.UserTypeEnum,
                    ReadingCategory = x.VisitTask.ReadingCategory,
                    FirstReplyTime = x.ReadingMedicalReviewDialogList.Min(x => x.CreateTime),
                    LastReplyTime = x.ReadingMedicalReviewDialogList.Max(x => x.CreateTime),
                    AuditAdviceEnum = x.AuditAdviceEnum,
                    DoctorUserIdeaEnum = x.DoctorUserIdeaEnum,
                    SaveConclusionTime=x.SaveConclusionTime,
                    IsClosedDialog=x.IsClosedDialog,
                    IsHaveQuestion=x.IsHaveQuestion,
                    MedicalDialogCloseEnum=x.MedicalDialogCloseEnum,
                    IsInvalid=x.IsInvalid,

                    SubjectId=x.VisitTask.SubjectId,
                    TrialReadingCriterionId = x.VisitTask.TrialReadingCriterion.Id,
                    TrialReadingCriterionName =x.VisitTask.TrialReadingCriterion.CriterionName,
                    ReadingTool= x.VisitTask.TrialReadingCriterion.ReadingTool,

                    IsReadingTaskViewInOrder = x.VisitTask.TrialReadingCriterion.IsReadingTaskViewInOrder,
                    IsReadingShowSubjectInfo = x.VisitTask.TrialReadingCriterion.IsReadingShowSubjectInfo,
                    IsReadingShowPreviousResults = x.VisitTask.TrialReadingCriterion.IsReadingShowPreviousResults,
                    DigitPlaces = x.VisitTask.TrialReadingCriterion.DigitPlaces,
                    IseCRFShowInDicomReading = x.VisitTask.TrialReadingCriterion.IseCRFShowInDicomReading,
                    CriterionType = x.VisitTask.TrialReadingCriterion.CriterionType,

                }).WhereIf(!inDto.SubjectCode.IsNullOrEmpty(), x => x.SubjectCode == inDto.SubjectCode);

            var result=await taskMedicalReviewquery.ToPagedListAsync(inDto.PageIndex, inDto.PageSize, inDto.SortField.IsNullOrEmpty() ? nameof(GetIRMedicalFeedbackListOutDto.AuditState) : inDto.SortField,
               inDto.Asc);

            return result;
        }
    }
} 
