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

using IRaCIS.Core.Domain.Models;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using MiniSoftware;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Domain.Share.Common;
using System.IO;
using System.Linq;
using Spire.Doc;

namespace IRaCIS.Core.Application.Service
{
    /// <summary>
    /// TrialEmailNoticeConfigService
    /// </summary>	
    [ApiExplorerSettings(GroupName = "Trial")]
    public class TrialEmailNoticeConfigService : BaseService, ITrialEmailNoticeConfigService
    {

        private readonly IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigRepository;
        private readonly IRepository<TrialEmailBlackUser> _trialEmailBlackUserRepository;
        private readonly IRepository<EmailNoticeConfig> _emailNoticeConfigRepository;


        private readonly IRepository<Trial> _trialRepository;
        private readonly IRepository<TaskMedicalReview> _taskMedicalReviewRepository;
        private readonly IRepository<VisitTask> _visitTaskRepository;
        private readonly IRepository<TrialUser> _trialUserRepository;
        private readonly IRepository<Subject> _subjectRepository;
        private readonly IRepository<SubjectVisit> _subjectVisitRepository;




        public TrialEmailNoticeConfigService(
            IRepository<TrialEmailNoticeConfig> trialEmailNoticeConfigRepository, 
            IRepository<VisitTask> visitTaskRepository,
            IRepository<Trial> trialRepository,
            IRepository<TrialUser> trialUserRepository, 
            IRepository<TaskMedicalReview> taskMedicalReviewRepository, 
            IRepository<Subject> subjectRepository,
            IRepository<SubjectVisit> subjectVisitRepository, 
            IRepository<TrialEmailBlackUser> trialEmailBlackUserRepository, 
            IRepository<EmailNoticeConfig> emailNoticeConfigRepository
            )
        {
            _trialEmailNoticeConfigRepository = trialEmailNoticeConfigRepository;
            _visitTaskRepository = visitTaskRepository;
            _trialRepository = trialRepository;
            _trialUserRepository = trialUserRepository;
            _taskMedicalReviewRepository = taskMedicalReviewRepository;
            _subjectRepository = subjectRepository;
            _subjectVisitRepository = subjectVisitRepository;
            _trialEmailBlackUserRepository = trialEmailBlackUserRepository;
            _emailNoticeConfigRepository = emailNoticeConfigRepository;
        }

        /// <summary>
        /// 获取项目邮箱
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<GetTrialEmailSetOutDto> GetTrialEmail(GetTrialEmailSetInDto inDto)
        {
            return await _trialRepository.Where(x => x.Id == inDto.TrialId,ignoreQueryFilters:true).Select(x => new GetTrialEmailSetOutDto()
            {
                TrialId = inDto.TrialId,
                EmailAuthorizationCode = x.EmailAuthorizationCode,
                EmailSMTPServerAddress = x.EmailSMTPServerAddress,
                EmailFromEmail = x.EmailFromEmail,
                EmailFromName = x.EmailFromName,
                IsConfigureEmail = x.IsConfigureEmail,
                EmailSMTPServerPort = x.EmailSMTPServerPort

            }).FirstOrDefaultAsync();
        }

        /// <summary>
        /// 设置项目邮箱
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        public async Task<IResponseOutput> SetTrialEmail(SetTrialEmailInDto inDto)
        {

            await TestEmailConfigAsync(new TrialEmailNoticeConfigAddOrEdit()
            {

                AuthorizationCode = inDto.EmailAuthorizationCode,
                FromEmail = inDto.EmailFromEmail,
                FromName = inDto.EmailFromName,
                SMTPServerAddress = inDto.EmailSMTPServerAddress,
                SMTPServerPort = inDto.EmailSMTPServerPort,
                TrialId = inDto.TrialId,
            });

            await _trialRepository.UpdatePartialFromQueryAsync(inDto.TrialId, x => new Trial()
            {

                EmailFromEmail = inDto.EmailFromEmail,
                EmailFromName = inDto.EmailFromName,
                EmailAuthorizationCode = inDto.EmailAuthorizationCode,
                EmailSMTPServerAddress = inDto.EmailSMTPServerAddress,
                EmailSMTPServerPort = inDto.EmailSMTPServerPort,
                IsConfigureEmail = true,
            });



            await _trialEmailNoticeConfigRepository.BatchUpdateNoTrackingAsync(x => x.TrialId == inDto.TrialId, x => new TrialEmailNoticeConfig()
            {
                AuthorizationCode = inDto.EmailAuthorizationCode,
                FromEmail = inDto.EmailFromEmail,
                FromName = inDto.EmailFromName,
                SMTPServerAddress = inDto.EmailSMTPServerAddress,
                SMTPServerPort = inDto.EmailSMTPServerPort,
            });

            await _trialRepository.SaveChangesAsync();
            return ResponseOutput.Ok();
        }

        /// <summary>
        /// 同步系统配置的文档到想项目中 ---废弃
        /// </summary>
        /// <param name="trialId"></param>
        /// <returns></returns>
        /// 
        private async Task SyncSystemEmainCofigDocListAsync(Guid trialId)
        {

            //判断流程配置是否确认  确认了一定确认了标准   可以进行同步

            if (_repository.Where<Trial>(t => t.Id == trialId).Any(t => t.IsTrialProcessConfirmed == true))
            {

                //只要有系统标准的文档 说明同步过了
                var trialDocCount = _trialEmailNoticeConfigRepository.Where(t => t.TrialId == trialId).Count();

                if (trialDocCount == 0)
                {
                    //找到确认的标准
                    var list = await _repository.Where<ReadingQuestionCriterionTrial>(t => t.TrialId == trialId && t.IsConfirm).Select(t => new { t.CriterionType, TrialReadingCriterionId = t.Id }).ToListAsync();

                    var confirmedCriterionTypeList = list.Select(t => (CriterionType?)t.CriterionType).ToList();

                    var docmentList = _repository.Where<TrialEmailNoticeConfig>(t => t.BusinessScenarioEnum == EmailBusinessScenario.EnrollConfirmed || t.BusinessScenarioEnum == EmailBusinessScenario.PDConfirmed)
                        //.Where(t => (confirmedCriterionTypeList.Contains(t.CriterionTypeEnum)) || t.CriterionTypeEnum == null).Select(t => new { t.Path, t.Name, t.Code, t.BusinessScenarioEnum, t.CriterionTypeEnum })
                        .ToList();



                    foreach (var item in docmentList)
                    {
                        await _trialEmailNoticeConfigRepository.AddAsync(new TrialEmailNoticeConfig()
                        {
                            TrialId = trialId,
                            TrialReadingCriterionId = list.Where(t => t.CriterionType == item.CriterionTypeEnum).FirstOrDefault()?.TrialReadingCriterionId,
                            //FileName = item.Name,
                            //FilePath = item.Path,
                            BusinessScenarioEnum = item.BusinessScenarioEnum,
                            Code = item.Code
                        });
                    }

                }


            }



            await _trialEmailNoticeConfigRepository.SaveChangesAsync();
        }




        private async Task<bool> DealMedicalReviewTasKGenerateAndIsSendAsync(Guid trialId, bool? isHandSend, string pdAnswer, List<Guid> taskIdList, List<Guid> minUserIdList)
        {

            var isNeedSend = true;

            //手动发送的时候，也有可能答案是是  此时是 这里不发送，发送已经生成的文件
            if (pdAnswer == "是" && isHandSend == null)
            {
                isNeedSend = true;

            }
            else
            {
                //正常阅片为否的
                if (isHandSend == null)
                {
                    isNeedSend = false;

                    //生成任务
                    foreach (var taskId in taskIdList)
                    {
                        await _taskMedicalReviewRepository.AddAsync(new TaskMedicalReview()
                        {
                            TrialId = trialId,
                            VisitTaskId = taskId,
                            MedicalManagerUserId = minUserIdList.FirstOrDefault(),
                            AllocateTime = DateTime.Now
                            ,
                            IsAutoGenerate = true,
                            PDRelationTaskIdListStr = string.Join('|', taskIdList.Distinct())
                        }, true);

                    }
                }
                else if (isHandSend == true)
                {
                    //手动发送
                    isNeedSend = false;
                }
                else
                {
                    // 医学审核确认未否了 才发
                    isNeedSend = true;
                }
            }




            return isNeedSend;

        }

