<?php

namespace App\ClientCollection\Customer;

/**
 * Does the email sending for an invoice for a particular individual.
 * @author Gabriel
 *
 */
class EmailSend
{

	/**
	 * The email data.
	 * @var \App\ClientCollection\Customer\EmailData
	 */
	private $emailData;


	public function __construct(\App\ClientCollection\Customer\EmailData $emailData)
	{
		$this->emailData = $emailData;
	}

	/**
	 * Send email
	 * @param array $emailData - output of EmailData nanespace classes
	 */
	public function send()
	{
		// CHECK IF IN TRANSACTION
		if (!\DB::isInsideTransaction()) {
			throw new \DBException('The `send` method must be called inside transaction.');
		}

		// CHECK IF THE PROCESS CAN CONTINUE //////////////////////////////////////////////////////
		if ($this->emailData->getMessages()->hasErrorOrWarning()) {
			throw new \RuntimeException('Could not send email due to this error: '.$this->emailData->getMessages()->getMessageBulk());
		}

		$emailActualData = $this->emailData->getData();
		if (!$emailActualData['toFull']) {
			throw new \RuntimeException('There is no TO email configured for this invoice.');
		}


 	// SEND THE EMAIL /////////////////////////////////////////////////////////////////////////
		try {
			// init email object
			$mail = \Entity\Email::insert();

			// FROM details
			$emailConfig = \App\Config\AutoEmailSender::getInstance()->getAll();
			$mail->fromEmail = $emailConfig['collectionReminders']['email'];
			$mail->fromName = $emailConfig['collectionReminders']['name'];

			// TO address
			$recipients = [];
			foreach ($emailActualData['toFull'] as $em) {
				$recipients[] = $em;
			}
			$mail->to = $recipients;

			// BCC address
			$bccRecipients = [];
			foreach ($emailActualData['bccManual'] as $em) {
				$bccRecipients[] = $em;
			}
			if (!empty($bccRecipients)) {
				$mail->bcc = $bccRecipients;
			}

			$emailReplacingVars = $this->emailData->getVars();

			// replace vars and set the subject
			$mail->subject = $this->replaceVars($emailActualData['subject'], $emailReplacingVars);

			// replace vars and set the body
			$emailBody = htmlUnclean($emailActualData['body']);
			$mail->body = $this->replaceVars($emailBody, $emailReplacingVars);

			// Set email properties
			$mail->priority = 3; // high priority
			$mail->category = 'ClientCollection';

			// Save email to queue - cron will handle sending
			$mail->save();
		}
		catch (\App\Entity\Exception $e) {
			throw new \RuntimeException("Could not create email due to a technical problem. Message: ".$e->getMessage());
		}

	}

	/**
	 * Get parsed body
	 */
	private function replaceVars(string $content, array $emailVars) :string
	{

		// encapsulate var nams into %s
		$varsNames = array_map(function ($val) {
			return '%'.$val.'%';
		}, array_keys($emailVars));

		$varsValues = array_values($emailVars);

		$content = str_replace($varsNames, $varsValues, $content);

		return $content;
	}


}