<?php

namespace Franzz\Spot;
use Franzz\Objects\PhpObject;
use Franzz\Objects\Mask;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
use \Settings;

class Email extends PhpObject {

	private $sServName;
	private $sTemplateName;

	/**
	 * Email Template
	 * @var Mask
	 */
	public $oTemplate;

	private $asDests;

	public function __construct($sServName, $sTemplateName='') {
		parent::__construct(__CLASS__);
		$this->sServName = $sServName;
		$this->setTemplate($sTemplateName);
		$this->asDests = array();
	}

	public function setTemplate($sTemplateName) {
		$this->sTemplateName = $sTemplateName;
		$this->oTemplate = new Mask($this->sTemplateName);
		$this->oTemplate->setTag('local_server', $this->sServName);
	}

	/**
	 * Set Target User Info
	 * @param array $asDests Contains: id_user, name, email, language, timezone, active
	 */
	public function setDestInfo($asDests) {
		if(array_key_exists('email', $asDests)) $asDests = array($asDests);
		$this->asDests = $asDests;
	}

	public function send() {
		$oPHPMailer = new PHPMailer(true);

		//Server settings
		if(Settings::DEBUG) $oPHPMailer->SMTPDebug = SMTP::DEBUG_SERVER;//Enable verbose debug output
		$oPHPMailer->isSMTP();											//Send using SMTP
		$oPHPMailer->CharSet 	= Settings::TEXT_ENC;					//Mail Character Set
		$oPHPMailer->Encoding	= 'base64';								//Base 64 Character Encoding
		$oPHPMailer->Host       = Settings::MAIL_SERVER;				//Set the SMTP server to send through
		$oPHPMailer->SMTPAuth   = true;									//Enable SMTP authentication
		$oPHPMailer->Username   = Settings::MAIL_USER;					//SMTP username
		$oPHPMailer->Password   = Settings::MAIL_PASS;					//SMTP password
		$oPHPMailer->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;		//Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` encouraged
		$oPHPMailer->Port       = 587;									//TCP port to connect to, use 465 for `PHPMailer::ENCRYPTION_SMTPS` above
		$oPHPMailer->setFrom(Settings::MAIL_FROM, Spot::PROJECT_NAME);
		$oPHPMailer->addReplyTo(Settings::MAIL_FROM, Spot::PROJECT_NAME);

		$bSuccess = true;
		foreach($this->asDests as $asDest) {
			//Message
			$this->oTemplate->setLanguage($asDest['language'], Spot::DEFAULT_LANG);
			$this->oTemplate->setTimezone($asDest['timezone']);

			//Unsubscribe Link
			$sUnsubLink = $this->sServName.'?a=unsubscribe_email&id='.$asDest['id_user'];
			$this->oTemplate->setTag('unsubscribe_link', htmlspecialchars($sUnsubLink));
			$oPHPMailer->addCustomHeader('List-Unsubscribe','<mailto:'.Settings::MAIL_FROM.'?subject=unsubscribe>, <'.$sUnsubLink.'>');
			$oPHPMailer->addCustomHeader('List-Unsubscribe-Post','List-Unsubscribe=One-Click');

			//Email Content
			$this->oTemplate->setTag('timezone', 'lang:time.city', self::getTimeZoneCity($asDest['timezone']));
			$sHtmlMessage = $this->oTemplate->getMask();
			$sPlainMessage = strip_tags(str_replace('<br />', "\n", $sHtmlMessage));

			//Recipients
			try {
				$oPHPMailer->addAddress($asDest['email'], $asDest['name']);
			} catch (Exception $oError) {
				$this->addError('Invalid address skipped: '.$asDest['email'].' ('.$asDest['name'].')');
				continue;
			}

			//Content
			$oPHPMailer->isHTML(true);
			$oPHPMailer->Subject = $this->oTemplate->getTranslator()->getTranslation($this->sTemplateName.'.subject');
			$oPHPMailer->Body    = $sHtmlMessage;
			$oPHPMailer->AltBody = $sPlainMessage;

			try {
				$bSuccess = $bSuccess && $oPHPMailer->send();
			}
			catch (Exception $oError) {
				$this->addError('Message could not be sent to "'.$asDest['email'].'". Mailer Error: '.$oPHPMailer->ErrorInfo);
				$oPHPMailer->getSMTPInstance()->reset();
			}
			$oPHPMailer->clearAddresses();
			$oPHPMailer->clearCustomHeaders();
		}
		return $bSuccess;
	}

	private static function getTimeZoneCity($sTimeZone) {
		return (strpos($sTimeZone, '/')!==false)?str_replace('_', ' ', explode('/', $sTimeZone)[1]):$sTimeZone;
	}
}
