<?php
/**
 * @package			RSForm! Pro
 * @copyright		(C) 2007-2019 www.rsjoomla.com
 * @license       	GPL, http://www.gnu.org/copyleft/gpl.html
 */

defined('_JEXEC') or die;

use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\Factory;
use Joomla\CMS\Table\Table;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Form\Form;
use Joomla\CMS\HTML\HTMLHelper;

/**
 * Class plgSystemRsfpgetresponse
 */
class plgSystemRsfpgetresponse extends CMSPlugin
{

	/**
	 * @var bool
	 */
	protected $autoloadLanguage = true;

	/**
	 * @param $form
	 *
	 * @return bool|void
	 */
	public function onRsformFormSave($form)
	{
		$app = Factory::getApplication();
		$data = array(
			'form_id'			 => $form->FormId,
			'enable_getresponse' => $app->input->post->get('enable_getresponse', 0, 'int'),
			'getresponse_update' => $app->input->post->get('getresponse_update', 0, 'int'),
			'getresponse_list' 	 => $app->input->post->get('getresponse_list', '', 'raw'),
			'vars' 	 			 => $app->input->post->get('getresponse_vars', array(), 'array')
		);

		$row = $this->getTable();
		if (!$row)
		{
			return;
		}
		if (!$row->bind($data))
		{
			return false;
		}

		$row->check();

		return $row->store();
	}

	protected function getTable()
	{
		return Table::getInstance('RSForm_GetResponse', 'Table');
	}

	/**
	 * @param $tabs
	 */
	public function onRsformBackendAfterShowConfigurationTabs($tabs)
	{
		$tabs->addTitle(Text::_('RSFP_GETRESPONSE'), 'rsfp-getresponse');
		$tabs->addContent($this->configurationScreen());
	}

	/**
	 * @return string
	 */
	protected function configurationScreen()
	{
		ob_start();

		Form::addFormPath(__DIR__ . '/forms');

		$form = Form::getInstance( 'plg_system_rsfpgetresponse.configuration', 'configuration', array('control' => 'rsformConfig'), false, false );
		$form->bind($this->loadFormData());

		?>
		<div id="page-getresponse" class="form-horizontal">
			<?php
			foreach ($form->getFieldsets() as $fieldset)
			{
				if ($fields = $form->getFieldset($fieldset->name))
				{
					foreach ($fields as $field)
					{
						echo $field->renderField();
					}
				}
			}
			?>
		</div>
		<?php

		$contents = ob_get_contents();
		ob_end_clean();

		return $contents;
	}

	private function loadFormData()
	{
		$data 	= array();
		$db 	= Factory::getDbo();

		$query = $db->getQuery(true)
			->select('*')
			->from($db->qn('#__rsform_config'))
			->where($db->qn('SettingName') . ' LIKE ' . $db->q('getresponse.%', false));
		if ($results = $db->setQuery($query)->loadObjectList())
		{
			foreach ($results as $result)
			{
				$data[$result->SettingName] = $result->SettingValue;
			}
		}

		return $data;
	}

	/**
	 *
	 */
	public function onRsformBackendAfterShowFormEditTabsTab()
	{
		echo '<li><a href="javascript: void(0);" id="getresponse"><span class="rsficon rsficon-envelope-square"></span><span class="inner-text">' . Text::_('RSFP_GETRESPONSE') . '</span></a></li>';
	}