        /// <summary>
        /// 测试邮件 带附件 填充word --前端不需
        /// </summary>
        /// <param name="visitTaskId"></param>
        /// <param name="isHandSend"> 为空 代表 正常任务自动发送，为true  代表医学审核手动发送  为false 代表医学审核自动发送 </param>
        /// <param name="emailStoreMode"></param>
        /// <param name="sendFileRelativePath"></param>
        /// <returns></returns>
        /// <exception cref="BusinessValidationFailedException"></exception>
        public async Task<string> BaseBusinessScenarioSendEmailAsync(Guid visitTaskId, bool? isHandSend, EmailStoreSendMode emailStoreMode, string sendFileRelativePath)
        {

            EmailBusinessScenario? businessScenarioEnum = null;

            #region 任务关联的项目配置  标准信息及配置，subject 信息
            var taskInfo = await _visitTaskRepository.Where(t => t.Id == visitTaskId).Select(t => new
            {

                t.Trial.ResearchProgramNo,
                t.Subject.TrialSite.TrialSiteCode,
                SubjectCode = t.Subject.Code,
                t.Trial.Sponsor.SponsorName,
                t.Trial.IsEnrollementQualificationConfirm,
                t.Trial.IsPDProgressView,


                VisitEarliestScanDate = t.SourceSubjectVisit.EarliestScanDate,
                VisitName = (string?)t.SourceSubjectVisit.VisitName,
                IsFinalVisit = (bool?)t.SourceSubjectVisit.IsFinalVisit,
                PDState = (PDStateEnum?)t.SourceSubjectVisit.PDState,
                IsEnrollmentConfirm = (bool?)t.SourceSubjectVisit.IsEnrollmentConfirm,
                IsBaseline = (bool?)t.SourceSubjectVisit.IsBaseLine,


                ModuleEarliestScanDate = t.ReadModule.SubjectVisit.EarliestScanDate,
                ModuleVisitName = (string?)t.ReadModule.SubjectVisit.VisitName,
                MoudulePDState = (PDStateEnum?)t.ReadModule.SubjectVisit.PDState,

                t.SourceSubjectVisitId,
                t.SouceReadModuleId,
                t.SubjectId,
                t.Subject.SiteId,

                t.DoctorUserId,
                t.ReadingTaskState,
                t.ReadingCategory,
                t.SignTime,
                //仲裁规则
                t.TrialReadingCriterion.ArbitrationRule,
                //单双中
                t.TrialReadingCriterion.ReadingType,

                t.TrialReadingCriterion.CriterionType,
                //有序与否
                t.TrialReadingCriterion.IsReadingTaskViewInOrder,

                t.TrialId,



                t.IsAnalysisCreate,
                t.TrialReadingCriterionId,
            }).FirstNotNullAsync();


            if (taskInfo.IsAnalysisCreate)
            {
                return string.Empty;
            }

            #endregion


            #region 任务 -邮件场景区分

            if (taskInfo.ReadingTaskState == ReadingTaskState.HaveSigned)
            {
                //入组确认场景
                if (taskInfo.IsEnrollmentConfirm == true && taskInfo.IsEnrollementQualificationConfirm == true && taskInfo.IsBaseline == true)
                {
                    businessScenarioEnum = EmailBusinessScenario.EnrollConfirmed;


                }
                //PD确认场景
                else if (taskInfo.IsPDProgressView &&
                    (taskInfo.PDState == PDStateEnum.PDProgress && taskInfo.SourceSubjectVisitId != null) ||
                    (taskInfo.SouceReadModuleId != null && taskInfo.MoudulePDState == PDStateEnum.PDProgress))
                {
                    businessScenarioEnum = EmailBusinessScenario.PDConfirmed;
                }
                else
                {
                    return string.Empty;
                }

            }
            else
            {
                //---进行邮件发送前，该任务必须已签名完成并已经触发完成相应的任务生成
                throw new BusinessValidationFailedException(_localizer["TrialEmailN_TaskNotSigned"]);
            }



            #endregion


            #region 发收件人配置 确保无误


            var emailConfig = await _trialEmailNoticeConfigRepository.Where(t => t.TrialId == taskInfo.TrialId && t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.BusinessScenarioEnum == businessScenarioEnum)
                .Include(t => t.TrialEmailNoticeUserList).FirstOrDefaultAsync();


            if (emailConfig == null || (emailConfig.IsAutoSend == false && isHandSend == null))
            {
                //throw new BusinessValidationFailedException("找不到该项目标准场景下邮件的配置");

                return string.Empty;
            }


            var sendEmailConfig = new SMTPEmailConfig();

            //收件人 如果是CRC  CRA  要按照中心发送
            var toUserTypeEnumList = emailConfig.TrialEmailNoticeUserList.Where(t => t.EmailUserType == EmailUserType.To).Select(c => c.UserType).ToList();



            var toUserList = _repository.Where<TrialSiteUser>(t => t.TrialId == taskInfo.TrialId && toUserTypeEnumList.Contains(t.User.UserTypeEnum) && t.SiteId == taskInfo.SiteId).Select(t => new { t.User.EMail, t.User.FullName }).ToList();

            var copyUserTypeEnumList = emailConfig.TrialEmailNoticeUserList.Where(t => t.EmailUserType == EmailUserType.Copy).Select(c => c.UserType).ToList();
            var copyUserList = _repository.Where<TrialUser>(t => t.TrialId == taskInfo.TrialId && copyUserTypeEnumList.Contains(t.User.UserTypeEnum)).Select(t => new { t.User.EMail, t.User.FullName }).ToList();


            if (toUserList.Count() == 0)
            {
                //---没有收件人，无法发送邮件
                throw new BusinessValidationFailedException(_localizer["TrialEmailN_NoRecipient"]);
            }


            if (emailConfig.FromEmail.Contains("@") && !string.IsNullOrEmpty(emailConfig.FromEmail))
            {

                sendEmailConfig.FromEmailAddress = new MimeKit.MailboxAddress(emailConfig.FromName, emailConfig.FromEmail);
                sendEmailConfig.AuthorizationCode = emailConfig.AuthorizationCode;
                sendEmailConfig.UserName = emailConfig.FromEmail;

                sendEmailConfig.Host = emailConfig.SMTPServerAddress;
                sendEmailConfig.Port = emailConfig.SMTPServerPort;


                //测试
                //sendEmailConfig.ToMailAddressList.Add(new MimeKit.MailboxAddress("ddd", "872297557@qq.com"));

            }
            else
            {
                //---项目发件邮箱配置有误，请核实
                throw new BusinessValidationFailedException(_localizer["TrialEmailN_InvalidEmailConfig"]);
            }

            foreach (var item in toUserList)
            {

                if (item.EMail.Contains("@") && !string.IsNullOrEmpty(item.EMail))
                {

                    sendEmailConfig.ToMailAddressList.Add(new MimeKit.MailboxAddress(item.FullName, item.EMail));

                }
            }
            foreach (var item in copyUserList)
            {

                if (item.EMail.Contains("@") && !string.IsNullOrEmpty(item.EMail))
                {

                    sendEmailConfig.CopyToMailAddressList.Add(new MimeKit.MailboxAddress(item.FullName, item.EMail));

                }
            }
            #endregion

            #region 确保 邮件Html存在 

            //邮件附件
            var path = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, _userInfo.IsEn_Us ? emailConfig.AttachPath : emailConfig.AttachCNPath);

            if (!File.Exists(path))
            {
                //---找不到该项目标准场景下邮件模板
                throw new BusinessValidationFailedException(_localizer["TrialEmailN_EmailTemplateNotFound"]);
            }


