using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Spreadsheet;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.MassTransit.Consumer;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Domain.Models;
using MassTransit;
using Microsoft.Extensions.Options;
using MimeKit;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reactive.Joins;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace IRaCIS.Core.Application.MassTransit.Recurring
{

    /// <summary>
    /// 10分钟检测通知IR 已通知的进行标注，下次不会再通知
    /// </summary>
    public class UrgentIRUnReadTaskRecurringEventConsumer(
        IRepository<ReadingQuestionCriterionTrial> _trialReadingCriterionRepository,
        IRepository<VisitTask> _visitTaskRepository,
           IRepository<Trial> _trialRepository,
         IRepository<Dictionary> _dictionaryRepository,
        IRepository<TrialUserRole> _trialUserRoleRepository,
        IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigrepository,
        IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<UrgentIRUnReadTaskRecurringEvent>
    {
        private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;

        public async Task Consume(ConsumeContext<UrgentIRUnReadTaskRecurringEvent> context)
        {
            var isEn_US = context.Message.CultureInfoName == StaticData.CultureInfo.en_US;

            //设置当前事件传递过来的语言
            var culture = context.Message.CultureInfoName;
            CultureInfo.CurrentCulture = new CultureInfo(culture);

            var trialId = context.Message.TrialId;

            var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);
            var scenario = EmailBusinessScenario.ExpeditedReading;
            var trialEmailConfig = _trialEmailNoticeConfigrepository.Where(t => t.TrialId == trialId && t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();

            if (trialEmailConfig != null)
            {


                var dictionValue = await CommonEmailHelper.TranslationDictionary(new TranslationDictionaryDto()
                {
                    DictionaryRepository = _dictionaryRepository,
                    IsEn_US = isEn_US,
                    DictionaryList = new List<DictionaryDto>()
                {
                    new DictionaryDto (){DictionaryCode= "YesOrNo",EnumValue="true" }
                }
                });

                //找到该项目所有的IR 并且有加急 和Pd  未读的任务

                Expression<Func<VisitTask, bool>> comonTaskFilter = t => t.TrialId == trialId && t.TaskState == TaskState.Effect && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskAllocationState == TaskAllocationState.Allocated;

                var trialUserList = _trialUserRoleRepository.Where(t => t.TrialId == trialId && t.TrialUser.JoinTime != null).Select(t => new
                {
                    t.UserId,
                    t.UserRole.FullName,
                    t.UserRole.IdentityUser.EMail,
                    t.UserRole.IdentityUser.UserName,
                    t.Trial.TrialCode,
                    t.Trial.ResearchProgramNo,
                    t.UserRole.IdentityUser.UserWorkLanguage
                    //TrialReadingCriterionList = t.Trial.TrialReadingCriterionList.Select(t => new { t.CriterionName, TrialReadingCriterionId = t.Id }).ToList()
                });


                foreach (var trialUser in trialUserList)
                {
                    //重新设置当前发送邮件的语言
                    var workLanguage = trialUser.UserWorkLanguage;
                    isEn_US = workLanguage == UserWorkLanguage.US;

                    var userId = trialUser.UserId;

                    var doctorCriterionList = await _trialReadingCriterionRepository.Where(t => t.IsSigned && t.IsConfirm && t.TrialId == trialId && t.Trial.TrialUserRoleList.Any(t => t.UserId == userId))
                         .Select(c => new
                         {

                             TrialReadingCriterionId = c.Id,
                             CriterionName = c.CriterionName,

                             UnReadList = c.VisitTaskList.Where(t => t.ExpetidEmailNoticeTime == null) //没有被通知
                                  .Where(t => t.DoctorUserId == userId && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskState == TaskState.Effect)
                                  // 前序 不存在 未一致性核查未通过的
                                  .Where(t => !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum > sv.VisitNum))
                                  //前序 不存在  未生成任务的访视
                                  .Where(t => c.IsAutoCreate == false ? !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(d => d.TrialReadingCriterionId == t.TrialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum) : true)

                                  .Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true))

                                  .Where(t => t.SourceSubjectVisit.PDState == PDStateEnum.PDProgress || t.SourceSubjectVisit.IsEnrollmentConfirm ||
                                  t.ReadModule.SubjectVisit.PDState == PDStateEnum.PDProgress || t.ReadModule.SubjectVisit.IsEnrollmentConfirm)
                                  .Select(c => new
                                  {
                                      SubejctCode = c.IsAnalysisCreate ? c.BlindSubjectCode : c.Subject.Code,
                                      c.TaskBlindName,
                                      c.TaskName,
                                      VisitTaskId = c.Id
                                  }).ToList()

                         }).ToListAsync();


                    var toTalUnreadCount = doctorCriterionList.SelectMany(t => t.UnReadList).Count();

                    if (toTalUnreadCount > 0)
                    {
                        var messageToSend = new MimeMessage();

                        //发件地址
                        messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
                        messageToSend.To.Add(new MailboxAddress(trialUser.FullName, trialUser.EMail));

                        var companyName = isEn_US ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;

                        Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
                        {
                            var topicStr = string.Format(input.topicStr, trialUser.ResearchProgramNo);

                            var template = input.htmlBodyStr;

                            //正则提取循环的部分 {%for%}(.*?){%end for%}
                            string pattern = @"{%for%}(.*?){%end for%}";
                            var match = Regex.Match(template, pattern, RegexOptions.Singleline);

                            string criteriaTemplate = match.Groups[1].Value; // 提取循环模板

                            // 构建循环内容
                            string criteriaDetails = "";
                            foreach (var criteria in doctorCriterionList)
                            {
                                if (criteria.UnReadList.Count() > 0)
                                {
                                    criteriaDetails += string.Format(criteriaTemplate, criteria.CriterionName, criteria.UnReadList.Select(t => t.SubejctCode).Distinct().Count(), criteria.UnReadList.Count());

                                }
                            }

                            // 用循环内容替换原始模板中的循环部分
                            string emailContent = template.Replace(criteriaTemplate, criteriaDetails).Replace("{%for%}", "").Replace("{%end for%}", "");



                            var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, emailContent, workLanguage),
                                trialUser.FullName,

                            DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                            toTalUnreadCount,

                            trialUser.ResearchProgramNo,
                             dictionValue[0],
                            _systemEmailConfig.SiteUrl
                                );

                            return (topicStr, htmlBodyStr);
                        };

                         await CommonEmailHelper.GetTrialEmailSubejctAndHtmlInfoAndBuildAsync(trialEmailConfig, messageToSend, emailConfigFunc, workLanguage);

                        await SendEmailHelper.SendTrialEmailAsync(messageToSend, trialInfo);

                        //处理标记已通知的任务

                        var visitTaskIdList = doctorCriterionList.Where(t => t.UnReadList.Count() > 0).SelectMany(t => t.UnReadList.Select(u => u.VisitTaskId)).ToList();

                        await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => visitTaskIdList.Contains(t.Id), u => new VisitTask() { ExpetidEmailNoticeTime = DateTime.Now });
                    }


                }



            }





        }
    }
}
