<?php

/**
 * Vvveb
 *
 * Copyright (C) 2022  Ziadin Givan
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */

namespace Vvveb\Plugins\Newsletter\Controller;

use function Vvveb\__;
use Vvveb\Controller\Crud;
use function Vvveb\email;
use function Vvveb\htmlToText;
use function Vvveb\siteSettings;
use Vvveb\System\Cache;
use Vvveb\System\Sites;
use function Vvveb\url;

class NewsletterSend extends Crud {
	function listAutocomplete() {
		$listModel  = new \Vvveb\Sql\Plugins\Newsletter\Newsletter_listSQL();
		$text       = trim($this->request->get['text'] ?? '');

		$options = [
			'status' => 1,
			'search' => $text,
		] + $this->global;

		$results = $listModel->getAll($options);
		$search = [];

		if (isset($results['newsletter_list'])) {
			foreach ($results['newsletter_list'] as $list) {
				$search[$list['newsletter_list_id']] =  $list['name'];
			}
		}

		$this->response->setType('json');
		$this->response->output($search);
	}

	function newsletterAutocomplete() {
		$postModel  = new \Vvveb\Sql\Plugins\Newsletter\Newsletter_postSQL();
		$text       = trim($this->request->get['text'] ?? '');

		$options = [
			'status' => 1,
			'search' => $text,
		] + $this->global;

		$results = $postModel->getAll($options);
		$search = [];

		if (isset($results['newsletter_post'])) {
			foreach ($results['newsletter_post'] as $post) {
				$search[$post['newsletter_post_id']] =  $post['name'];
			}
		}

		$this->response->setType('json');
		$this->response->output($search);
	}

	private function processVariables($content, $variables = []) {
		return preg_replace_callback('/{\$(.+?)}/', function ($matches) use ($variables) {
			$key = $matches[1];

			if (isset($variables[$key])) {
				return $variables[$key];
			}

			return $matches[0];
		}, $content);
	}

	private function sendMail($to, $subject, $template,  $data = [], $config = []) {
		return email($to, $subject, $template, $data, $config, null, $this->global['site_id']);
	}

	private function unsubscribeLink() {
		return 'http://unsubscribe';
	}

	function next() {
		$newsletter = $this->request->post['newsletter'];
		$position   = $this->request->get['position'];
		$count      = $this->request->get['count'];
		$newsletter_list_id = $newsletter['newsletter_list_id'] ?? false;
		$newsletter_post_id = $newsletter['newsletter_post_id'] ?? false;
		$limit              = $newsletter['step'] ?? 100;
		$subject            = $newsletter['subject'] ?? '';
		$from               = $newsletter['from'] ?? '';
		$sender             = $newsletter['sender'] ?? '';
		$reply              = $newsletter['reply'] ?? '';

		if ($newsletter_post_id) {
			$postModel  = new \Vvveb\Sql\Plugins\Newsletter\Newsletter_postSQL();
			if ($post = $postModel->get(['newsletter_post_id' => $newsletter_post_id])) {
				$content = $post['content'];
			}
		}

		$defaults['unsubscribe_link'] = $this->unsubscribeLink();

		$success = false;

		if ($newsletter_list_id && $content) {
			$listModel  = new \Vvveb\Sql\Plugins\Newsletter\Newsletter_mailSQL();
			if ($list = $listModel->getAll(['newsletter_list_id' => $newsletter_list_id, 'start' => $position, 'limit' => $limit])) {
				$mails = $list['newsletter_mail'];
				$total    = $list['count'];
				foreach ($mails as $mail) {
					$config = ['from' => $from, 'sender' => $sender, 'reply' => $reply];

					$to = $mail['email'];

					$variables = $mail + $defaults + $this->global;

					$html = $this->processVariables($content, $variables);
					$txt = htmlToText($html);

					$template = ['html' => $html, 'txt' => $txt];
					if (! ($success = $this->sendMail($to, $subject, $template, [], $config))) {
						$message = sprintf(__('Error sending mail to %s'), $to);
						break;
					}
				}

				$position  += $total;
			}
		}


		$last = ($position > $count);
		$message = '';
		if ($last) {
			$message = __('Sending finished!');
		}


		$url = ['module'=> 'plugins/newsletter/newsletter-send', 'action' => 'next', 'position' => $position, 'count' => $count, 'last' => $last, 'newsletter_post_id' => $newsletter['newsletter_post_id'], 'newsletter_list_id' => $newsletter['newsletter_list_id'], 'success' => $message];
		//sleep(1);

		if ($this->request->isAjax()) {
			$this->response->setType('json');
			$this->response->output($url + ['url' => url($url)]);
		} else {
			$this->redirect(url($url));

			die('Processing');
		}

		return;
	}


	function test() {
		$newsletter = $this->request->post['newsletter'];
		$to   = $this->request->post['test_email'];

		$newsletter_list_id = $newsletter['newsletter_list_id'] ?? false;
		$newsletter_post_id = $newsletter['newsletter_post_id'] ?? false;
		$subject            = $newsletter['subject'] ?? '';
		$from               = $newsletter['from'] ?? '';
		$sender             = $newsletter['sender'] ?? '';
		$reply              = $newsletter['reply'] ?? '';

		$content = '';
		if ($newsletter_post_id) {
			$postModel  = new \Vvveb\Sql\Plugins\Newsletter\Newsletter_postSQL();
			if ($post = $postModel->get(['newsletter_post_id' => $newsletter_post_id])) {
				$content = $post['content'];
			}
		}

		$config = ['from' => $from, 'sender' => $sender, 'reply' => $reply];
		$defaults = ['email' => $to, 'first_name' => 'John', 'last_name' => 'Doe', 'unsubscribe_link' => $this->unsubscribeLink()];
		$html = $this->processVariables($content, $defaults + $this->global);
		$txt = htmlToText($html);

		$template = ['html' => $html, 'txt' => $txt];

		if (! ($success = $this->sendMail($to, $subject, $template, [], $config))) {
			$message = sprintf(__('Error sending mail to %s'), $to);
			$this->view->errors[] = $message;
		} else {
			$this->view->success[]= __('Test email sent!');
		}

		$this->index();
	}

