<?php

use Joomla\Utilities\ArrayHelper;

/**
 * @package DJ-Catalog2
 * @copyright Copyright (C) DJ-Extensions.com, All rights reserved.
 * @license http://www.gnu.org/licenses GNU/GPL
 * @author url: http://dj-extensions.com
 * @author email contact@dj-extensions.com
 */

defined('_JEXEC') or die('Restricted access');

JTable::addIncludePath(JPath::clean(JPATH_ADMINISTRATOR . '/components/com_djcatalog2/tables'));
require_once JPATH_ROOT . '/administrator/components/com_djcatalog2/helpers/route.php';
require_once JPATH_ROOT . '/administrator/components/com_djcatalog2/helpers/attachment.php';

jimport('joomla.mail.helper');

class DJCatalog2HelperMessenger extends JObject
{
	
	protected static $users = array();
	
	protected static $templates = array();
	
	/**
	 *
	 * @param mixed $sender :	user's ID (int) or user's email (string) or array
	 * @param mixed $recipient : user's ID (int) or user's email (string)
	 * @param array $options :   associative array containing additional options such as type of notification (template)
	 *							  'type' => type of message / template
	 *							  'notify_recipient' => true|false, default: true
	 *							  'anonymize' => true|false, default: false
	 *							  'CC' => array,
	 *							  'BCC' => array,
	 *							  'reply_to_email => string
	 *
	 * @param array $mergeData : additional data to be used in mail template
	 *
	 */
	//public function notify($message, $subject, $recipient, $options = array(), $attachments = array(), $mergeData = array(), $additionalData = null)
	public function notify($recipient, $options = array(), $attachments = array(), $mergeData = array(), $additionalData = null)
	{
		require_once JPath::clean(JPATH_ADMINISTRATOR . '/components/com_djcatalog2/helpers/mailer.php');
		
		$params = JComponentHelper::getParams('com_djcatalog2');
		
		$recipient_user = static::getUser($recipient);
		
		if (!$recipient_user) {
			$this->setError(JText::_('COM_DJCATALOG2_MESSENGER_ERROR_MISSING_RECIPIENT'));
			return false;
		}
		
		$template_type = isset($options['type']) ? $options['type'] : false;
		if (!$template_type) {
			$this->setError(JText::_('COM_DJCATALOG2_MESSENGER_ERROR_MISSING_TEMPLATE'));
			return false;
		}
		
		$template = static::getTemplate($template_type);
		if (empty($template)) {
			$this->setError(JText::_('COM_DJCATALOG2_MESSENGER_ERROR_MISSING_TEMPLATE'));
			return false;
		}
		
		$table = JTable::getInstance('Message', 'DJCatalog2Table', array());
		
		$data = array(
			'id' => null,
			'subject' => '',
			'message' => '',
			'subject' => null,
			'message' => null,
			'user_to' => $recipient_user->id,
			'recipient_name' => $recipient_user->name,
			'recipient_email' => $recipient_user->email,
			'additional_data' => $additionalData,
			'template_type' => $template_type
		);
		
		if (is_array($attachments) && count($attachments) > 0) {
			$this->processAttachments($attachments, $data);
		}
		
		$mail_data = array(
			'recipient_email' => $recipient_user->email,
			'recipient_name' => $recipient_user->name,
		);
		
		$this->prepareConfigData($mergeData);
		
		Joomla\CMS\Factory::getApplication()->triggerEvent('onDJCatalog2EmailPrepare', array(&$mail_data, &$mergeData, $template, $options));
		
		if (!empty($mergeData) && is_array($mergeData)) {
			foreach ($mergeData as $k => $v) {
				$val = $v;
				if (is_array($v)) {
					$val = implode(', ', $v);
				} else if (is_object($v)) {
					$tmpVal = ArrayHelper::fromObject($v);
					if (count($tmpVal)) {
						$val = implode(', ', $tmpVal);
					} else {
						$val = '';
					}
				}
				$mail_data[$k] = $val;
			}
		}
		
		DJCatalog2HelperMailer::prepare($mail_data, $template);
		$data['message'] = $mail_data['message'];
		$data['subject'] = $mail_data['subject'];
		
		if (!isset($options['skip_db'])) {
			try {
				if (isset($options['anonymize']) && $options['anonymize'] == true) {
					$data['recipient_email'] = $this->anonymizeEmail($data['recipient_email']);
				}
				
				$this->saveMessage($table, $data);
				
				$mail_data['notification_id'] = $table->id;
				$mail_data['sent_time'] = $table->sent_time;
				$mail_data['attachments'] = $table->attachments;
				
			} catch (Exception $e) {
				$this->setError(JText::_('COM_DJCATALOG2_MESSENGER_ERROR_COULDNT_SAVE_MESSAGE') . ' ' . $e->getMessage());
				return false;
			}
		}
		
		/*$notify_recipient = true;
		 if (isset($options['notify_recipient'])) {
		 $notify_recipient = (bool)$options['notify_recipient'];
		 }*/
		
		$CC = array();
		if (isset($options['CC'])) {
			if (is_string($options['CC'])) {
				$CC = array($options['CC']);
			} else if (is_array($options['CC'])) {
				$CC = $options['CC'];
			}
		}
		
		$BCC = array();
		if (isset($options['BCC'])) {
			if (is_string($options['BCC'])) {
				$BCC = array($options['BCC']);
			} else if (is_array($options['BCC'])) {
				$BCC = $options['BCC'];
			}
		}
		
		$replyTo = null;
		if (isset($options['reply_to_email']) && !empty($options['reply_to_email'])) {
			$replyTo = $options['reply_to_email'];
		}
		
		$notified = DJCatalog2HelperMailer::send($mail_data, $template, $CC, $BCC, $replyTo, true);
		
		//$notified = ($notify_recipient) ? DJCatalog2HelperMailer::send($mail_data, $template, $CC, $BCC, $replyTo, true) : true;
		
		/*
		 $notify_administrator = false;
		 if (isset($options['notify_administrator'])) {
		 $notify_administrator = (bool)$options['notify_administrator'];
		 }*/
		
		/*
		 if ($params->get('admin_notifications', 0) && $params->get('admin_notifications_user') && $notify_administrator) {
		 $adminUser = static::getUserById((int)$params->get('admin_notifications_user'));
		 if ($adminUser) {
		 //$template = static::getTemplate('admin_notification');
		 $admin_data = $mail_data;
		 $admin_data['recipient_email'] = $adminUser->email;
		 $admin_data['subject'] = $template->subject . ' - ' . JText::sprintf('COM_DJCATALOG2_SUBJECT_COPY_OF', $mail_data['subject']);
		 
		 DJCatalog2HelperMailer::send($admin_data, $template);
		 }
		 }*/
		
		if (!$notified) {
			$this->setError(JText::_('COM_DJCATALOG2_MESSENGER_ERROR_COULDNT_SEND_MAIL'));
			return false;
		}
		
		return true;
	}
	
	
	/**
	 *
	 * @param DJCatalog2TableMessage $table
	 * @param array $data
	 */
	protected function saveMessage(&$table, &$data)
	{
		
		// Bind the data.
		if (!$table->bind($data)) {
			throw new Exception($table->getError());
		}
		
		if ((int)$table->sent_time == 0) {
			$table->sent_time = JFactory::getDate()->toSql();
		}
		
		// Check the data.
		if (!$table->check()) {
			throw new Exception($table->getError());
		}
		
		// Store the data.
		if (!$table->store()) {
			throw new Exception($table->getError());
		}
		
		return true;
	}
	