	/**
	 * @throws Exception
	 */
	public function onRsformBackendAfterShowFormEditTabs()
	{
		$row    = $this->getTable();
		$app    = Factory::getApplication();
		$formId = $app->input->getInt('formId', 0);

		if (!$row)
		{
			return;
		}

		$row->load($formId);

		if (!RSFormProHelper::getConfig('getresponse.key'))
		{
			?>
			<div id="getresponsediv">
				<h3 class="rsfp-legend"><?php echo Text::_('RSFP_GETRESPONSE') ?></h3>
				<div class="alert alert-warning"><?php echo Text::_('RSFP_GETRESPONSE_NOTOKEN') ?></div>
			</div>
			<?php
			return;
		}

		if ($row->vars)
		{
			$row->vars = unserialize($row->vars);
		}

		require_once JPATH_ADMINISTRATOR . '/components/com_rsform/helpers/getresponse/GetResponseAPI3.class.php';

		$fields_array = $this->_getFields($formId);
		$fields       = array(
			HTMLHelper::_('select.option', '', Text::_('JSELECT')),
		);
		foreach ($fields_array as $field)
		{
			$fields[] = HTMLHelper::_('select.option', '{' . $field . ':value}', $field);
		}

		// Merge Vars
		$merge_vars = $this->standardFields();

		try
		{
			$response = new GetResponse(RSFormProHelper::htmlEscape(RSFormProHelper::getConfig('getresponse.key')));

			$ping = $response->ping();

			if (isset($ping->code))
			{
				?>
				<div id="getresponsediv">
					<h3 class="rsfp-legend"><?php echo Text::_('RSFP_GETRESPONSE') ?></h3>
					<div class="alert alert-error" style="width: 620px;"><?php echo Text::sprintf('RSFP_GETRESPONSE_ERROR', $ping->code, $ping->message); ?></div>
				</div>
				<?php

				return false;
			}

			$custom_fields = $response->getCustomFields();
			$custom_values = array();

			if (!empty($custom_fields))
			{
				foreach ($custom_fields as $custom_field)
				{
					$merge_vars[$custom_field->name] = $custom_field->name;
				}

				foreach ($custom_fields as $custom_field)
				{
					$custom_values[$custom_field->name] = $custom_field->values;
				}
			}

			$custom_values = array_filter($custom_values);

			Factory::getDocument()->addScriptDeclaration('
jQuery(document).ready(function ($) {
	var $possible_values = $(\'.btn-possible-values\');

	$possible_values.each(function(){
		$(this).click(function(e){
			e.preventDefault();
			$(this).next(\'p\').slideToggle(\'fast\');
		});
	});
});
');

			Factory::getDocument()->addStyleDeclaration('
	.getresponse_possible_values .btn-possible-values{
		display:block;
		clear:both;
		margin-bottom:20px;
	}
	.getresponse_possible_values p{
		display:none;
	}
');
			?>
			<div id="getresponsediv">
				<h3 class="rsfp-legend"><?php echo Text::_('RSFP_GETRESPONSE') ?></h3>
				<table class="table table-bordered">
					<tr>
						<td>
							<label for="enable_getresponse"><?php echo Text::_('RSFP_GETRESPONSE_ENABLE'); ?></label>
						</td>
						<td><?php echo RSFormProHelper::renderHTML('select.booleanlist', 'enable_getresponse', '', $row->enable_getresponse); ?></td>
					</tr>
					<tr>
						<td>
							<label for="getresponse_update"><?php echo Text::_('RSFP_GETRESPONSE_UPDATE_IF_EXISTS'); ?></label>
						</td>
						<td><?php echo RSFormProHelper::renderHTML('select.booleanlist', 'getresponse_update', '', $row->getresponse_update); ?></td>
					</tr>
					<tr>
						<td>
							<label for="getresponse_list"><?php echo Text::_('RSFP_GETRESPONSE_LISTS'); ?></label>
						</td>
						<td>
							<?php
							$campaigns = $response->getCampaigns();
							$lists     = array();

							foreach ($campaigns as $item)
							{
								$lists[] = HTMLHelper::_('select.option', $item->campaignId, $item->name);
							}

							?>
							<select name="getresponse_list" id="getresponse_list">
								<?php echo HTMLHelper::_('select.options',
									$lists,
									'value', 'text', RSFormProHelper::htmlEscape($row->getresponse_list));
								?>
							</select>

						</td>
					</tr>
					<?php
					foreach ($merge_vars as $merge_var => $title)
					{
						?>
						<tr>
							<td>
								<label for="<?php echo 'getresponse_vars' . $merge_var ?>"><?php echo $title; ?></label>
							</td>
							<td><?php echo HTMLHelper::_('select.genericlist', $fields, 'getresponse_vars[' . $merge_var . ']', null, 'value', 'text', isset($row->vars[$merge_var]) ? $row->vars[$merge_var] : null); ?>

								<?php
								if (isset($custom_values[$merge_var]))
								{?>
									<div id="getresponse_possible_values_<?php echo $merge_var; ?>" class="getresponse_possible_values">
										<button class="btn btn-secondary btn-possible-values" type="button"><?php echo Text::_('RSFP_POSSIBLE_VALUES') ?></button>
										<p><small><?php echo nl2br(RSFormProHelper::htmlEscape(implode("\n", $custom_values[$merge_var]))); ?></small></p>
									</div>

								<?php } ?>

							</td>

						</tr>
					<?php
					}
					?>
				</table>
			</div>

			<?php
		}
		catch (Exception $e)
		{
			$app->enqueueMessage($e->getMessage(), 'error');
		}
	}

	/**
	 * @param $args
	 *
	 * @throws Exception
	 */
	public function onRsformFrontendAfterFormProcess($args)
	{
		$formId       = (int) $args['formId'];
		$SubmissionId = (int) $args['SubmissionId'];
		$app          = Factory::getApplication();
		$row		  = $this->getTable();

		if ($row && $row->load($formId) && $row->enable_getresponse)
		{
			try
			{
				require_once JPATH_ADMINISTRATOR . '/components/com_rsform/helpers/getresponse/GetResponseAPI3.class.php';
				$response = new GetResponse(RSFormProHelper::htmlEscape(RSFormProHelper::getConfig('getresponse.key')));

				$custom_fields = array();

				foreach ($response->getCustomFields() as $field)
				{
					$custom_fields[$field->name] = $field->customFieldId;
				}

				$ping = $response->ping();

				if (isset($ping->code))
				{
					throw new Exception(Text::sprintf('RSFP_GETRESPONSE_ERROR', $ping->code, $ping->message));
				}

				list($args['placeholders'], $args['values']) = RSFormProHelper::getReplacements($SubmissionId);

				// Grab configured fields
				$fields = array();
				if ($row->vars)
				{
					$fields = unserialize($row->vars);
				}

				if (!is_array($fields))
				{
					$fields = array();
				}

				$element = array(
					'campaign'          => array(
						'campaignId' => $row->getresponse_list
					),
					'dayOfCycle'        => 0,
					'customFieldValues' => array(),
				);

				foreach ($fields as $field => $value)
				{
					// Custom fields should be in a separate array
					if ($field == 'name' || $field == 'email')
					{
						$element[$field] = str_replace($args['placeholders'], $args['values'], $value);
					}
					else
					{
						if ($value !== '')
						{
							$element['customFieldValues'][] = array(
								'customFieldId' => $custom_fields[$field],
								'value'         => array(
									str_replace($args['placeholders'], $args['values'], $value)
								),
							);
						}
					}
				}

				if ((int) $row->getresponse_update)
				{

					$result = $response->getContacts(array(
						'query' => array(
							'email' => $element['email'],
						),
					));

					$result = (array) $result;

					if (!empty($result))
					{
						$contact = $response->updateContact($result[0]->contactId, $element);
					}
					else
					{
						$contact = $response->addContact($element);
					}
				}
				else
				{
					$contact = $response->addContact($element);
				}

				if (property_exists($contact, 'code'))
				{
					throw new Exception(Text::sprintf('RSFP_GETRESPONSE_ERROR', $contact->code, $contact->message));
				}

			}
			catch (Exception $e)
			{
				$app->enqueueMessage($e->getMessage(), 'error');

				if (!empty($contact) && property_exists($contact, 'context'))
				{
					foreach ($contact->context as $context)
					{
						if (is_object($context))
						{
							if (is_array($context->fieldName))
							{
								$fieldName = $context->fieldName[0];

								if (isset($context->fieldName[1]))
								{
									$fieldName .= ' ' . $context->fieldName[1];
								}
							}
							else
							{
								$fieldName = $context->fieldName;
							}

							$app->enqueueMessage(Text::sprintf('RSFP_GETRESPONSE_CONTEXT_ERROR', $fieldName, $context->errorDescription), 'error');
						}
						else
						{
							$app->enqueueMessage(Text::sprintf('RSFP_GETRESPONSE_CONTEXT_ERROR_2', $context), 'error');
						}
					}
				}
			}
		}
	}

	/**
	 * @return array
	 */
	public function standardFields()
	{
		return array(
			'name'  => Text::_('RSFP_GETRESPONSE_NAME'),
			'email' => Text::_('RSFP_GETRESPONSE_EMAIL'),
		);
	}

	/**
	 * @param $formId
	 *
	 * @return mixed
	 */
	protected function _getFields($formId)
	{
		$db    = Factory::getDbo();
		$query = $db->getQuery(true)
			->select($db->qn('p.PropertyValue'))
			->from($db->qn('#__rsform_components', 'c'))
			->join('LEFT', $db->qn('#__rsform_properties', 'p') . ' ON (' . $db->qn('c.ComponentId') . '=' . $db->qn('p.ComponentId') . ')')
			->where($db->qn('c.FormId') . '=' . $db->q($formId))
			->where($db->qn('p.PropertyName') . '=' . $db->q('NAME'))
			->order($db->qn('c.Order') . ' ' . $db->escape('ASC'));

		return $db->setQuery($query)->loadColumn();
	}

	public function onRsformBackendFormCopy($args)
	{
		$formId = $args['formId'];
		$newFormId = $args['newFormId'];

		if ($row = $this->getTable())
		{
			if ($row->load($formId))
			{
				$row->form_id = $newFormId;
				if ($row->check())
				{
					$row->store();
				}
			}
		}
	}

	/**
	 * @param $formId
	 */
	public function onRsformFormDelete($formId)
	{
		if ($row = $this->getTable())
		{
			$row->delete($formId);
		}
	}

	/**
	 * @param $form
	 * @param $xml
	 * @param $fields
	 */
	public function onRsformFormBackup($form, $xml, $fields)
	{
		if ($row = $this->getTable())
		{
			if ($row->load($form->FormId))
			{
				$row->check();

				$data = $row->getProperties();
				unset($data['form_id']);

				$xml->add('getresponse');
				foreach ($data as $property => $value)
				{
					$xml->add($property, $value);
				}
				$xml->add('/getresponse');
			}
		}
	}

	/**
	 * @param $form
	 * @param $xml
	 * @param $fields
	 */
	public function onRsformFormRestore($form, $xml, $fields)
	{
		if (isset($xml->getresponse))
		{
			$data = array(
				'form_id' => $form->FormId
			);
			foreach ($xml->getresponse->children() as $property => $value)
			{
				$data[$property] = (string) $value;
			}

			$row = $this->getTable();
			$row->save($data);
		}
	}

	/**
	 *
	 */
	public function onRsformBackendFormRestoreTruncate()
	{
		Factory::getDbo()->truncateTable('#__rsform_getresponse');
	}
}