using DocumentFormat.OpenXml.Office2013.Excel;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml.Vml;
using DocumentFormat.OpenXml.Wordprocessing;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.MassTransit.Command;
using IRaCIS.Core.Domain;
using IRaCIS.Core.Domain.BaseModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using MassTransit;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.Extensions.Options;
using MimeKit;
using NPOI.SS.Formula.Functions;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IRaCIS.Core.Application.MassTransit.Consumer;

/// <summary>
/// 用户提交 发送邮件 通知SPM 或者PM
/// </summary>
public class UserSiteSurveySubmitedEventConsumer(
      IRepository<Trial> _trialRepository,
      IRepository<TrialSite> _trialSiteRepository,
      IRepository<TrialSiteSurvey> _trialSiteSurveyRepository,
      IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
      IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig
    ) : IConsumer<UserSiteSurveySubmitedEvent>
{
    private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
    public async Task Consume(ConsumeContext<UserSiteSurveySubmitedEvent> context)
    {
        var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;

        var trialSiteSurveyId = context.Message.TrialSiteSurveyId;

        var siteSurveyInfo = _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId).FirstOrDefault().IfNullThrowException();

        var trialId = siteSurveyInfo.TrialId;

        var trialUserList = await _trialSiteSurveyRepository.Where(t => t.TrialId == siteSurveyInfo.TrialId).SelectMany(t => t.Trial.TrialUserList)
            .Where(t => t.User.UserTypeEnum == UserTypeEnum.SPM || t.User.UserTypeEnum == UserTypeEnum.CPM || t.User.UserTypeEnum == UserTypeEnum.ProjectManager || t.User.UserTypeEnum == UserTypeEnum.APM)
            .Select(t => new { t.User.FullName, t.User.EMail, t.User.UserTypeEnum }).ToListAsync();

        var sPMOrCPMList = trialUserList.Where(t => t.UserTypeEnum == UserTypeEnum.SPM || t.UserTypeEnum == UserTypeEnum.CPM).ToList();
        var pmAndAPMList = trialUserList.Where(t => t.UserTypeEnum == UserTypeEnum.ProjectManager || t.UserTypeEnum == UserTypeEnum.APM).ToList();

        var messageToSend = new MimeMessage();

        var toUserName = string.Empty;

        //有SPM
        if (sPMOrCPMList.Count > 0)
        {
            foreach (var user in sPMOrCPMList)
            {
                messageToSend.To.Add(new MailboxAddress(user.FullName, user.EMail));
            }

            toUserName = string.Join('、', sPMOrCPMList.Select(t => t.FullName));

        }
        else
        {
            foreach (var user in pmAndAPMList)
            {
                messageToSend.To.Add(new MailboxAddress(user.FullName, user.EMail));
            }

            toUserName = string.Join('、', pmAndAPMList.Select(t => t.FullName));
        }

        var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);

        var siteInfo = await _trialSiteRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.Id == siteSurveyInfo.TrialSiteId, true);

        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, trialInfo.ResearchProgramNo);
            var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
                toUserName,
            siteInfo.TrialSiteCode,
            siteInfo.TrialSiteAliasName,

            siteSurveyInfo.UserName,
            siteSurveyInfo.Email,
            siteSurveyInfo.Phone,
            _systemEmailConfig.SiteUrl
                );

            return (topicStr, htmlBodyStr);
        };

        var scenario = _trialSiteSurveyRepository.Any(t => t.Id != trialSiteSurveyId && t.TrialId == siteSurveyInfo.TrialId && t.TrialSiteId == siteSurveyInfo.TrialSiteId) ?
          EmailBusinessScenario.Approval_UpdateSiteSurvey : EmailBusinessScenario.Approval_SubmitSiteSurvey;

        await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(_emailNoticeConfigrepository, EmailBusinessScenario.Approval_SubmitSiteSurvey, messageToSend, emailConfigFunc);

        await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);

    }
}