	function send() {
		$newsletter   = $this->request->post['newsletter'];
		$newsletter_list_id = $newsletter['newsletter_list_id'] ?? false;
		$position = 0;
		$count = 0;
		//var_dump($newsletter);
		if ($newsletter_list_id) {
			$listModel  = new \Vvveb\Sql\Plugins\Newsletter\Newsletter_mailSQL();
			if ($list = $listModel->getCount(['newsletter_list_id' => $newsletter_list_id, 'start'])) {
				$count = $list['newsletter_mail'];
			}
		}

		$url = ['module'=> 'plugins/newsletter/newsletter-send', 'action' => 'next', 'position' => $position, 'newsletter_post_id' => $newsletter['newsletter_post_id'], 'newsletter_list_id' => $newsletter_list_id, 'count' => $count];
		$this->view->newsletter = $newsletter;
		$this->view->nextUrl = url($url);
	}

	function index() {
		$view = $this->view;

		$admin_path  = \Vvveb\adminPath();

		$controllerPath  = $admin_path . 'index.php?module=media/media';
		$view->scanUrl   = "$controllerPath&action=scan";
		$view->uploadUrl = "$controllerPath&action=upload";
		$view->linkUrl   = $admin_path . 'index.php?module=content/post&action=urlAutocomplete';
		$theme           = Sites::getTheme(SITE_ID) ?? 'default';
		$view->themeCss  = '';

		if (file_exists(DIR_THEMES . "$theme/css/admin-post-editor.css")) {
			$view->themeCss .= PUBLIC_PATH . "themes/$theme/css/admin-post-editor.css";
		} else {
			if (file_exists(DIR_THEMES . "$theme/css/style.css")) {
				$view->themeCss .= PUBLIC_PATH . "themes/$theme/css/style.css";
			}
		}

		foreach (['custom.css', 'fonts.css'] as $css) {
			if (file_exists(DIR_THEMES . "$theme/css/$css")) {
				$view->themeCss .= ',' . PUBLIC_PATH . "themes/$theme/css/$css";
			}
		}

		$site = siteSettings($this->global['site_id'], $this->global['language_id']);
		$view->newsletter = $this->request->post['newsletter'] ?? [];
		$view->newsletter['from'] = $view->newsletter['from'] ?? $site['contact-email'];
		$view->newsletter['sender'] = $view->newsletter['sender'] ?? $site['description']['title'];
		$view->newsletter['reply'] = $view->newsletter['reply'] ?? $site['contact-email'];

		$admin_path    = \Vvveb\adminPath();
		$newsletterUrl = $admin_path . 'index.php?module=plugins/newsletter/editor&action=newsletter';
		$previewUrl = $admin_path . 'index.php?module=plugins/newsletter/editor&action=newsletter';
		$processUrl = $admin_path . 'index.php?module=plugins/newsletter/newsletter-list&action=send';

		$view->newsletter['preview_url'] = '';
		$newsletter_post_id = $view->newsletter['newsletter_post_id'] ?? $this->request->get['newsletter_post_id'] ?? null;
		$newsletter_list_id =  $view->newsletter['newsletter_list_id'] ?? $this->request->get['newsletter_list_id'] ?? null;

		if ($newsletter_post_id) {
			$view->newsletter['newsletter_post_id'] = $newsletter_post_id;
			$postModel  = new \Vvveb\Sql\Plugins\Newsletter\Newsletter_postSQL();
			if ($post = $postModel->get(['newsletter_post_id' => $newsletter_post_id])) {
				$view->newsletter['newsletter_post_id_text'] = $post['name'];
				$view->newsletter['subject'] = $post['name'];
			}

			$view->newsletter['preview_url'] = $previewUrl . '&newsletter_post_id=' . $newsletter_post_id;
		}

		if ($newsletter_list_id) {
			$view->newsletter['newsletter_list_id'] = $newsletter_list_id;
			$listModel  = new \Vvveb\Sql\Plugins\Newsletter\Newsletter_listSQL();
			if ($list = $listModel->get(['newsletter_list_id' => $newsletter_list_id])) {
				$view->newsletter['newsletter_list_id_text'] = $list['name'];
			}
		}

		$view->newsletter['step']        = 100;
		$view->newsletter['sleep_step']  = 1000;
		$view->newsletter['sleep_email'] = 100;
		$view->preview_url               = $previewUrl;
		$view->procedss_url              = $processUrl;

		$view->themeFonts = Cache::getInstance()->cache(APP, 'fonts-list-' . $theme, function () use ($theme) {
			$fonts = \Vvveb\System\Media\Font::themeFonts($theme);
			$names = [];

			if ($fonts) {
				foreach ($fonts as $font) {
					if (isset($font['font-family'])) {
						$names[$font['font-family']] = null;
					}
				}
			}

			return $names;
		}, 604800);
	}
}
