//--------------------------------------------------------------------
//     此代码由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;

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

        private readonly IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigRepository;

        public IRepository<VisitTask> _visitTaskRepository { get; }
        public IRepository<TrialUser> _trialUserRepository { get; }

        public TrialEmailNoticeConfigService(IRepository<TrialEmailNoticeConfig> trialEmailNoticeConfigRepository, IRepository<VisitTask> visitTaskRepository, IRepository<TrialUser> trialUserRepository)
        {
            _trialEmailNoticeConfigRepository = trialEmailNoticeConfigRepository;
            _visitTaskRepository = visitTaskRepository;
            _trialUserRepository = trialUserRepository;
        }


        /// <summary>
        /// 同步系统配置的文档到想项目中
        /// </summary>
        /// <param name="trialId"></param>
        /// <param name="criterionTypeEnum"></param>
        /// <returns></returns>
        /// 
        private async Task SyncSystemEmainCofigDocListAsync(Guid trialId, CriterionType? criterionTypeEnum)
        {
            if (criterionTypeEnum != null)
            {
                var docmentList = _repository.Where<CommonDocument>(t => t.CriterionTypeEnum == criterionTypeEnum).Select(t => new { t.Path, t.Name, t.Code, t.BusinessScenarioEnum }).ToList();

                var trialDocCount = _trialEmailNoticeConfigRepository.Where(t => t.CriterionTypeEnum == criterionTypeEnum && t.TrialId == trialId).Count();

                if (trialDocCount == 0)
                {

                    foreach (var item in docmentList)
                    {
                        await _trialEmailNoticeConfigRepository.AddAsync(new TrialEmailNoticeConfig() {  TrialId=trialId,  CriterionTypeEnum= criterionTypeEnum.Value,  FileName = item.Name, FilePath = item.Path, BusinessScenarioEnum = item.BusinessScenarioEnum, Code = item.Code });
                    }

                }

            }

            await _trialEmailNoticeConfigRepository.SaveChangesAsync();
        }



        /// <summary>
        /// 测试邮件 带附件 填充word --前端不需要用
        /// </summary>
        /// <param name="visitTaskId"></param>
        /// <returns></returns>
        /// <exception cref="BusinessValidationFailedException"></exception>
        public async Task BaseBusinessScenarioSendEmailAsync(Guid visitTaskId)
        {

            CommonDocumentBusinessScenario? 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.ReadingTaskState,
                t.ReadingCategory,
                t.SignTime,
                //仲裁规则
                t.TrialReadingCriterion.ArbitrationRule,
                //单双中
                t.TrialReadingCriterion.ReadingType,

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

                t.TrialId,




                t.TrialReadingCriterionId,
            }).FirstNotNullAsync();

            #endregion


            #region 任务 -邮件场景区分

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


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

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



            #endregion


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


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


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

                return;
            }


            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("没有收件人,无法发送邮件");
            }


            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("项目发件邮箱配置有误,请核实");
            }

            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, emailConfig.FilePath);

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


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

            #endregion



            var answer = "否";
            var isNeedSend = true;

            //入组确认  根据每个标准配置的是否自动发送,发送邮件与否
            if (businessScenarioEnum == CommonDocumentBusinessScenario.EnrollConfirmed)
            {
                //如果其他阅片人已经做了,说明发送了入组确认报告,第二个人做完就不发送了
                if (await _visitTaskRepository.AnyAsync(t => t.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false &&
                t.Id != visitTaskId && t.ReadingTaskState == ReadingTaskState.HaveSigned &&  t.TrialReadingCriterionId==taskInfo.TrialReadingCriterionId))
                {
                    isNeedSend = false;
                }
                else
                {
                    sendEmailConfig.TopicDescription = "入组确认";

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


                        sendEmailConfig.HtmlBodyStr = string.Format(templateInfo,
                            $" 附件为入组确认报告,请查收 "
                            );
                    }



                    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 = "是";
                    }
                }

               
            }
            else if (businessScenarioEnum == CommonDocumentBusinessScenario.PDConfirmed)
            {
                sendEmailConfig.TopicDescription = "疾病进展";

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


                    sendEmailConfig.HtmlBodyStr = string.Format(templateInfo,
                        $" 附件为疾病进展确认报告,请查收 "
                        );
                }

                //有序

                if (taskInfo.IsReadingTaskViewInOrder)
                {


                    //单重

                    if (taskInfo.ReadingType == ReadingMethod.Single)
                    {
                        //仲裁在访视上   或者在阅片期
                        if (taskInfo.ArbitrationRule != ArbitrationRule.None)
                        {

                            throw new BusinessValidationFailedException("单重有序阅片配置有误(不应该有仲裁对象配置),请核查!");
                        }


                        //要求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("单重有序阅片 该类型的任务不应进入此处逻辑,请联系后台开发核查!");
                        }


                    }
                    //双重
                    else 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);
                            }
                            //双人  产生裁判,并且裁判完成 发
                            else if (taskList.Count == 3 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned) == 3 && taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Count() == 1)
                            {

                                answer = await TranslatePdStateAsync(taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).First().Id, ReadingCategory.Judge, taskInfo.CriterionType);

                            }
                            else
                            {
                                isNeedSend = false;

                            }


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

                                #region MyRegion

                                ////看该访视是否是截止访视 
                                //var moduleIdList = await _repository.Where<ReadModule>(t => t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.SubjectVisitId == taskInfo.SourceSubjectVisitId && t.ReadingSetType == ReadingSetType.ImageReading)
                                //    .Select(t => (Guid?) t.Id).ToListAsync();

                                ////截止访视
                                //if (moduleIdList.Count > 0)
                                //{
                                //    //截止访视,需要等待生成全局,完成全局再发

                                //    isNeedSend = false;

                                //}
                                ////非截止访视    CRC在该访视设置PD后,在提交的时候,生成了阅片期,一定会生成全局任务
                                //else
                                //{

                                //    isNeedSend = false;
                                //}

                                #endregion


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

                                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);
                                }
                                //双人全局产生裁判
                                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)
                                {

                                    answer = await TranslatePdStateAsync(taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).First().Id, ReadingCategory.Judge, taskInfo.CriterionType);

                                }
                                else
                                {
                                    isNeedSend = false;

                                }
                            }
                            else
                            {
                                throw new BusinessValidationFailedException("发送PD 进展邮件中发现任务数据有问题!");
                            }



                        }
                        else
                        {

                            //throw new BusinessValidationFailedException("双重有序阅片 没有定义该仲裁规则处理逻辑,请联系业务和后台开发核查!");

                            //只发第一个人
                            if (await _visitTaskRepository.AnyAsync(t => t.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false &&
                            t.Id != visitTaskId && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId))
                            {
                                isNeedSend = false;
                            }
                            else
                            {

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


                    }
                    else
                    {
                        throw new BusinessValidationFailedException("有序阅片配置有误(应为单重或者双重阅片),请核查!");
                    }


                }
                //无序
                else
                {
                    //单重


                    if (taskInfo.ReadingType == ReadingMethod.Single && taskInfo.ArbitrationRule == ArbitrationRule.None)
                    {
                        answer = await TranslatePdStateAsync(visitTaskId, taskInfo.ReadingCategory, taskInfo.CriterionType);
                    }
                    //双重  截止访视只在阅片期的时候存在  要求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);
                        }
                        else if (taskList.Count == 3 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned) == 3 && taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Count() == 1)
                        {

                            answer = await TranslatePdStateAsync(taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).First().Id, ReadingCategory.Judge, taskInfo.CriterionType);

                        }
                        else
                        {
                            isNeedSend = false;
                        }

                    }
                    else
                    {
                        //throw new BusinessValidationFailedException("无序阅片配置有误(应为单重无仲裁对象,双重针对访视仲裁),请核查!");


                        //只发第一个人
                        if (await _visitTaskRepository.AnyAsync(t => t.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false &&
                        t.Id != visitTaskId && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId))
                        {
                            isNeedSend = false;
                        }
                        else
                        {

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

                    }

                }

            }
            else
            {
                isNeedSend=false;
            }

            #region MiniWord 组织字典 发送
            if (isNeedSend)
            {
                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 : taskInfo.ModuleEarliestScanDate,
                    ["SignTime"] = taskInfo.SignTime,
                    ["Result"] = answer

                };

                MemoryStream memoryStream = new MemoryStream();

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

                memoryStream.Seek(0, SeekOrigin.Begin);

                sendEmailConfig.EmailAttachMentConfigList.Add(new EmailAttachMentConfig()
                {
                    FileName = emailConfig.FileName,

                    FileStream = memoryStream
                });


                await SendEmailHelper.SendEmailAsync(sendEmailConfig);

            }
            #endregion


        }




        private async Task<string> TranslatePdStateAsync(Guid visitTaskId, ReadingCategory readingCategory, CriterionType criterionType)
        {

            var answer = string.Empty;

            ReadingTaskQuestionAnswer visitQuestionAnswer = null;

            ReadingTaskQuestionAnswer globalQuestionAnswer = null;



            switch (criterionType)
            {


                case CriterionType.RECIST1Pointt1:

                    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.TaskId == visitTaskId && t.TrialReadingQuestion.QuestionType == QuestionType.Tumor).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.Tumor).FirstNotNullAsync();

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

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

                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("不应有 除访视、裁判、全局其他类型的任务进行发送邮件,请核查业务逻辑");
                    }

                    if (answer == VisitTumorEvaluation.PD.GetEnumInt())
                    {
                        return "是";
                    }
                    if (answer == VisitTumorEvaluation.ND.GetEnumInt())
                    {
                        return "ND";
                    }
                    if (answer == VisitTumorEvaluation.NE.GetEnumInt())
                    {
                        return "NE";
                    }
                    else
                    {
                        return "否";
                    }
                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.iRECIST:
                case CriterionType.RANO_BM:
                case CriterionType.RANO:
                case CriterionType.IWCLL2018:
                case CriterionType.mRECISTHCC:
                case CriterionType.Cheson2007:
                case CriterionType.IMWG2016:
                default:

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



         



          
        }


        /// <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();

        }

        [HttpPost]
        public async Task<List<TrialEmailNoticeConfigView>> GetTrialEmailNoticeConfigList(TrialEmailNoticeConfigQuery inQuery)
        {

            await SyncSystemEmainCofigDocListAsync(inQuery.TrialId, inQuery.CriterionTypeEnum);

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

            return await trialEmailNoticeConfigQueryable.ToListAsync();
        }


        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 });

                }


                await _trialEmailNoticeConfigRepository.AddAsync(entity, true);

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



            }
            else
            {
                await _repository.BatchDeleteAsync<TrialEmailNoticeUser>(t => t.TrialEmailNoticeConfigId == addOrEditTrialEmailNoticeConfig.Id);


                var entity = (await _trialEmailNoticeConfigRepository.Where(t => t.Id == addOrEditTrialEmailNoticeConfig.Id, true, true).Include(t => t.TrialEmailNoticeUserList).FirstOrDefaultAsync()).IfNullThrowException();


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


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

                }

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

                }
                await _repository.AddRangeAsync(trialEmailNoticeUsers);

                await _trialEmailNoticeConfigRepository.UpdateFromDTOAsync(addOrEditTrialEmailNoticeConfig);


                await _trialEmailNoticeConfigRepository.SaveChangesAsync();

                return ResponseOutput.Ok();
            }


        }


        private  async Task TestEmailConfigAsync(TrialEmailNoticeConfigAddOrEdit config)
        {
            var toUserList = await  _repository.Where<TrialUser>(t => t.TrialId == config.TrialId && config.ToUserTypeList.Contains(t.User.UserTypeEnum)).Select(t => new { t.User.EMail, t.User.FullName }).ToListAsync();


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

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

            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";


            sendEmailConfig.TopicDescription = "项目邮件测试";

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


                sendEmailConfig.HtmlBodyStr = string.Format(templateInfo,
                    $" 收到此邮件,代表邮件配置正确"
                    );
            }

            try
            {
                await SendEmailHelper.SendEmailAsync(sendEmailConfig);

            }
            catch (Exception ex)
            {

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


        }


        [HttpDelete("{trialEmailNoticeConfigId:guid}")]
        public async Task<IResponseOutput> DeleteTrialEmailNoticeConfig(Guid trialEmailNoticeConfigId)
        {
            var success = await _trialEmailNoticeConfigRepository.DeleteFromQueryAsync(t => t.Id == trialEmailNoticeConfigId, true);

            return ResponseOutput.Ok();
        }


    }
}