text: const errors = require('@tryghost/errors');
  const DomainEvents = require('@tryghost/domain-events');
  const {MemberSubscribeEvent} = require('@tryghost/member-events');
  
  const messages = {
      emailVerificationNeeded: `We're hard at work processing your import. To make sure you get great deliverability on a list of that size, we'll need to enable some extra features for your account. A member of our team will be in touch with you by email to review your account make sure everything is configured correctly so you're ready to go.`,
      emailVerificationEmailSubject: `Email needs verification`,
      emailVerificationEmailMessageImport: `Email verification needed for site: {siteUrl}, just imported: {importedNumber} members.`,
      emailVerificationEmailMessageAPI: `Email verification needed for site: {siteUrl} has added: {importedNumber} members through the API in the last 30 days.`
  };
  
  class VerificationTrigger {
      /**
       *
       * @param {object} deps
       * @param {number} deps.configThreshold Threshold for triggering verification as defined in config
       * @param {() => boolean} deps.isVerified Check Ghost config to see if we are already verified
       * @param {() => boolean} deps.isVerificationRequired Check Ghost settings to see whether verification has been requested
       * @param {(content: {subject: string, message: string, amountImported: number}) => {}} deps.sendVerificationEmail Sends an email to the escalation address to confirm that customer needs to be verified
       * @param {any} deps.membersStats MemberStats service
       * @param {any} deps.Settings Ghost Settings model
       * @param {any} deps.eventRepository For querying events
       */
      constructor({
          configThreshold,
          isVerified,
          isVerificationRequired,
          sendVerificationEmail,
          membersStats,
          Settings,
          eventRepository
      }) {
          this._configThreshold = configThreshold;
          this._isVerified = isVerified;
          this._isVerificationRequired = isVerificationRequired;
          this._sendVerificationEmail = sendVerificationEmail;
          this._membersStats = membersStats;
          this._Settings = Settings;
          this._eventRepository = eventRepository;
  
          DomainEvents.subscribe(MemberSubscribeEvent, async (event) => {
              if (event.data.source === 'api' && isFinite(this._configThreshold)) {
                  const createdAt = new Date();
                  createdAt.setDate(createdAt.getDate() - 30);
                  const events = await this._eventRepository.getNewsletterSubscriptionEvents({}, {
                      'data.source': `data.source:'api'`,
                      'data.created_at': `data.created_at:>'${createdAt.toISOString().replace('T', ' ').substring(0, 19)}'`
                  });
  
                  if (events.meta.pagination.total > this._configThreshold) {
                      await this.startVerificationProcess({
                          amountImported: events.meta.pagination.total,
                          throwOnTrigger: false,
                          source: 'api'
                      });
                  }
              }
          });
      }
  
      async getImportThreshold() {
          const volumeThreshold = this._configThreshold;
          if (isFinite(volumeThreshold)) {
              const membersTotal = await this._membersStats.getTotalMembers();
              return Math.max(membersTotal, volumeThreshold);
          } else {
              return volumeThreshold;
          }
      }
  
      /**
       * @typedef IVerificationResult
       * @property {boolean} needsVerification Whether the verification workflow was triggered
       */
  
      /**
       *
       * @param {object} config
       * @param {number} config.amountImported Amount of members which were imported
       * @param {boolean} config.throwOnTrigger Whether to throw if verification is needed
       * @param {string} config.source Source of the verification trigger - currently either 'api' or 'import'
       * @returns {Promise<IVerificationResult>} Object containing property "needsVerification" - true when triggered
       */
      async startVerificationProcess({
          amountImported,
          throwOnTrigger,
          source
      }) {
          if (!this._isVerified()) {
              // Only trigger flag change and escalation email the first time
              if (!this._isVerificationRequired()) {
                  await this._Settings.edit([{
                      key: 'email_verification_required',
                      value: true
                  }], {context: {internal: true}});
  
                  this._sendVerificationEmail({
                      message: source === 'api'
                          ? messages.emailVerificationEmailMessageAPI
                          : messages.emailVerificationEmailMessageImport,
                      subject: messages.emailVerificationEmailSubject,
                      amountImported
                  });
  
                  if (throwOnTrigger) {
                      throw new errors.ValidationError({
                          message: messages.emailVerificationNeeded
                      });
                  }
  
                  return {
                      needsVerification: true
                  };
              }
          }
  
          return {
              needsVerification: false
          };
      }
  }
  
  module.exports = VerificationTrigger;
  