using DocumentFormat.OpenXml;
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>
    /// 定时过期提醒
    /// </summary>
    public class SystemDocumentErverDayEventConsumer(
        IRepository<ReadingQuestionCriterionTrial> _trialReadingCriterionRepository,
        IRepository<VisitTask> _visitTaskRepository,
           IRepository<SystemDocument> _systemDocumentRepository,
             IRepository<IdentityUser> _identityUserRepository,
                   IRepository<SystemDocConfirmedIdentityUser> _systemDocConfirmedUserRepository,
         IRepository<Dictionary> _dictionaryRepository,
        IRepository<TrialUserRole> _trialUserRoleRepository,
        IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,

        IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<SystemDocumentErverDayEvent>
    {
        private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;

        public async Task Consume(ConsumeContext<SystemDocumentErverDayEvent> context)
        {

            DateTime now = DateTime.Now;
            Console.WriteLine("发送定时过期提醒");
            var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
            var systemDocQuery =
            from sysDoc in _systemDocumentRepository.AsQueryable(false)
            from identityUser in _identityUserRepository.AsQueryable(false).Where(t => t.UserRoleList.Where(t => t.IsUserRoleDisabled == false).Any(t => sysDoc.NeedConfirmedUserTypeList.AsQueryable().Any(c => c.NeedConfirmUserTypeId == t.UserTypeId)))
            join confirmc in _systemDocConfirmedUserRepository.Where() on new { ConfirmUserId = identityUser.Id, SystemDocumentId = sysDoc.Id } equals new { confirmc.ConfirmUserId, confirmc.SystemDocumentId } into cc
            from confirm in cc.DefaultIfEmpty()
            select new UnionDocumentWithConfirmInfoView()
            {
                IsSystemDoc = true,
                Id = sysDoc.Id,
                CreateTime = sysDoc.CreateTime,
                IsDeleted = sysDoc.IsDeleted,
                SignViewMinimumMinutes = sysDoc.SignViewMinimumMinutes,
                Name = sysDoc.Name,
                Path = sysDoc.Path,
                FileTypeId = sysDoc.FileTypeId,
                UpdateTime = sysDoc.UpdateTime,
                ConfirmUserId = identityUser.Id,
                ConfirmTime = confirm.ConfirmTime,
                UserCreateTime = identityUser.CreateTime,
                CurrentStaffTrainDays = sysDoc.CurrentStaffTrainDays,
                NewStaffTrainDays = sysDoc.NewStaffTrainDays,
                RealName = identityUser.FullName,
                UserName = identityUser.UserName,


                IsNeedSendEmial = identityUser.IsZhiZhun || (!identityUser.IsZhiZhun && sysDoc.DocUserSignType == DocUserSignType.InnerAndOuter),
                FullFilePath = sysDoc.Path
            };
            var datalist = await systemDocQuery.IgnoreQueryFilters().Where(t => t.IsDeleted == false && t.ConfirmTime == null)
             .ToListAsync();
            datalist = datalist.Where(x => x.SuggestFinishTime != null && x.SuggestFinishTime.Value.Date == DateTime.Now.Date)
                .Where(x => x.IsNeedSendEmial).ToList();
            var confirmUserIdList = datalist.Select(t => t.ConfirmUserId).Distinct().ToList();
            var userinfoList = await _identityUserRepository.Where(x => confirmUserIdList.Contains(x.Id)).ToListAsync();

            Console.WriteLine("发送定时过期提醒:人员数量" + userinfoList.Count);
            int index = 1;
            foreach (var userinfo in userinfoList)
            {
                try
                {
                    Console.WriteLine($"{index}发送定时过期提醒,邮箱:{userinfo.EMail},姓名{userinfo.UserName}");
                    index++;
                    var messageToSend = new MimeMessage();
                    //发件地址
                    messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
                    messageToSend.To.Add(new MailboxAddress(String.Empty, userinfo.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, companyName);

                        var htmlBodyStr = string.Format(
                           CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
                           userinfo.UserName   // 用户名  {0}

                            );

                        return (topicStr, htmlBodyStr);
                    };

                    var scenario = EmailBusinessScenario.GeneralTraining_ExpirationNotification;

                    var emailConfig = _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();

                    if (emailConfig != null)
                    {
                        await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailConfig, messageToSend, emailConfigFunc);

                        await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
                    }


                }
                catch (Exception)
                {

                }

            }


        }
    }

    /// <summary>
    /// 生效通知
    /// </summary>
    public class SystemDocumentPublishEventConsumer(
     IRepository<ReadingQuestionCriterionTrial> _trialReadingCriterionRepository,
     IRepository<VisitTask> _visitTaskRepository,
        IRepository<SystemDocument> _systemDocumentRepository,
          IRepository<IdentityUser> _identityUserRepository,
                IRepository<SystemDocConfirmedIdentityUser> _systemDocConfirmedUserRepository,
      IRepository<Dictionary> _dictionaryRepository,
     IRepository<TrialUserRole> _trialUserRoleRepository,
     IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,

     IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<SystemDocumentPublishEvent>
    {
        private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;

        public async Task Consume(ConsumeContext<SystemDocumentPublishEvent> context)
        {

            var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
            var systemDocQuery =
            from sysDoc in _systemDocumentRepository.AsQueryable(false).Where(x => context.Message.Ids.Contains(x.Id))
            from identityUser in _identityUserRepository.AsQueryable(false).Where(t => t.Status == UserStateEnum.Enable && t.UserRoleList.Where(t => t.IsUserRoleDisabled == false).Any(t => sysDoc.NeedConfirmedUserTypeList.AsQueryable().Any(c => c.NeedConfirmUserTypeId == t.UserTypeId)))
            select new UnionDocumentWithConfirmInfoView()
            {
                IsSystemDoc = true,
                Id = sysDoc.Id,
                CreateTime = sysDoc.CreateTime,
                IsDeleted = sysDoc.IsDeleted,
                SignViewMinimumMinutes = sysDoc.SignViewMinimumMinutes,
                Name = sysDoc.Name,
                Path = sysDoc.Path,
                FileTypeId = sysDoc.FileTypeId,
                UpdateTime = sysDoc.UpdateTime,
                ConfirmUserId = identityUser.Id,

                RealName = identityUser.FullName,
                UserName = identityUser.UserName,
                IsNeedSendEmial = identityUser.IsZhiZhun || (!identityUser.IsZhiZhun && sysDoc.DocUserSignType == DocUserSignType.InnerAndOuter),


                FullFilePath = sysDoc.Path
            };
            var datalist = await systemDocQuery.IgnoreQueryFilters().Where(x => x.IsNeedSendEmial).ToListAsync();

            var confirmUserIdList = datalist.Select(t => t.ConfirmUserId).Distinct().ToList();
            var userinfoList = await _identityUserRepository.Where(x => confirmUserIdList.Contains(x.Id)).ToListAsync();
            int index = 1;
            foreach (var userinfo in userinfoList)
            {
                string msg = $"{index}生效通知,邮箱:{userinfo.EMail},姓名{userinfo.UserName},";
                index++;
                try
                {

                    var messageToSend = new MimeMessage();
                    //发件地址
                    messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
                    messageToSend.To.Add(new MailboxAddress(String.Empty, userinfo.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, companyName);

                        var htmlBodyStr = string.Format(
                           CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
                           userinfo.UserName   // 用户名  {0}

                            );

                        return (topicStr, htmlBodyStr);
                    };

                    var scenario = EmailBusinessScenario.GeneralTraining_EffectiveNotification;

                    var emailConfig = _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario && t.IsAutoSend && t.IsEnable).FirstOrDefault();

                    if (emailConfig != null)
                    {
                        await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(emailConfig, messageToSend, emailConfigFunc);

                        await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
                        msg += "发送成功";
                    }


                }
                catch (Exception)
                {
                    msg += "发送失败";

                }


                Console.WriteLine(msg);
            }

        }
    }
}