<?php

declare(strict_types=1);

namespace App\Model;

use Nette;
use Nette\Database\Context;
use Nette\Database\Table\ActiveRow;
use Nette\Database\Table\Selection;
use Nette\Utils\ArrayHash;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\SMTP;
use Nette\SmartObject;

require '../PHPMailer/PHPMailer/src/Exception.php';
require '../PHPMailer/PHPMailer/src/PHPMailer.php';
require '../PHPMailer/PHPMailer/src/SMTP.php';


class MailManager {

	use SmartObject;

	protected $database;

	private $url_dir;
	private $host;
	private $port;
	private $from;
	private $fromname;
	private $secure;

	const
		# DB
		TABLE_NAME = 'invitations',
		COLUMN_ID = 'invitation_id',
		COLUMN_BODY = 'body',
		COLUMN_NAME = 'name',
		COLUMN_KEY_ID = 'event_id',
		TABLE_CON = 'contacts',
		COLUMN_CON_ID = 'contact_id',
		COLUMN_CON_MAIL = 'mail',
		COLUMN_CON_NAME = 'name',
		COLUMN_CON_ADRESS = 'adress_id',
		TABLE_ADRESS = 'adress',
		COLUMN_TOKEN = 'token',
		COLUMN_ACTIVE = 'active',
		COLUMN_CON_SALT = 'salt';

	public function __construct($databaseurl, $host, $port, $from, $fromname, $secure, Context $database) {
		$this->url_dir = $databaseurl;
		$this->database = $database;
		$this->host = $host;
		$this->port = $port;
		$this->from = $from;
		$this->fromname = $fromname;
		$this->secure = $secure;
		
	}

	#tahání mailů podle contact_id
	public function idToMail($contact_id) {
		return $this->database->table(self::TABLE_CON)->where(self::COLUMN_CON_ID, $contact_id)->where(self::COLUMN_ACTIVE, 1)->fetchField(self::COLUMN_CON_MAIL);
	}

	#tahání jmén podle contact_id
	public function idToName($contact_id) {
		return $this->database->table(self::TABLE_CON)->where(self::COLUMN_CON_ID, $contact_id)->fetchField(self::COLUMN_CON_NAME);
	}

	#tahání pozvanky podle invitation_id
	public function idToInv($invitation_id) {
		return $this->database->table(self::TABLE_NAME)->where(self::COLUMN_ID, $invitation_id)->fetchField(self::COLUMN_BODY);
	}

	#tahání jména pozvánky podle invitation_id
	public function idToinvN($invitation_id) {
		return $this->database->table(self::TABLE_NAME)->where(self::COLUMN_ID, $invitation_id)->fetchField(self::COLUMN_NAME);
	}

	public function idToSalt($contact_id) {
		return $this->database->table(self::TABLE_CON)->where(self::COLUMN_CON_ID, $contact_id)->fetchField(self::COLUMN_CON_SALT);
	}

	public function oneMail($contact_id, $invitation_id) {

		$con_mail = $this->idToMail($contact_id);
		$con_salt = $this->idToSalt($contact_id);
		$con_name = $this->idToName($contact_id);
		$inv_body = $this->idToInv($invitation_id);
		$inv_name = $this->idToInvN($invitation_id);
		$token = sha1($con_mail.$con_salt);
		$dir = $this->url_dir;
		#$dir = self::DIR;

		$odhlaseni = "<br> Pro odhlášení od odběru pozvánek klikněte zde: <a href=\"http://". $dir ."/adresar/odhlasit/". $token . "\"> Odhlášení odběru</a>.";

		try {

		    $mail = new PHPMailer();

		    $mail->SMTPAutoTLS = false;
			$mail->CharSet = "utf-8";
			$mail->Encoding = "base64";
			$mail->Host = $this->host;
			$mail->SMTPSecure = $this->secure; 
			$mail->Port = $this->port; 
		    $mail->isSMTP(); 
		    
		    //Recipients
		    $mail->setFrom($this->from, $this->fromname);
		    $mail->addAddress($con_mail, $con_name);     

		    // Attachments
		   	$mail->addAttachment('../GDPR.pdf');         

		    $mail->isHTML(true);                             
		    $mail->Subject = $inv_name;
		    $mail->Body    = $inv_body . $odhlaseni;
		    $mail->AltBody = strip_tags($inv_body);

		    $mail->send();

		} catch (Exception $e) {
		    throw new Exception("Error Processing Request", 1);
		}
	}

	public function allMail($adress_id, $invitation_id) {

		$inv_body = $this->idToInv($invitation_id);
		$inv_name = $this->idToInvN($invitation_id);
		$tokens = $this->tokens($adress_id);
		$dir = $this->url_dir;

		try {

			$mail = new PHPMailer();

			$mail->SMTPAutoTLS = false;
			$mail->CharSet = "utf-8";
			$mail->Encoding = "base64";
			$mail->Host = $this->host;
			$mail->SMTPSecure = $this->secure; 
			$mail->Port = $this->port; 
		    $mail->isSMTP(); 
		    $mail->isHTML(true);

		    //Recipients
		  	$mail->setFrom($this->from, $this->fromname);
		  	$mail->addAttachment('../GDPR.pdf');         // GDPR příloha
			$mail->addAddress($this->from, $this->fromname);

				foreach ($tokens as $email => $token) {
					$mail->AddCC($email);
					$mail->Body = $inv_body . "<br> Pro odhlášení od odběru pozvánek klikněte zde: <a href=\"http://". $dir ."/adresar/odhlasit/". $token . "\"> Odhlášení odběru</a>.";
					$mail->Subject = $inv_name;
					$mail->AltBody = strip_tags($inv_body);
					$mail->send();
					$mail->ClearAllRecipients();
				}
		    
		} catch (Exception $e) {
		    throw new Exception("Error Processing Request", 1);
		}
	}

	#vrací tokeny a maily v poli (mail => token)
	public function tokens($id) {
		return $this->database->fetchPairs('SELECT mail, token FROM contacts WHERE adress_id = ? AND active = 1', $id);

	}

	#invitation $id podle event_id
	public function idToInvitation($id) {
		return $this->database->table(self::TABLE_NAME)->where(self::COLUMN_KEY_ID, $id)->fetchField(self::COLUMN_ID);
		
	}

	#event_id podle adress_id
	public function adressToEvent($adress_id) {
		return $this->database->table(self::TABLE_ADRESS)->where(self::COLUMN_CON_ADRESS, $adress_id)->fetchField(self::COLUMN_KEY_ID);
	}	


	#invitation_id podle adress_id
	public function contactToInvitation($id) {

		$event_id = $this->adressToEvent($id);
		return $this->database->table(self::TABLE_NAME)->where(self::COLUMN_KEY_ID, $event_id)->fetchField(self::COLUMN_ID);
	}

	#odhlášení odběru dle tokenu
	public function odhlasitOdber($token) {
		$values = array(
			'active' => 0
		);
		$this->database->table(self::TABLE_CON)->where(self::COLUMN_TOKEN, $token)->update($values);
	}

}