	/**
	 *
	 * @param int|string $data user ID or user email
	 * @return JUser
	 */
	public static function getUser($data)
	{
		$user = false;
		
		if (is_numeric($data)) {
			if ((int)$data > 0) {
				$user = static::getUserById($data);
			} else {
				return false;
			}
		} else if (is_string($data)) {
			$user = static::getUserByEmail(trim($data));
		}
		
		return $user;
	}
	
	/**
	 *
	 * @param int $user_id
	 * @return JUser
	 */
	public static function getUserById($user_id, $skipChecks = false)
	{
		if (!$user_id) {
			return false;
		}
		if (!isset(static::$users[$user_id])) {
			
			$user = false;
			if ($skipChecks) {
				$user = new JUser($user_id);
			} else {
				$db = JFactory::getDbo();
				$query = $db->getQuery(true)->select('count(*)')->from('#__users')->where('id=' . (int)$user_id);
				$db->setQuery($query);
				$result = $db->loadResult();
				if ($result) {
					$user = new JUser($user_id);
				}
			}
			
			static::$users[$user_id] = $user;
		}
		
		return static::$users[$user_id];
	}
	
	
	/**
	 *
	 * @param string $email
	 * @return JUser
	 */
	public static function getUserByEmail($email)
	{
		$db = JFactory::getDbo();
		$query = $db->getQuery(true);
		$query->select('id')->from('#__users')->where('email LIKE ' . $db->quote($db->escape(trim($email))));
		$db->setQuery($query);
		$user_id = $db->loadResult();
		
		$user = new JUser();
		
		if ($user_id > 0) {
			$user = static::getUserById($user_id);
		} else {
			$user->email = $email;
			$parts = explode('@', $email, 2);
			$user->name = $parts[0];
		}
		
		return $user;
	}
	
