import * as plugins from './email.plugins.js';
import { EmailService } from './email.classes.emailservice.js';
import { logger } from './email.logging.js';

export class RuleManager {
  public emailRef: EmailService;
  public smartruleInstance = new plugins.smartrule.SmartRule<
    plugins.smartmail.Smartmail<plugins.mailgun.IMailgunMessage>
  >();

  constructor(emailRefArg: EmailService) {
    this.emailRef = emailRefArg;
  }

  public async handleNotification(notification: plugins.mailgun.IMailgunNotification) {
    console.log(notification['message-url']);

    // basic checks here
    // none for now

    const fetchedSmartmail = await this.emailRef.mailgunConnector.receiveEmail(
      notification['message-url']
    );
    console.log('=======================');
    console.log('Received a mail:');
    console.log(`From: ${fetchedSmartmail.options.creationObjectRef.From}`);
    console.log(`To: ${fetchedSmartmail.options.creationObjectRef.To}`);
    console.log(`Subject: ${fetchedSmartmail.options.creationObjectRef.Subject}`);
    console.log('^^^^^^^^^^^^^^^^^^^^^^^');

    logger.log(
      'info',
      `email from ${fetchedSmartmail.options.creationObjectRef.From} to ${fetchedSmartmail.options.creationObjectRef.To} with subject '${fetchedSmartmail.options.creationObjectRef.Subject}'`,
      {
        eventType: 'receivedEmail',
        email: {
          from: fetchedSmartmail.options.creationObjectRef.From,
          to: fetchedSmartmail.options.creationObjectRef.To,
          subject: fetchedSmartmail.options.creationObjectRef.Subject,
        },
      }
    );

    this.smartruleInstance.makeDecision(fetchedSmartmail);
  }

  public async init() {
    // lets forward stuff
    await this.createForwards();
  }

  /**
   * creates the default forwards
   */
  public async createForwards() {
    const forwards: { originalToAddress: string[]; forwardedToAddress: string[] }[] = [
      {
        originalToAddress: ['bot@mail.nevermind.group'],
        forwardedToAddress: ['phil@metadata.company', 'dominik@metadata.company'],
      },
      {
        originalToAddress: ['legal@mail.lossless.com'],
        forwardedToAddress: ['phil@lossless.com'],
      },
      {
        originalToAddress: ['christine.nyamwaro@mail.lossless.com', 'christine@nyamwaro.com'],
        forwardedToAddress: ['phil@lossless.com'],
      },
    ];
    console.log(`${forwards.length} forward rules configured:`);
    for (const forward of forwards) {
      console.log(forward);
    }

    for (const forward of forwards) {
      this.smartruleInstance.createRule(
        10,
        async (smartmailArg) => {
          const matched = forward.originalToAddress.reduce<boolean>((prevValue, currentValue) => {
            return smartmailArg.options.creationObjectRef.To.includes(currentValue) || prevValue;
          }, false);
          if (matched) {
            console.log('Forward rule matched');
            console.log(forward);
            return 'apply-continue';
          } else {
            return 'continue';
          }
        },
        async (smartmailArg: plugins.smartmail.Smartmail<plugins.mailgun.IMailgunMessage>) => {
          forward.forwardedToAddress.map(async (toArg) => {
            const forwardedSmartMail = new plugins.smartmail.Smartmail({
              body:
                `
              <div style="background: #CCC; padding: 10px; border-radius: 3px;">
                <div><b>Original Sender:</b></div>
                <div>${smartmailArg.options.creationObjectRef.From}</div>
                <div><b>Original Recipient:</b></div>
                <div>${smartmailArg.options.creationObjectRef.To}</div>
                <div><b>Forwarded to:</b></div>
                <div>${forward.forwardedToAddress.reduce<string>((pVal, cVal) => {
                  return `${pVal ? pVal + ', ' : ''}${cVal}`;
                }, null)}</div>
                <div><b>Subject:</b></div>
                <div>${smartmailArg.getSubject()}</div>
                <div><b>The original body can be found below.</b></div>
              </div>
              ` + smartmailArg.getBody(),
              from: 'forwarder@mail.lossless.one',
              subject: `Forwarded mail for '${smartmailArg.options.creationObjectRef.To}'`,
            });
            for (const attachment of smartmailArg.attachments) {
              forwardedSmartMail.addAttachment(attachment);
            }
            await this.emailRef.mailgunConnector.sendEmail(forwardedSmartMail, toArg);
            console.log(`forwarded mail to ${toArg}`);
            logger.log(
              'info',
              `email from ${
                smartmailArg.options.creationObjectRef.From
              } to phil@lossless.com with subject '${smartmailArg.getSubject()}'`,
              {
                eventType: 'forwardedEmail',
                email: {
                  from: smartmailArg.options.creationObjectRef.From,
                  to: smartmailArg.options.creationObjectRef.To,
                  forwardedTo: toArg,
                  subject: smartmailArg.options.creationObjectRef.Subject,
                },
              }
            );
          });
        }
      );
    }
  }
}