/// <summary>
/// 调研表初审通过，进行复审发送邮件
/// </summary>
public class SiteSurveySPMSubmitedEventConsumer(
      IRepository<Trial> _trialRepository,
      IRepository<TrialSite> _trialSiteRepository,
      IRepository<TrialSiteSurvey> _trialSiteSurveyRepository,
      IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
      IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig) : IConsumer<SiteSurveySPMSubmitedEvent>
{
    private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;
    public async Task Consume(ConsumeContext<SiteSurveySPMSubmitedEvent> context)
    {

        var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;

        var trialSiteSurveyId = context.Message.TrialSiteSurveyId;

        var siteSurveyInfo = _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId).FirstOrDefault().IfNullThrowException();

        var trialId = siteSurveyInfo.TrialId;

        var messageToSend = new MimeMessage();

        var trialUserList = _trialRepository.Where(t => t.Id == trialId)
            .SelectMany(t => t.TrialUserList)
            .Where(t => t.User.UserTypeEnum == UserTypeEnum.SPM || t.User.UserTypeEnum == UserTypeEnum.CPM || t.User.UserTypeEnum == UserTypeEnum.ProjectManager || t.User.UserTypeEnum == UserTypeEnum.APM)
            .Select(t => new { t.User.EMail, t.User.FullName, t.User.UserTypeEnum }).ToList();

        var sPMOrCPMList = trialUserList.Where(t => t.UserTypeEnum == UserTypeEnum.SPM || t.UserTypeEnum == UserTypeEnum.CPM).ToList();
        var pmAndAPMList = trialUserList.Where(t => t.UserTypeEnum == UserTypeEnum.ProjectManager || t.UserTypeEnum == UserTypeEnum.APM).ToList();

        var toUserName = string.Empty;

        foreach (var item in pmAndAPMList)
        {
            messageToSend.To.Add(new MailboxAddress(item.FullName, item.EMail));

            toUserName = string.Join('、', pmAndAPMList.Select(t => t.FullName));
        }



        var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);

        var siteInfo = await _trialSiteRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.Id == siteSurveyInfo.TrialSiteId, true);


        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, trialInfo.ResearchProgramNo);
            var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
            toUserName,
            siteInfo.TrialSiteCode,
            siteInfo.TrialSiteAliasName,

           siteSurveyInfo.UserName,
           siteSurveyInfo.Email,
           siteSurveyInfo.Phone,
           _systemEmailConfig.SiteUrl
                );

            return (topicStr, htmlBodyStr);
        };

        await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(_emailNoticeConfigrepository, EmailBusinessScenario.SiteSurveyReject, messageToSend, emailConfigFunc);

        await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
    }
}


/// <summary>
/// 调研表驳回发送邮件    之前已有，需要迁移过来
/// </summary>
public class SiteSurverRejectedEventConsumer(
      IRepository<User> _userRepository,
      IRepository<Trial> _trialRepository,
      IRepository<TrialSite> _trialSiteRepository,
      IRepository<TrialSiteSurvey> _trialSiteSurveyRepository,
      IRepository<EmailNoticeConfig> _emailNoticeConfigrepository,
      IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig
    ) : IConsumer<SiteSurverRejectedEvent>
{
    private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue;

    public async Task Consume(ConsumeContext<SiteSurverRejectedEvent> context)
    {
        var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;

        var trialSiteSurveyId = context.Message.TrialSiteSurveyId;

        var siteSurveyInfo = _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId).FirstOrDefault().IfNullThrowException();

        var trialId = siteSurveyInfo.TrialId;


        var messageToSend = new MimeMessage();

        var name = siteSurveyInfo.UserName;

        if (context.Message.IsHaveSPMOrCPM)
        {
            //PM 驳回到SPM
            if (siteSurveyInfo.State == TrialSiteSurveyEnum.CRCSubmitted)
            {
                var user = await _userRepository.FirstOrDefaultAsync(t => t.Id == siteSurveyInfo.PreliminaryUserId);

                name = user.FullName;

                messageToSend.To.Add(new MailboxAddress(name, user.EMail));
            }
            //SPM 驳回到CRC
            else if (siteSurveyInfo.State == TrialSiteSurveyEnum.ToSubmit)
            {
                messageToSend.To.Add(new MailboxAddress(name, siteSurveyInfo.Email));
            }

        }
        else
        {
            //没有SPM  PM驳回到CRC

            messageToSend.To.Add(new MailboxAddress(String.Empty, siteSurveyInfo.Email));
        }

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


        var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);

        var siteInfo = await _trialSiteRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.Id == siteSurveyInfo.TrialSiteId, true);


        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, trialInfo.ResearchProgramNo);
            var htmlBodyStr = string.Format(CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
           name,
            trialInfo.TrialCode,
                 trialInfo.ResearchProgramNo,
                trialInfo.ExperimentName,
            siteInfo.TrialSiteCode,
            siteInfo.TrialSiteAliasName,
               siteSurveyInfo.LatestBackReason,
            _systemEmailConfig.SiteUrl,
               (siteSurveyInfo.State == TrialSiteSurveyEnum.ToSubmit ? "inline - block" : "none")
                );

            return (topicStr, htmlBodyStr);
        };

        await CommonEmailHelper.GetEmailSubejctAndHtmlInfoAndBuildAsync(_emailNoticeConfigrepository, EmailBusinessScenario.SiteSurveyReject, messageToSend, emailConfigFunc);

        await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);


    }
}