	/**
	 *
	 * @param string $type
	 * @return object
	 */
	public static function getTemplate($type)
	{
		$type = trim($type);
		
		$template = static::findTemplate($type);
		
		if (!$template) {
			$template = new stdClass();
			$template->body = '[[message]]';
			$template->subject = '[[subject]]';
			$template->type = 'plain';
		} else {
			if (is_object($template)) {
				$template = clone $template;
			} else {
				$template = clone $plain_template;
			}
		}
		
		return $template;
	}
	
	/**
	 *
	 * @param string $type
	 * @return object|false $template or false
	 */
	protected static function findTemplate($type)
	{
		if (!isset(static::$templates[$type])) {
			$db = JFactory::getDbo();
			$query = $db->getQuery(true);
			$query->select('*')->from('#__djc2_message_templates')->where('type=' . $db->quote($type));
			$db->setQuery($query);
			$template = $db->loadObject();
			
			if (empty($template) || !$template->state) {
				return false;
			}
			
			static::$templates[$type] = $template;
		}
		
		return static::$templates[$type];
	}
	
	public static function validateDate($date, $format = 'Y-m-d')
	{
		$d = DateTime::createFromFormat($format, $date);
		return $d && $d->format($format) === $date;
	}
	
	public static function getUserAvatar($user_id)
	{
		if (!isset(static::$classifieds_avatars[$user_id])) {
			$has_avatar = false;
			$params = JComponentHelper::getParams('com_djclassifieds');
			if ((int)$user_id) {
				$db = JFactory::getDbo();
				$query = $db->getQuery(true);
				$query->select('*')->from('#__djcf_images')->where('item_id=' . (int)$user_id . ' AND type=' . $db->quote('profile'));
				$db->setQuery($query);
				
				$profile = $db->loadObject();
				if ($profile) {
					static::$classifieds_avatars[$user_id] = JUri::root() . $profile->path . $profile->name . '_ths.' . $profile->ext;
					$has_avatar = true;
				}
			}
			
			if (!$has_avatar) {
				static::$classifieds_avatars[$user_id] = JUri::root() . 'components/com_djclassifieds/assets/images/default_profile_s.png';
			}
		}
		
		return static::$classifieds_avatars[$user_id];
	}
	
	protected function processAttachments($attachments, &$data)
	{
		$fileInfos = array();
		$userTo = (!empty($data['user_to'])) ? $data['user_to'] : 0;
		
		foreach ($attachments as $file) {
			$fileInfo = DJCatalog2HelperAttachment::processFile($file, $userTo);
			if (is_array($fileInfo)) {
				$fileInfos[] = $fileInfo;
			}
		}
		
		$data['attachments'] = json_encode($fileInfos);
	}
	
	protected function anonymizeEmail($email)
	{
		$parts = explode('@', $email);
		$anonymous = '*';
		$domain = $parts[1];
		$strlen = strlen($parts[0]);
		
		if ($strlen - 2 > 0) {
			$anonymous = substr($parts[0], 0, 1);
			for ($i = 0; $i < $strlen; $i++) {
				$anonymous .= '*';
			}
			$anonymous .= substr($parts[0], -1, 1);
		}
		
		return $anonymous . '@' . $domain;
	}
	
	protected function prepareConfigData(&$data)
	{
		$app = JFactory::getApplication();
		
		/*if (!isset($data['logo'])) {
			$data['logo'] = JUri::root(false) . 'images/logo.png';
		}*/
		if (!isset($data['site_name'])) {
			$data['site_name'] = $app->getCfg('sitename');
		}
		if (!isset($data['site_url'])) {
			$data['site_url'] = JUri::root(false);
		}
	}
}