            var pathToFile = _hostEnvironment.WebRootPath
                      + Path.DirectorySeparatorChar.ToString()
                      + "EmailTemplate"
                      + Path.DirectorySeparatorChar.ToString()
                     //+ "SubjectEnrollConfirmOrPDProgress.html";
                     + (_userInfo.IsEn_Us ? "SubjectEnrollConfirmOrPDProgress_US.html" : "SubjectEnrollConfirmOrPDProgress.html");

            #endregion


            #region 不同场景 Tile 设置

            if (businessScenarioEnum == EmailBusinessScenario.EnrollConfirmed)
            {
                sendEmailConfig.TopicDescription = _localizer["TrialEmailN_EnrollmentConfirmation", taskInfo.ResearchProgramNo, taskInfo.SubjectCode];

                using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))
                {
                    var templateInfo = SourceReader.ReadToEnd();


                    sendEmailConfig.HtmlBodyStr = string.Format(templateInfo,
                        //--- 附件为疾病进展确认报告，请查收 
                        _localizer["TrialEmailN_SubjectDiseaseProgression"]
                        );
                }
            }
            else if (businessScenarioEnum == EmailBusinessScenario.PDConfirmed)
            {
                sendEmailConfig.TopicDescription = _localizer["TrialEmailN_PDReport", taskInfo.ResearchProgramNo, taskInfo.SubjectCode];

                using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))
                {
                    var templateInfo = SourceReader.ReadToEnd();


                    sendEmailConfig.HtmlBodyStr = string.Format(templateInfo,
                        //--- 附件为疾病进展确认报告，请查收 
                        _localizer["TrialEmailN_SubjectDiseaseProgression"]
                        );
                }
            }
            else
            {
                //
            }

            #endregion


            #region 不同标准 不同项目配置 发送邮件的时机 处理具体逻辑

            var answer = "否";
            var isNeedSend = true;
            var minUserIdList = _trialUserRepository.Where(t => t.User.UserTypeEnum == Domain.Share.UserTypeEnum.MIM && t.TrialId == taskInfo.TrialId).Select(t => t.UserId).ToList();



            //入组确认  根据每个标准配置的是否自动发送，发送邮件与否
            if (businessScenarioEnum == EmailBusinessScenario.EnrollConfirmed)
            {
                if (await _repository.Where<ReadingTableQuestionAnswer>().AnyAsync(x => x.VisitTaskId == visitTaskId && x.Answer == TargetState.Exist.GetEnumInt() &&
             x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State && x.ReadingQuestionTrial.LesionType == LesionType.TargetLesion))
                {
                    answer = "是";
                }


                //如果其他阅片人已经做了，说明发送了入组确认报告，第二个人做完就不发送了

                //入组确认一直交给第一个人，如果第一个人重阅 还未做完，第二个人先做完了，此时不发

                var existFirstEnrollTask = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && t.IsAnalysisCreate == false
                && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId).OrderBy(t => t.SignTime).FirstOrDefaultAsync();

                //入组确认的医生已确定
                if ((existFirstEnrollTask != null) && (taskInfo.DoctorUserId != existFirstEnrollTask.DoctorUserId))
                {
                    isNeedSend = false;
                }
                else
                {
                    isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, new List<Guid>() { visitTaskId }, minUserIdList);


                    if (answer == "是")
                    {
                        //把另外一个人的任务设置为不加急（如果项目加急是否  subject 加急是否）
                        var urgent = _repository.Where<SubjectVisit>(t => t.Id == taskInfo.SourceSubjectVisitId).Select(t => new { IsSubjectUrgent = t.Subject.IsUrgent, t.Trial.IsUrgent }).FirstOrDefault();

                        if (urgent?.IsUrgent == false || urgent?.IsSubjectUrgent == false)
                        {
                            await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false &&
                    t.Id != visitTaskId && t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId, u => new VisitTask() { IsUrgent = false });
                        }
                    }


                }




            }
            else if (businessScenarioEnum == EmailBusinessScenario.PDConfirmed)
            {


                //有序

                if (taskInfo.IsReadingTaskViewInOrder)
                {



                    //双重
                    if (taskInfo.ReadingType == ReadingMethod.Double)
                    {


                        //仲裁在访视上   就没有全局阅片 没有阅片期
                        if (taskInfo.ArbitrationRule == ArbitrationRule.Visit)
                        {
                            //找到 访视，裁判 所有有效任务(不可能有全局的)   访视和裁判任务的SourceSubjectVisitId 一样
                            var taskList = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect &&
                            (t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Judge)).ToListAsync();


                            //这里要求 到这里已经如果有裁判  已经生成裁判了保存数据库
                            //双人阅片，没有产生裁判 第二个人读完发
                            if (taskList.Count == 2 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit) == 2)
                            {

                                answer = await TranslatePdStateAsync(visitTaskId, taskInfo.ReadingCategory, taskInfo.CriterionType);


                                isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Select(t => t.Id).ToList(), minUserIdList);

                            }
                            //双人  产生裁判，并且裁判完成 发
                            else if (taskList.Count == 3 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned) == 3 && taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Count() == 1)
                            {
                                var judgeResultId = taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).First().JudgeResultTaskId.Value;
                                answer = await TranslatePdStateAsync(judgeResultId, ReadingCategory.Visit, taskInfo.CriterionType);

                                isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Select(t => t.Id).ToList(), minUserIdList);

                            }
                            else
                            {
                                isNeedSend = false;

                            }




                        }
                        //仲裁在阅片期   
                        else if (taskInfo.ArbitrationRule == ArbitrationRule.Reading)
                        {
                            //是访视任务  不可能是裁判任务（访视上不会生成裁判），也不会是全局任务（全局任务 SourceSubjectVisitId=null ）
                            if (taskInfo.SourceSubjectVisitId != null)
                            {

                                //访视类型的任务  根本就不需要发送邮件

                                isNeedSend = false;

                            }
                            //是全局任务 或者全局的裁判任务   (如果是全局任务，那么此时裁判任务已经生成)
                            else if (taskInfo.SouceReadModuleId != null)
                            {
                                var taskList = await _visitTaskRepository.Where(t => t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect && t.SouceReadModuleId == taskInfo.SouceReadModuleId
                                && (t.ReadingCategory == ReadingCategory.Global || t.ReadingCategory == ReadingCategory.Judge)).ToListAsync();

                                //两个全局没有裁判
                                if (taskList.Count == 2 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Global) == 2)
                                {

                                    answer = await TranslatePdStateAsync(visitTaskId, taskInfo.ReadingCategory, taskInfo.CriterionType);

                                    isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Select(t => t.Id).ToList(), minUserIdList);
                                }
                                //双人全局产生裁判
                                else if (taskList.Count == 3 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned) == 3 && taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Count() == 1 && taskList.Where(t => t.ReadingCategory == ReadingCategory.Global).Count() == 2)
                                {

                                    var judgeResultId = taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).First().JudgeResultTaskId.Value;
                                    answer = await TranslatePdStateAsync(judgeResultId, ReadingCategory.Global, taskInfo.CriterionType);

                                    isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Select(t => t.Id).ToList(), minUserIdList);

                                }
                                else
                                {
                                    isNeedSend = false;

                                }
                            }
                            else
                            {
                                //---发送PD 进展邮件中发现任务数据有问题！
                                throw new BusinessValidationFailedException(_localizer["TrialEmailN_PDProgressEmailTask"]);
                            }



                        }
                        else
                        {

                            //---双重有序阅片 没有定义该仲裁规则处理逻辑，请联系业务和后台开发核查！
                            throw new BusinessValidationFailedException(_localizer["TrialEmailN_DoubleBlindedError"]);
                        }


                    }

                    //屏蔽单重阅片添加
                    else
                    {
                        isNeedSend = false;
                        return string.Empty;
                    }

                    #region 发邮件屏蔽单重的
                    ////单重
                    //else if (taskInfo.ReadingType == ReadingMethod.Single)
                    //{
                    //    //仲裁在访视上   或者在阅片期
                    //    if (taskInfo.ArbitrationRule != ArbitrationRule.None)
                    //    {

                    //---单重有序阅片配置有误(不应该有仲裁对象配置)，请核查！
                    //        throw new BusinessValidationFailedException(_localizer["TrialEmailN_SingleBlindedSet"]);
                    //    }


                    //    //要求PD 确认的访视  是截止访视 还是非截止访视(根据该访视有没有配置阅片期来判断)

                    //    if (taskInfo.ReadingCategory == ReadingCategory.Visit)
                    //    {
                    //        //存在阅片期  那么就是截止访视
                    //        if (await _repository.Where<ReadModule>(t => t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.SubjectVisitId == taskInfo.SourceSubjectVisitId && t.ReadingSetType == ReadingSetType.ImageReading).AnyAsync())
                    //        {
                    //            isNeedSend = false;
                    //        }
                    //        else//非截止访视 在访视读完后，发送
                    //        {
                    //            answer = await TranslatePdStateAsync(visitTaskId, ReadingCategory.Visit, taskInfo.CriterionType);
                    //        }
                    //    }
                    //    //截止访视  在访视读完，并完成全局阅片后发送全局的结果
                    //    else if (taskInfo.ReadingCategory == ReadingCategory.Global)
                    //    {
                    //        answer = await TranslatePdStateAsync(visitTaskId, ReadingCategory.Global, taskInfo.CriterionType);
                    //    }
                    //    else
                    //    {
                    //---单重有序阅片 该类型的任务不应进入此处逻辑，请联系后台开发核查！
                    //        throw new BusinessValidationFailedException(_localizer["TrialEmailN_SingleBlindedSequenced"]);
                    //    }

                    //    isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, new List<Guid>() { visitTaskId }, minUserIdList);


                    //}
                    //else
                    //{
                    //---有序阅片配置有误(应为单重或者双重阅片)，请核查！
                    //    throw new BusinessValidationFailedException(_localizer["TrialEmailN_BlindedSequencedReading"]);
                    //}

                    #endregion




                }
                //屏蔽无序阅片添加
                else
                {
                    isNeedSend = false;
                    return string.Empty;
                }

                #region 发送邮件屏蔽无序的
                //    //无序
                //else
                //{
                //    //单重


                //    if (taskInfo.ReadingType == ReadingMethod.Single && taskInfo.ArbitrationRule == ArbitrationRule.None)
                //    {
                //        answer = await TranslatePdStateAsync(visitTaskId, taskInfo.ReadingCategory, taskInfo.CriterionType);

                //        isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, new List<Guid>() { visitTaskId }, minUserIdList);
                //    }
                //    //双重  截止访视只在阅片期的时候存在  要求PD确认的访视 肯定是非截止访视
                //    else if (taskInfo.ReadingType == ReadingMethod.Double && taskInfo.ArbitrationRule == ArbitrationRule.Visit)
                //    {
                //        //在两位阅片人读完访视后，如果有裁判者等裁判读完，如果无裁判则等第二个人的读完

                //        var taskList = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect
                //        && (t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Judge)).ToListAsync();

                //        //这里要求 到这里已经如果有裁判  已经生成裁判了保存数据库
                //        if (taskList.Count == 2 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit) == 2)
                //        {

                //            answer = await TranslatePdStateAsync(visitTaskId, taskInfo.ReadingCategory, taskInfo.CriterionType);

                //            isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Select(t => t.Id).ToList(), minUserIdList);
                //        }
                //        else if (taskList.Count == 3 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned) == 3 && taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Count() == 1)
                //        {
                //            var judgeResultId = taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).First().JudgeResultTaskId.Value;
                //            answer = await TranslatePdStateAsync(judgeResultId, ReadingCategory.Visit, taskInfo.CriterionType);

                //            isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Select(t => t.Id).ToList(), minUserIdList);


                //        }
                //        else
                //        {
                //            isNeedSend = false;
                //        }

                //    }
                //    else
                //    {
                //---无序阅片配置有误(应为单重无仲裁对象，双重针对访视仲裁)，请核查！
                //        throw new BusinessValidationFailedException(_localizer["TrialEmailN_UnblindedSequencedReading"]);
                //    }

                //}

                #endregion
            }
            else
            {
                isNeedSend = false;
            }

            #endregion


            #region MiniWord 组织字典 发送


            if (emailStoreMode == EmailStoreSendMode.NotStoreLocalOnlySentEmail)
            {

                var phyPath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, sendFileRelativePath);


                //先预先生成了邮件，发送预先生成的邮件
                sendEmailConfig.EmailAttachMentConfigList.Add(new EmailAttachMentConfig()
                {
                    FileName = $"{taskInfo.SubjectCode}_{Path.GetFileNameWithoutExtension(_userInfo.IsEn_Us ? emailConfig.AttachName : emailConfig.AttachNameCN)}.pdf",

                    FileStream = File.OpenRead(phyPath),
                });


                await SendEmailHelper.SendEmailAsync(sendEmailConfig);

                return string.Empty;
            }

            var value = new Dictionary<string, object>()
            {
                ["SponsorName"] = taskInfo.SponsorName,
                ["ResearchProgramNo"] = taskInfo.ResearchProgramNo,
                ["TrialSiteCode"] = taskInfo.TrialSiteCode,
                ["SubjectCode"] = taskInfo.SubjectCode,
                ["VisitName"] = taskInfo.SourceSubjectVisitId != null ? taskInfo.VisitName : taskInfo.ModuleVisitName,
                ["EarliestScanDate"] = taskInfo.SourceSubjectVisitId != null ? taskInfo.VisitEarliestScanDate?.ToString("yyyy-MM-dd") : taskInfo.ModuleEarliestScanDate?.ToString("yyyy-MM-dd"),
                ["SignTime"] = taskInfo.SignTime?.ToString("yyyy-MM-dd"),
                ["Result"] = answer

            };

            var (serverFilePath, relativePath, fileRealName) = FileStoreHelper.GetSubjectEnrollConfirmOrPDEmailPath(_hostEnvironment, Path.GetFileName(path), taskInfo.TrialId, taskInfo.SiteId, taskInfo.SubjectId, true);

            if (emailStoreMode == EmailStoreSendMode.StoreLocalSend || emailStoreMode == EmailStoreSendMode.OnlyStoreLocalNotSentEmail)
            {

                MemoryStream wordMemoryStream = new MemoryStream();

                Document document = new Document();

                MiniSoftware.MiniWord.SaveAsByTemplate(wordMemoryStream, path, value);

                document.LoadFromStream(wordMemoryStream, FileFormat.Docx);

                document.SaveToFile(serverFilePath, FileFormat.PDF);


            }
            //手动生成发送的邮件内容，但是并不发送
            if (emailStoreMode == EmailStoreSendMode.OnlyStoreLocalNotSentEmail)
            {
                isNeedSend = false;

                return relativePath;
            }


            //正常的即时生成邮件  并发送邮件
            if (isNeedSend)
            {


                MemoryStream memoryStream = new MemoryStream();
                MemoryStream pdfMemoryStream = new MemoryStream();


                MiniSoftware.MiniWord.SaveAsByTemplate(memoryStream, path, value);
                Document document = new Document();

                document.LoadFromStream(memoryStream, FileFormat.Docx);
                document.SaveToStream(pdfMemoryStream, FileFormat.PDF);
                pdfMemoryStream.Seek(0, SeekOrigin.Begin);

                sendEmailConfig.EmailAttachMentConfigList.Add(new EmailAttachMentConfig()
                {
                    FileName = $"{taskInfo.SubjectCode}_{Path.GetFileNameWithoutExtension(_userInfo.IsEn_Us ? emailConfig.AttachName : emailConfig.AttachNameCN)}.pdf",

                    FileStream = pdfMemoryStream
                });


                await SendEmailHelper.SendEmailAsync(sendEmailConfig);

            }



            return string.Empty;





            #endregion


        }



        /// <summary>
        /// 手动生成入组确认 或者PD 进展的邮件   如果能发送，会返回文件的路径，否则会给出提示
        /// </summary>
        /// <param name="generateEmailCommand"></param>

        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> ManualGenerateEmailFile(GenerateEmailCommand generateEmailCommand)
        {
            var subjectId = generateEmailCommand.SubjectId;
            var businessScenarioEnum = generateEmailCommand.BusinessScenarioEnum;
            var trialReadingCriterionId = generateEmailCommand.TrialReadingCriterionId;


            var trialConfig = await _subjectRepository.Where(t => t.Id == subjectId).Select(t => new { t.Trial.IsEnrollementQualificationConfirm, t.Trial.IsPDProgressView }).FirstNotNullAsync();

            //找到入组确认 或者Pd 进展   已生成任务的  访视
            var subjectVisitList = await _subjectVisitRepository.Where(t => t.SubjectId == subjectId & t.CheckState == CheckStateEnum.CVPassed && (t.IsEnrollmentConfirm == true || t.PDState == PDStateEnum.PDProgress)).ToListAsync();

            if (businessScenarioEnum == EmailBusinessScenario.EnrollConfirmed)
            {

                if (trialConfig.IsEnrollementQualificationConfirm == false)
                {
                    //---项目未配置入组确认！
                    return ResponseOutput.NotOk(_localizer["TrialEmailN_InCons"]);

                }
                var exisitBaseline = subjectVisitList.FirstOrDefault(t => t.IsEnrollmentConfirm);
                if (exisitBaseline == null)
                {
                    //---不存在配置了入组确认的并且生成任务的基线访视
                    return ResponseOutput.NotOk(_localizer["TrialEmailN_NoBaseLine"]);
                }
                else
                {
                    //入组确认不用管项目的 有序 无序  单重  双重  阅片

                    //找到最早签名的
                    var firstSignTask = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == exisitBaseline.Id /*&& t.TaskState == TaskState.Effect*/ && t.IsAnalysisCreate == false
                                                           && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.TrialReadingCriterionId == trialReadingCriterionId).OrderBy(t => t.SignTime).FirstOrDefaultAsync();


                    if (firstSignTask != null)
                    {
                        var task = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == exisitBaseline.Id && t.TaskState == TaskState.Effect && t.DoctorUserId == firstSignTask.DoctorUserId && t.IsAnalysisCreate == false
                                                         && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.TrialReadingCriterionId == trialReadingCriterionId).OrderBy(t => t.SignTime).FirstOrDefaultAsync();

                        //如果存在做完的该任务

                        if (task == null)
                        {
                            //---做入组确认的阅片人基线任务没有阅片完！
                            return ResponseOutput.NotOk(_localizer["TrialEmailN_IncompBase"]);
                        }
                        else
                        {
                            var filePath = await BaseBusinessScenarioSendEmailAsync(task.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty);

                            if (string.IsNullOrEmpty(filePath))
                            {
                                //---邮件手动生成失败，请联系开发核实该场景失败原因
                                return ResponseOutput.NotOk(_localizer["TrialEmailN_EmailFail"]);
                            }
                            else
                            {
                                return ResponseOutput.Ok(new { RelativePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id });

                            }


                        }
                    }
                    else
                    {
                        //---当前未有阅片人读完基线任务！
                        return ResponseOutput.NotOk(_localizer["TrialEmailN_NoReader"]);
                    }





                }
            }

            else if (businessScenarioEnum == EmailBusinessScenario.PDConfirmed)
            {

                if (trialConfig.IsPDProgressView == false)
                {
                    //---项目未配置PD进展！
                    return ResponseOutput.NotOk(_localizer["TrialEmailN_NoPDConfig"]);
                }

                //是否是截止访视 截止访视在全局发  否则就在当前访视发

                var pdSubjectVisitIdList = subjectVisitList.Where(t => t.PDState == PDStateEnum.PDProgress).OrderBy(t => t.VisitNum).Select(t => (Guid?)t.Id).ToList();

                if (pdSubjectVisitIdList.Count == 0)
                {
                    //---不存在配置了PD进展的并且生成任务的访视
                    return ResponseOutput.NotOk(_localizer["TrialEmailN_NoPDTasks"]);
                }


                var currentLatestPdVisitId = pdSubjectVisitIdList.Last();
                //标准配置
                var trialReadingCriterionConfig = await _repository.Where<ReadingQuestionCriterionTrial>(t => t.Id == trialReadingCriterionId).Select(t => new
                { TrialReadingCriterionId = t.Id, t.ReadingType, t.IsReadingTaskViewInOrder, t.CriterionType, t.ArbitrationRule }).FirstNotNullAsync();

                // 项目双重
                if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Double && trialReadingCriterionConfig.IsReadingTaskViewInOrder)
                {
                    //仲裁在访视上面
                    if (trialReadingCriterionConfig.ArbitrationRule == ArbitrationRule.Visit)
                    {
                        //在两位阅片人读完访视后，如果有裁判者等裁判读完，如果无裁判则等第二个人的读完

                        var taskList = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == currentLatestPdVisitId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false
                        && t.TaskState == TaskState.Effect && (t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Judge)).ToListAsync();

                        var totalTaskCount = taskList.Count;
                        var finishedCount = taskList.Where(t => t.ReadingTaskState == ReadingTaskState.HaveSigned).Count();


                        //发送随访的
                        if (totalTaskCount == 2 && totalTaskCount == finishedCount)
                        {
                            var task = taskList.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Visit);

                            var filePath = await BaseBusinessScenarioSendEmailAsync(task.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty);

                            return ResponseOutput.Ok(new { RelativePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id });
                        }
                        //发送全局
                        else if (totalTaskCount == 3 && totalTaskCount == finishedCount)
                        {
                            var task = taskList.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Judge);

                            var filePath = await BaseBusinessScenarioSendEmailAsync(task.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty);

                            return ResponseOutput.Ok(new { RelativePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id });
                        }
                        else
                        {
                            //---当前受试者最新PD访视阅片任务完成状态不符合发送条件
                            return ResponseOutput.NotOk(_localizer["TrialEmailN_PDNotFinished"]);
                        }

                    }
                    //仲裁在阅片期上
                    else if (trialReadingCriterionConfig.ArbitrationRule == ArbitrationRule.Reading)
                    {
                        var existReadModule = await _repository.Where<ReadModule>(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.SubjectVisitId == currentLatestPdVisitId && t.ReadingSetType == ReadingSetType.ImageReading)
                        .FirstOrDefaultAsync();

                        if (existReadModule == null)
                        {
                            //---项目配置了阅片期仲裁，但是当前受试者最新PD访视没有影像学阅片期
                            return ResponseOutput.NotOk(_localizer["TrialEmailN_PDNoImaging"]);
                        }
                        else
                        {
                            var taskList = await _visitTaskRepository.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect && t.SouceReadModuleId == existReadModule.Id
                             && (t.ReadingCategory == ReadingCategory.Global || t.ReadingCategory == ReadingCategory.Judge)).ToListAsync();

                            var totalTaskCount = taskList.Count;
                            var finishedCount = taskList.Where(t => t.ReadingTaskState == ReadingTaskState.HaveSigned).Count();



                            //发送全局的
                            if (totalTaskCount == 2 && totalTaskCount == finishedCount)
                            {
                                var task = taskList.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Global);

                                var filePath = await BaseBusinessScenarioSendEmailAsync(task.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty);

                                return ResponseOutput.Ok(new { RelativePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id });
                            }
                            //发送全局裁判的
                            else if (totalTaskCount == 3 && totalTaskCount == finishedCount)
                            {
                                var task = taskList.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Judge);

                                var filePath = await BaseBusinessScenarioSendEmailAsync(task.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty);

                                return ResponseOutput.Ok(new { RelativePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id });
                            }


                            else
                            {
                                //---当前受试者最新PD访视阅片期任务完成状态不符合发送条件
                                return ResponseOutput.NotOk(_localizer["TrialEmailN_PDPhaseNotFinished"]);
                            }
                        }


                    }
                    else
                    {
                        //---未定义该仲裁规则发送业务逻辑！
                        return ResponseOutput.NotOk(_localizer["TrialEmailN_NoRuleDefined"]);
                    }
                }

                #region 发送邮件屏蔽单重阅片情况
                //// 项目单重   判断最新的Pd 访视是否完成 是否有阅片期即可  
                //else if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Single)
                //{



                //    var task = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == currentLatestPdVisitId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false
                //                                         && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.TrialReadingCriterionId == trialReadingCriterionId).FirstOrDefaultAsync();


                //    if (task == null)
                //    {
                //        return ResponseOutput.NotOk("当前受试者最新PD访视任务未阅片完成");
                //    }
                //    else
                //    {
                //        //存在阅片期  那么就是截止访视

                //        var existReadModule = await _repository.Where<ReadModule>(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.SubjectVisitId == currentLatestPdVisitId && t.ReadingSetType == ReadingSetType.ImageReading)
                //            .FirstOrDefaultAsync();
                //        if (existReadModule != null)
                //        {

                //            var global = await _visitTaskRepository.Where(t => t.SouceReadModuleId == currentLatestPdVisitId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false
                //                                                && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.TrialReadingCriterionId == trialReadingCriterionId).FirstOrDefaultAsync();


                //            if (global != null)
                //            {
                //                var filePath = await BaseBusinessScenarioSendEmailAsync(global.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty);

                //                return ResponseOutput.Ok(new { RelativePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id });
                //            }
                //            else
                //            {
                //                return ResponseOutput.NotOk("当前受试者阅片期任务未阅片完成");
                //            }

                //        }
                //        else//非截止访视 在访视读完后，发送
                //        {
                //            var filePath = await BaseBusinessScenarioSendEmailAsync(task.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty);

                //            return ResponseOutput.Ok(new { RelativePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id });
                //        }
                //    }


                //}
                #endregion

                else
                {
                    //---当前项目配置，不满足双重有序阅片，不满足发送条件！
                    return ResponseOutput.NotOk(_localizer["TrialEmailN_NoDoubleOrder"]);
                }

            }

            else
            {
                //---当前项目配置，未定义发送业务逻辑！
                return ResponseOutput.NotOk(_localizer["TrialEmailN_NoSendLogicDefined"]);
            }




        }

        /// <summary>
        /// 手动发送邮件
        /// </summary>
        /// <param name="visitTaskId"></param>
        /// <param name="sendFileRelativePath"></param>
        /// <returns></returns>
        [HttpPut]
        public async Task<IResponseOutput> ManualSendEmail(Guid visitTaskId, string sendFileRelativePath)
        {
            var filePath = await BaseBusinessScenarioSendEmailAsync(visitTaskId, true, EmailStoreSendMode.NotStoreLocalOnlySentEmail, sendFileRelativePath);

            return ResponseOutput.Ok();

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="visitTaskId"> 任务Id</param>
        /// <param name="readingCategory"> 任务类型</param>
        /// <param name="criterionType">标准类型</param>
        /// <param name="IsGlobalGenerate">  是否是全局产生（区分裁判任务）</param>
        /// <returns></returns>
        /// <exception cref="BusinessValidationFailedException"></exception>
        private async Task<string> TranslatePdStateAsync(Guid visitTaskId, ReadingCategory readingCategory, CriterionType criterionType, bool? IsGlobalGenerate = null)
        {

            var answer = string.Empty;

            ReadingTaskQuestionAnswer visitQuestionAnswer = null;

            ReadingTaskQuestionAnswer globalQuestionAnswer = null;



            switch (criterionType)
            {


                case CriterionType.RECIST1Point1:

                    if (readingCategory == ReadingCategory.Visit)
                    {

                        visitQuestionAnswer = await _repository.Where<ReadingTaskQuestionAnswer>(t => t.VisitTaskId == visitTaskId && t.ReadingQuestionTrial.QuestionType == QuestionType.Tumor).FirstNotNullAsync();


                        answer = visitQuestionAnswer.Answer;
                    }
                    else if (readingCategory == ReadingCategory.Global)
                    {
                        var questionAnsewer = await _repository.Where<ReadingGlobalTaskInfo>(t => t.GlobalTaskId == visitTaskId && t.TrialReadingQuestion.QuestionType == QuestionType.Tumor).OrderByDescending(c => c.VisitTask.VisitTaskNum).FirstNotNullAsync();


                        answer = questionAnsewer.Answer;
                        if (string.IsNullOrEmpty(questionAnsewer.Answer))
                        {
                            answer = await _repository.Where<ReadingTaskQuestionAnswer>(t => questionAnsewer.TaskId == t.VisitTaskId && t.ReadingQuestionTrial.QuestionType == QuestionType.Tumor)
                         .Select(t => t.Answer).FirstOrDefaultAsync();
                        }

                    }
                    //else if (readingCategory == ReadingCategory.Judge)
                    //{
                    //    var judgeResultTaskId = await _visitTaskRepository.Where(t => t.Id == visitTaskId).Select(t => t.JudgeResultTaskId).FirstNotNullAsync();

                    //    var questionAnsewer = await _repository.Where<ReadingTaskQuestionAnswer>(t => t.VisitTaskId == judgeResultTaskId && t.ReadingQuestionTrial.QuestionType == QuestionType.Tumor).FirstNotNullAsync();


                    //    answer = questionAnsewer.Answer;
                    //}
                    else
                    {
                        //---不应有 除访视、裁判、全局其他类型的任务进行发送邮件，请核查业务逻辑
                        throw new BusinessValidationFailedException(_localizer["TrialEmailN_InvalidTaskTypeForEmailSending"]);
                    }

                    if (answer == OverallAssessment.PD.GetEnumInt())
                    {
                        answer = "是";
                    }
                    else
                    {
                        answer = "否";
                    }

                    break;

                case CriterionType.PCWG3:
                    if (readingCategory == ReadingCategory.Visit)
                    {

                        visitQuestionAnswer = await _repository.Where<ReadingTaskQuestionAnswer>(t => t.VisitTaskId == visitTaskId && t.ReadingQuestionTrial.QuestionType == QuestionType.SiteVisitForTumorEvaluation).FirstNotNullAsync();


                        answer = visitQuestionAnswer.Answer;
                    }
                    else if (readingCategory == ReadingCategory.Global)
                    {
                        var questionAnsewer = await _repository.Where<ReadingGlobalTaskInfo>(t => t.TaskId == visitTaskId && t.TrialReadingQuestion.QuestionType == QuestionType.SiteVisitForTumorEvaluation).FirstNotNullAsync();

                        answer = questionAnsewer.Answer;
                    }
                    //else if (readingCategory == ReadingCategory.Judge)
                    //{
                    //    //var judgeResultTaskId = await _visitTaskRepository.Where(t => t.Id == visitTaskId).Select(t => t.JudgeResultTaskId).FirstNotNullAsync();

                    //    var questionAnsewer = await _repository.Where<ReadingTaskQuestionAnswer>(t => t.VisitTaskId == visitTaskId && t.ReadingQuestionTrial.QuestionType == QuestionType.SiteVisitForTumorEvaluation).FirstNotNullAsync();

                    //    answer = questionAnsewer.Answer;
                    //}
                    else
                    {
                        //---不应有 除访视、裁判、全局其他类型的任务进行发送邮件，请核查业务逻辑
                        throw new BusinessValidationFailedException(_localizer["TrialEmailN_InvalidTaskTypeForEmailSending"]);
                    }

                    if (answer == VisitTumorEvaluation.PD.GetEnumInt())
                    {
                        answer = "是";
                    }
                    if (answer == VisitTumorEvaluation.ND.GetEnumInt())
                    {
                        answer = "ND";
                    }
                    if (answer == VisitTumorEvaluation.NE.GetEnumInt())
                    {
                        answer = "NE";
                    }
                    else
                    {
                        answer = "否";
                    }
                    break;
                case CriterionType.SelfDefine:
                case CriterionType.mRECISTMesothelioma:
                case CriterionType.RECIL:
                case CriterionType.RECIST1Point0:
                case CriterionType.WHO:
                case CriterionType.PERCIST:
                case CriterionType.Forrest:
                case CriterionType.Lugano2014:
                case CriterionType.IRECIST1Point1:
                case CriterionType.RANO_BM:
                case CriterionType.RANO:
                case CriterionType.IWCLL2018:
                case CriterionType.mRECISTHCC:
                case CriterionType.Cheson2007:
                case CriterionType.IMWG2016:
                default:

                    //---该标准任务还未定义PD获取逻辑，联系业务和后台开发协商后补充
                    throw new BusinessValidationFailedException(_localizer["TrialEmailN_PDLogicNotDefined"]);
            }



            return answer;




        }


        /// <summary>
        /// 选择人员下拉
        /// </summary>
        /// <param name="trialId"></param>
        /// <returns></returns>
        public async Task<List<TrialUserType>> GetTrialUserTypeSelectList(Guid trialId)
        {

            var query = _trialUserRepository.Where(t => t.TrialId == trialId, false, true).IgnoreQueryFilters().Select(t => t.User.UserTypeRole).Distinct()

              .ProjectTo<TrialUserType>(_mapper.ConfigurationProvider);
               
            return await query.ToListAsync();

        }

        /// <summary>
        /// 黑名单用户Id  列表
        /// </summary>
        /// <param name="trialEmailNoticeConfigId"></param>
        /// <returns></returns>
        public async Task<List<TrialSelectUser>> GetTrialUserIdSelectList(Guid trialEmailNoticeConfigId)
        {

            var trialEmailNoticeConfig = await _trialEmailNoticeConfigRepository.Where(t => t.Id == trialEmailNoticeConfigId).Include(t => t.TrialEmailNoticeUserList).FirstNotNullAsync();

            var trialId = trialEmailNoticeConfig.TrialId;

            var userTypeList = trialEmailNoticeConfig.TrialEmailNoticeUserList.Select(t => t.UserType).ToList();


            var query = _trialUserRepository.Where(t => t.TrialId == trialId && userTypeList.Contains(t.User.UserTypeEnum), false, true).IgnoreQueryFilters()
                .Select(t => new TrialSelectUser()
                {
                    UserId = t.UserId,
                    UserName = t.User.UserName,
                    RealName = t.User.FullName,
                    UserTypeEnum = t.User.UserTypeEnum
                }).Distinct();

            return await query.ToListAsync();
        }

        /// <summary>
        /// 获取系统 邮件配置 勾选列表
        /// </summary>
        /// <param name="queryEmailNoticeConfig"></param>
        /// <returns></returns>
        public async Task<PageOutput<TrialSelectEmailNoticeConfigView>> GetSysEmailNoticeConfigList(EmailNoticeConfigQuery queryEmailNoticeConfig)
        {
            var emailNoticeConfigQueryable = _emailNoticeConfigRepository
           .WhereIf(queryEmailNoticeConfig.BusinessScenarioEnum != null, t => t.BusinessScenarioEnum == queryEmailNoticeConfig.BusinessScenarioEnum)
           .WhereIf(queryEmailNoticeConfig.IsReturnRequired != null, t => t.IsReturnRequired == queryEmailNoticeConfig.IsReturnRequired)
           .WhereIf(queryEmailNoticeConfig.IsEnable != null, t => t.IsEnable == queryEmailNoticeConfig.IsEnable)

           .ProjectTo<TrialSelectEmailNoticeConfigView>(_mapper.ConfigurationProvider, new { trialId = queryEmailNoticeConfig.TrialId });

            return await emailNoticeConfigQueryable.ToPagedListAsync(queryEmailNoticeConfig.PageIndex, queryEmailNoticeConfig.PageSize, queryEmailNoticeConfig.SortField, queryEmailNoticeConfig.Asc);
        }

        /// <summary>
        ///  批量勾选  传递列表每行数据，后台进行处理转换，建立关联关系
        /// </summary>
        /// <param name="batchAddList"></param>
        /// <returns></returns>
        public async Task<IResponseOutput> BatchAddSysEmailConfig(List<BatchAddTrialEmailNoticeConfig> batchAddList)
        {

            var first = batchAddList.First();
            var trialId = first.TrialId;

            var emailConfig = await _trialRepository.Where(t => t.Id == trialId).Select(x => new
            {
                TrialId = x.Id,
                EmailAuthorizationCode = x.EmailAuthorizationCode,
                EmailSMTPServerAddress = x.EmailSMTPServerAddress,
                EmailFromEmail = x.EmailFromEmail,
                EmailFromName = x.EmailFromName,
                IsConfigureEmail = x.IsConfigureEmail,
                EmailSMTPServerPort = x.EmailSMTPServerPort

            }).FirstNotNullAsync();

            var list = await _repository.Where<ReadingQuestionCriterionTrial>(t => t.TrialId == trialId && t.IsConfirm).Select(t => new { t.CriterionType, TrialReadingCriterionId = t.Id }).ToListAsync();


            var addList = _mapper.Map<List<TrialEmailNoticeConfig>>(batchAddList);


            foreach (var item in addList)
            {
                item.SysEmailNoticeConfigId = item.Id;
                item.Id = Guid.Empty;

                item.AuthorizationCode = emailConfig.EmailAuthorizationCode;
                item.FromEmail = emailConfig.EmailFromEmail;
                item.SMTPServerAddress = emailConfig.EmailSMTPServerAddress;
                item.FromName=emailConfig.EmailFromName;
                item.SMTPServerPort = emailConfig.EmailSMTPServerPort;
                item.IsAutoSend = false;
                item.IsEnable = false;

                item.TrialReadingCriterionId = list.FirstOrDefault(t => t.CriterionType == item.CriterionTypeEnum)?.TrialReadingCriterionId;

                item.TrialEmailNoticeUserList.AddRange(batchAddList.Where(t => t.Id == item.SysEmailNoticeConfigId)
                    .SelectMany(t => t.ToUserTypeList).Select(t => new TrialEmailNoticeUser() { EmailUserType = EmailUserType.To, UserType = t }));

                item.TrialEmailNoticeUserList.AddRange(batchAddList.Where(t => t.Id == item.SysEmailNoticeConfigId)
                   .SelectMany(t => t.CopyUserTypeList).Select(t => new TrialEmailNoticeUser() { EmailUserType = EmailUserType.Copy, UserType = t }));


                await _trialEmailNoticeConfigRepository.AddAsync(item);

            }

            await _trialEmailNoticeConfigRepository.SaveChangesAsync();

            return ResponseOutput.Ok();


        }


        [HttpPost]
        public async Task<List<TrialEmailNoticeConfigView>> GetTrialEmailNoticeConfigList(TrialEmailNoticeConfigQuery inQuery)
        {
            //await SyncSystemEmainCofigDocListAsync(inQuery.TrialId);

            var trialEmailNoticeConfigQueryable = _trialEmailNoticeConfigRepository.Where(t => t.TrialId == inQuery.TrialId)
              .WhereIf(inQuery.IsDistinguishCriteria == false, t => t.TrialReadingCriterionId == null)
               .WhereIf(inQuery.IsDistinguishCriteria == true, t => t.CriterionTypeEnum != null)
              .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
              .WhereIf(inQuery.BusinessScenarioEnum != null, t => t.BusinessScenarioEnum == inQuery.BusinessScenarioEnum)
              .ProjectTo<TrialEmailNoticeConfigView>(_mapper.ConfigurationProvider);

            return await trialEmailNoticeConfigQueryable.ToListAsync();
        }


        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
        public async Task<IResponseOutput> AddOrUpdateTrialEmailNoticeConfig(TrialEmailNoticeConfigAddOrEdit addOrEditTrialEmailNoticeConfig)
        {
            await TestEmailConfigAsync(addOrEditTrialEmailNoticeConfig);


            if (addOrEditTrialEmailNoticeConfig.Id == null)
            {

                var entity = _mapper.Map<TrialEmailNoticeConfig>(addOrEditTrialEmailNoticeConfig);


                foreach (var item in addOrEditTrialEmailNoticeConfig.ToUserTypeList)
                {
                    entity.TrialEmailNoticeUserList.Add(new TrialEmailNoticeUser() { EmailUserType = EmailUserType.To, UserType = item });

                }

                foreach (var item in addOrEditTrialEmailNoticeConfig.CopyUserTypeList)
                {
                    entity.TrialEmailNoticeUserList.Add(new TrialEmailNoticeUser() { EmailUserType = EmailUserType.Copy, UserType = item });

                }

                foreach (var userid in addOrEditTrialEmailNoticeConfig.BlackUserIdList)
                {
                    entity.TrialEmailBlackUserList.Add(new TrialEmailBlackUser() { UserId = userid });
                }

                await _trialEmailNoticeConfigRepository.AddAsync(entity, true);

                return ResponseOutput.Ok(entity.Id.ToString());

            }
            else
            {
                var id = (Guid)addOrEditTrialEmailNoticeConfig.Id;

                await _repository.BatchDeleteAsync<TrialEmailNoticeUser>(t => t.TrialEmailNoticeConfigId == addOrEditTrialEmailNoticeConfig.Id);
                await _repository.BatchDeleteAsync<TrialEmailBlackUser>(t => t.TrialEmailNoticeConfigId == addOrEditTrialEmailNoticeConfig.Id);


                List<TrialEmailNoticeUser> trialEmailNoticeUsers = new List<TrialEmailNoticeUser>();


                foreach (var item in addOrEditTrialEmailNoticeConfig.ToUserTypeList)
                {
                    trialEmailNoticeUsers.Add(new TrialEmailNoticeUser() { EmailUserType = EmailUserType.To, UserType = item, TrialEmailNoticeConfigId = id });

                }

                foreach (var item in addOrEditTrialEmailNoticeConfig.CopyUserTypeList)
                {
                    trialEmailNoticeUsers.Add(new TrialEmailNoticeUser() { EmailUserType = EmailUserType.Copy, UserType = item, TrialEmailNoticeConfigId = id });

                }
                await _repository.AddRangeAsync(trialEmailNoticeUsers);

                foreach (var userid in addOrEditTrialEmailNoticeConfig.BlackUserIdList)
                {
                    await _trialEmailBlackUserRepository.AddAsync(new TrialEmailBlackUser() { UserId = userid, TrialEmailNoticeConfigId = id });

                }

                await _trialEmailNoticeConfigRepository.UpdateFromDTOAsync(addOrEditTrialEmailNoticeConfig);


                await _trialEmailNoticeConfigRepository.SaveChangesAsync();

                var jobId = $"{addOrEditTrialEmailNoticeConfig.TrialId}_{id}";

                if (addOrEditTrialEmailNoticeConfig.IsAutoSend)
                {
                    HangfireJobHelper.AddOrUpdateTrialCronJob(jobId, addOrEditTrialEmailNoticeConfig.TrialId, addOrEditTrialEmailNoticeConfig.BusinessScenarioEnum, addOrEditTrialEmailNoticeConfig.EmailCron);

                }
                else
                {
                    HangfireJobHelper.RemoveCronJob(jobId);
                }

                return ResponseOutput.Ok();
            }


        }



        private async Task TestEmailConfigAsync(TrialEmailNoticeConfigAddOrEdit config)
        {


            if (!config.FromEmail.Contains("@") || string.IsNullOrEmpty(config.FromEmail))
            {
                //---项目发件邮箱配置有误，请核实
                throw new BusinessValidationFailedException(_localizer["TrialEmailN_InvalidEmailConfig"]);
            }

            try
            {
                await SendEmailHelper.TestEmailConfigAsync(new SystemEmailSendConfig()
                {
                    AuthorizationCode = config.AuthorizationCode,
                    FromEmail = config.FromEmail,
                    FromName = config.FromName,
                    Host = config.SMTPServerAddress,
                    Port = config.SMTPServerPort
                });

            }
            catch (Exception ex)
            {

                //---发件人配置错误，请核对服务器地址或者授权码是否填写有误
                throw new BusinessValidationFailedException(_localizer["TrialEmailN_InvalidSenderEmailConfig"] + ex.Message);
            }




            #region 人员还未加入，可以先配置邮件  历史废弃

            //var toUserList = await _repository.Where<TrialUser>(t => t.TrialId == config.TrialId)
            //   .WhereIf(config.ToUserTypeList != null, t => config.ToUserTypeList.Contains(t.User.UserTypeEnum))
            //   .Select(t => new { t.User.EMail, t.User.FullName }).ToListAsync();


            //if (toUserList.Count() == 0 || toUserList.Where(t => t.EMail.Contains("@")).Count() == 0)
            //{
            //    //---项目没有有效的收件人，无法发送邮件
            //    throw new BusinessValidationFailedException(_localizer["TrialEmailN_InvalidRecipient"]);
            //}

            //var sendEmailConfig = new SMTPEmailConfig();

            //sendEmailConfig.FromEmailAddress = new MimeKit.MailboxAddress(config.FromName, config.FromEmail);
            //sendEmailConfig.AuthorizationCode = config.AuthorizationCode;
            //sendEmailConfig.UserName = config.FromEmail;

            //sendEmailConfig.Host = config.SMTPServerAddress;
            //sendEmailConfig.Port = config.SMTPServerPort;


            //sendEmailConfig.ToMailAddressList.Add(new MimeKit.MailboxAddress(config.FromName, config.FromEmail));


            //var pathToFile = _hostEnvironment.WebRootPath
            //          + Path.DirectorySeparatorChar.ToString()
            //          + "EmailTemplate"
            //          + Path.DirectorySeparatorChar.ToString()
            //         //+ "EmailConfigTest.html";

            //         + (_userInfo.IsEn_Us ? "EmailConfigTest_US.html" : "EmailConfigTest.html");


            ////---项目邮件测试
            //sendEmailConfig.TopicDescription = _localizer["TrialEmailN_EmailTestMessage"];

            //using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))
            //{
            //    var templateInfo = SourceReader.ReadToEnd();


            //    sendEmailConfig.HtmlBodyStr = string.Format(templateInfo,
            //    //--- 收到此邮件，代表邮件配置正确
            //        _localizer["TrialEmailN_ConfigurationCorrect"]
            //        );
            //}

            //try
            //{
            //    await SendEmailHelper.SendEmailAsync(sendEmailConfig);

            //}
            //catch (Exception ex)
            //{

            //    //---发件人配置错误，请核对服务器地址或者授权码是否填写有误
            //    throw new BusinessValidationFailedException(_localizer["TrialEmailN_InvalidSenderEmailConfig"] + ex.Message);
            //}

            #endregion


        }

        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
        [HttpDelete("{trialEmailNoticeConfigId:guid}")]
        public async Task<IResponseOutput> DeleteTrialEmailNoticeConfig(Guid trialEmailNoticeConfigId)
        {
            var trialId=await _trialEmailNoticeConfigRepository.Where(t=>t.Id==trialEmailNoticeConfigId).Select(t=>t.TrialId).FirstOrDefaultAsync();
            var jobId = $"{trialId}_{trialEmailNoticeConfigId}";

            HangfireJobHelper.RemoveCronJob(jobId);

            var success = await _trialEmailNoticeConfigRepository.DeleteFromQueryAsync(t => t.Id == trialEmailNoticeConfigId, true);

            return ResponseOutput.Ok();
        }


    }
}
