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

// no direct access
defined('_JEXEC') or die;

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

/**
 * RSForm! Pro system plugin
 */
class plgSystemRsfpzohocrm extends CMSPlugin
{	
	/**
	 * @var bool
	 */
	protected $autoloadLanguage = true;
	
	public function onRsformFormSave($form)
	{
		$app             = Factory::getApplication();
		$data            = $app->input->post->get('zohocrm', array(), 'array');
		$data['form_id'] = $form->FormId;
		$row = $this->getTable();

		if ($row)
		{
			if (!$row->save($data))
			{
				$app->enqueueMessage($row->getError(), 'error');
			}
		}
	}

	protected function getTable()
	{
		return Table::getInstance('RSForm_ZohoCrm', 'Table');
	}
	
	public function onRsformBackendFormCopy($args){
		$formId = $args['formId'];
		$newFormId = $args['newFormId'];

		if ($row = $this->getTable() )
		{
			if ($row->load($formId))
			{
				if (!$row->bind(array('form_id' => $newFormId)))
				{
					return false;
				}

				$row->check();

				return $row->store();
			}
		}
	}

	public function onRsformBackendAfterShowFormEditTabs() {
		$formId = Factory::getApplication()->input->getInt('formId',0);
		$row	= $this->getTable();
		$lists	= array();
		
		if (!$row) {
			return;
		}
		
		$row->load($formId);
		$row->zh_merge_vars = @unserialize($row->zh_merge_vars);
		if ($row->zh_merge_vars === false) {
			$row->zh_merge_vars = array();
		}
		
		// Fields
		$fields_array = $this->_getFields($formId);
		$fields = array();
		foreach ($fields_array as $field)
		{
			$fields[] = HTMLHelper::_('select.option', $field, $field);
		}
		
		$file_fields_array = $this->_getFields($formId, 'files');
		
		$file_fields = array();
		foreach ($file_fields_array as $field)
		{
			$file_fields[] = HTMLHelper::_('select.option', $field, $field);
		}
		
		// Trigger workflow
		$lists['zh_trigger'] = RSFormProHelper::renderHTML('select.booleanlist','zohocrm[zh_wf_trigger]','',$row->zh_wf_trigger);

		$lists['zh_duplicates'] = RSFormProHelper::renderHTML('select.booleanlist','zohocrm[zh_duplicate_check]','',$row->zh_duplicate_check);
		$lists['zh_lar_id'] = '<input type="text" name="zohocrm[zh_lar_id]"  value="'.$row->zh_lar_id.'"/>';
		
		// Approval
		$lists['zh_approval'] = RSFormProHelper::renderHTML('select.booleanlist','zohocrm[zh_is_approval]','',$row->zh_is_approval );
		
		// Format type
		$format = array(
			HTMLHelper::_('select.option', 1, Text::_('RSFP_ZOHOCRM_FORMAT_1')),
			HTMLHelper::_('select.option', 2, Text::_('RSFP_ZOHOCRM_FORMAT_2'))
		);
		
		$lists['zh_format'] = HTMLHelper::_('select.genericlist', $format, 'zohocrm[zh_format]', '', 'value', 'text', $row->zh_format);
		
		// Published
		$lists['zh_published'] = RSFormProHelper::renderHTML('select.booleanlist','zohocrm[zh_published]','',$row->zh_published);

		// Based on another field
		$lists['zh_action'] = HTMLHelper::_('select.genericlist', array(
			HTMLHelper::_('select.option', 1, Text::_('RSFP_ZOHOCRM_ACTION_SUBSCRIBE')),
			HTMLHelper::_('select.option', 2, Text::_('RSFP_ZOHOCRM_LET_USER_DECIDE'))
		), 'zohocrm[zh_action]', 'onchange="zohoChangeAction(this.value);"', 'value', 'text', $row->zh_action);

		$lists['zh_action_field'] = HTMLHelper::_('select.genericlist', $fields, 'zohocrm[zh_action_field]', $row->zh_action != 2 ? 'disabled="disabled"' : '', 'value', 'text', $row->zh_action_field);

		// Debugging
		$lists['zh_debug'] = RSFormProHelper::renderHTML('select.booleanlist','zohocrm[zh_debug]','',$row->zh_debug);
		
		// Track GA
		$lists['zh_track_ga'] = RSFormProHelper::renderHTML('select.booleanlist','zohocrm[zh_track_ga]','',$row->zh_track_ga);

		// Fields
		$layouts = null;
		$lists['zh_fields'] = array();

		$lists['zh_layout_id'] = null;

		$found_layouts = array();
		$default_layout = null;

		// load the class
		require_once JPATH_ADMINISTRATOR . '/components/com_rsform/helpers/zohocrm/zohocrmapi.php';

		$configuration_error = false;
		try {
			$config = array(
				'grant_token' => RSFormProHelper::getConfig('zohocrm.grant_token'),
				'currentUserEmail' => RSFormProHelper::getConfig('zohocrm.user_email'),
				'client_id' => RSFormProHelper::getConfig('zohocrm.client_id'),
				'client_secret' => RSFormProHelper::getConfig('zohocrm.client_secret'),
				'apiBaseUrl' => RSFormProHelper::getConfig('zohocrm.host'),
			);

			$zohocrm = new RSFPZohoCrm($config);
		} catch (Exception $e) {
			$configuration_error = $e->getMessage();
		}

		$token_error = false;
		if (!$configuration_error) {
			try {
				// verify the auth_token to be generated
				$zohocrm->check_if_auth_token_exist();

				$layouts = $zohocrm->getFields();
			} catch (Exception $e) {
				$token_error = true;
				Factory::getApplication()->enqueueMessage('Zoho CRM: ' . $e->getMessage(), 'error');
			}

			if (is_array($layouts)) {
				foreach ($layouts as $layout_id => $layout) {
					if (empty($layout['sections'])) {
						continue;
					}
					// store the layout
					$found_layouts[] = HTMLHelper::_('select.option',$layout_id, $layout['layout_name']);
					// in case there is only one layout
					$default_layout = $layout_id;

					// the actual sections for the layout
					$sections = $layout['sections'];
					foreach ($sections as $section) {
						if (is_array($section)) {
							foreach ($section as $field) {
								$default_field_value = null;
								// if there is a layout
								if (isset($row->zh_merge_vars[$layout_id][$field->dv]))
								{
									$default_field_value = $row->zh_merge_vars[$layout_id][$field->dv];
								}
								// legacy - if no id is selected assumed is the "standard one"
								else if (isset($row->zh_merge_vars[$field->dv])) {
									$default_field_value = $row->zh_merge_vars[$field->dv];
								}
								
								if ($field->dv == 'link_attachment' && is_array($default_field_value))
								{
									$lists['zh_fields'][$layout_id][$field->label] = array();
									
									foreach ($default_field_value as $value)
									{
										$lists['zh_fields'][$layout_id][$field->label][] = HTMLHelper::_('select.genericlist', $fields, 'zohocrm[zh_merge_vars]['.$layout_id.'][' . $field->dv . '][]', null, 'value', 'text', $value);
									}
								}
								else 
								{
									$lists['zh_fields'][$layout_id][$field->label] = HTMLHelper::_('select.genericlist', (($field->dv == 'file_attachment' || $field->dv == 'Record_Image') ? $file_fields : $fields), 'zohocrm[zh_merge_vars]['.$layout_id.'][' . $field->dv . ']'.($field->dv == 'link_attachment' ? '[]' : ''), null, 'value', 'text', $default_field_value);
								}
							}
						}
					}
				}
			}
		}

		if (!empty($found_layouts))
		{
			if (count($found_layouts) > 1)
			{
				// If more than one layout, add a 'please select'
				$default_layout = $row->zh_layout_id;
				array_unshift($found_layouts, HTMLHelper::_('select.option', '', Text::_('RSFP_ZOHOCRM_LAYOUT_SELECT')));
			}

			$lists['zh_layout_id'] = HTMLHelper::_('select.genericlist', $found_layouts, 'zohocrm[zh_layout_id]', 'onchange="zohoDisplayLayout()"', 'value', 'text', $default_layout);
		}
		?>
		<div id="zohocrmdiv">
			<h3 class="rsfp-legend"><?php echo Text::_('RSFP_ZOHOCRM'); ?></h3>
			<div class="alert alert-info"><?php echo Text::_('PLG_SYSTEM_RSFPZOHOCRM_DESC'); ?></div>
			<table class="table table-bordered">
				<tr>
					<td nowrap><?php echo Text::_('RSFP_ZOHOCRM_USE_INTEGRATION'); ?></td>
					<td><?php echo $lists['zh_published']; ?></td>
				</tr>
				<tr>
					<td>
						<span class="hasTooltip" title="<?php echo Text::_('RSFP_ZOHOCRM_ACTION_DESC'); ?>"><?php echo Text::_('RSFP_ZOHOCRM_ACTION'); ?></span>
					</td>
					<td><?php echo $lists['zh_action']; ?><?php echo $lists['zh_action_field']; ?>
						<p><?php echo Text::_('RSFP_ZOHOCRM_ACTION_WARNING'); ?></p></td>
				</tr>
				<tr>
					<td nowrap>
						<span class="hasTooltip" title="<?php echo Text::_('RSFP_ZOHOCRM_SHOW_ZOHO_MESSAGES_DESC'); ?>"><?php echo Text::_('RSFP_ZOHOCRM_SHOW_ZOHO_MESSAGES'); ?></span>
					</td>
					<td><?php echo $lists['zh_debug']; ?></td>
				</tr>
				<tr>
					<td nowrap>
						<span class="hasTooltip" title="<?php echo Text::_('RSFP_ZOHOCRM_TRIGGER_DESC'); ?>"><?php echo Text::_('RSFP_ZOHOCRM_TRIGGER'); ?></span>
					</td>
					<td><?php echo $lists['zh_trigger']; ?></td>
				</tr>

				<tr>
					<td nowrap>
						<span class="hasTooltip" title="<?php echo Text::_('RSFP_ZOHOCRM_DUPLICATE_DESC'); ?>"><?php echo Text::_('RSFP_ZOHOCRM_DUPLICATE'); ?></span>
					</td>
					<td><?php echo $lists['zh_duplicates']; ?></td>
				</tr>

				<tr>
					<td nowrap>
						<span class="hasTooltip" title="<?php echo Text::_('RSFP_ZOHOCRM_APPROVAL_DESC'); ?>"><?php echo Text::_('RSFP_ZOHOCRM_APPROVAL'); ?></span>
					</td>
					<td><?php echo $lists['zh_approval']; ?></td>
				</tr>
				<tr>
					<td nowrap>
						<span class="hasTooltip" title="<?php echo Text::_('RSFP_ZOHOCRM_TRACK_GA_DESC'); ?>"><?php echo Text::_('RSFP_ZOHOCRM_TRACK_GA'); ?></span>
						<br />
						<a href="https://help.zoho.com/portal/helpcenter/articles/i-use-a-third-party-builder-and-not-zoho-crm-to-create-web-forms-how-do-i-set-it-up-for-google-adwords-integration-with-zoho-crm" target="_blank"><small><?php echo Text::_('RSFP_ZOHOCRM_MORE_INFO'); ?></small></a>
					</td>
					<td><?php echo $lists['zh_track_ga']; ?></td>
				</tr>
				<tr>
					<td nowrap>
						<span class="hasTooltip" title="<?php echo Text::_('RSFP_ZOHOCRM_LEAD_ASSIGNMENT_RULE_ID_DESC'); ?>"><?php echo Text::_('RSFP_ZOHOCRM_LEAD_ASSIGNMENT_RULE_ID'); ?></span>
					</td>
					<td><?php echo $lists['zh_lar_id']; ?></td>
				</tr>
				<tr>
					<td nowrap>
						<span class="hasTooltip" title="<?php echo Text::_('RSFP_ZOHOCRM_FORMAT_DESC'); ?>"><?php echo Text::_('RSFP_ZOHOCRM_FORMAT'); ?></span>
					</td>
					<td><?php echo $lists['zh_format']; ?></td>
				</tr>
			</table>

			<h3 class="rsfp-legend"><?php echo Text::_('RSFP_ZOHOCRM_MERGE_VARS'); ?></h3>
			<p><?php echo Text::_('RSFP_ZOHOCRM_MERGE_VARS_DESC'); ?></p>
			<?php
			if ($configuration_error)
			{
				?>
				<div class="alert alert-error"><?php echo $configuration_error; ?></div>
				<?php
			}
			if ($token_error)
			{
				?>
				<div class="alert alert-error"><?php echo Text::_('RSFP_ZOHOCRM_EMPTY_ACCESS_TOKEN'); ?></div>
				<?php
			}

			if (is_array($layouts))
			{
			?>
			<table class="table table-bordered">
				<tr>
					<td nowrap>
						<span class="hasTooltip" title="<?php echo Text::_('RSFP_ZOHOCRM_LAYOUT_DESC'); ?>"><?php echo Text::_('RSFP_ZOHOCRM_LAYOUT'); ?></span>
					</td>
					<td><?php echo $lists['zh_layout_id']; ?></td>
				</tr>
				<?php
				foreach ($layouts as $layout_id => $layout)
				{
					if (empty($layout['sections']))
					{
						continue;
					}
					$sections = $layout['sections'];

					foreach ($sections as $name => $section)
					{
						?>
						<tr class="rsfz_<?php echo $layout_id; ?> rsfz_hide" style="display:none">
							<td colspan="2" class="key center" align="center"><strong><?php echo $name; ?></strong></td>
						</tr>
						<?php
						if (is_array($section))
						{
							foreach ($section as $field)
							{
								// make the display list as an array
								$display_list_field = is_array($lists['zh_fields'][$layout_id][$field->label]) ? $lists['zh_fields'][$layout_id][$field->label] : array($lists['zh_fields'][$layout_id][$field->label]);
								
								foreach ($display_list_field as $i => $display_field) 
								{
								?>
									<tr class="rsfz_<?php echo $layout_id; ?> rsfz_hide" style="display:none">
										<td nowrap="nowrap" align="right" valign="top" class="key">
											<?php echo $field->label; ?><?php echo ($field->req === true || $field->req === 'true') ? ' *' : ''; ?>
											<?php if ($field->type == 'link_attachment' && $i == 0) { ?>
												<button type="button" class="btn btn-sm btn-small btn-primary zh_link_add" onclick="zohoCopyLink(this)"><?php echo Text::_('RSFP_ZOHOCRM_ADD_ANOTHER_LINK'); ?></button>
											<?php } else if ($field->type == 'link_attachment' && $i > 0){ ?>
												<button type="button" class="btn btn-sm btn-small btn-danger" onclick="zohoRemoveLink(this)"><?php echo Text::_('RSFP_ZOHOCRM_REMOVE_LINK'); ?></button>
											<?php } ?>
										</td>
										<td><?php
											echo $display_field;
											if (!empty($field->val) && is_array($field->val))
											{
												$fieldValues = array();
												foreach ($field->val as $displayValue => $value)
												{
													if (is_object($value) && isset($value->content))
													{
														$value = $value->content;
													}

													// failsafe
													if (!is_object($value))
													{
														$fieldValues[] = RSFormProHelper::htmlEscape($displayValue);
													}
												}
												?>
												<div><small><?php echo Text::sprintf('RSFP_ZOHOCRM_POSSIBLE_VALUES', implode('<br />', $fieldValues)); ?></small></div>
											<?php
											}
											?>
										</td>
									</tr>
								<?php
								}
							}
						}
					}
				}
				?>
			</table>
			<?php
			}
			?>
		</div>
		<?php

		Factory::getDocument()->addScriptDeclaration("
jQuery(function() {
	zohoDisplayLayout();
});

function zohoChangeAction(value) {
	jQuery('#zohocrmzh_action_field').prop('disabled', value !== '2');
}

function zohoCopyLink(element) {
	var tr_element = jQuery(element).parent().parent();
	var tr_clone = jQuery(tr_element).clone();
	
	jQuery(tr_clone).find('.zh_link_add').after('<button type=\"button\" class=\"btn btn-sm btn-small btn-danger\" onclick=\"zohoRemoveLink(this)\">".Text::_('RSFP_ZOHOCRM_REMOVE_LINK')."</button>');
	jQuery(tr_clone).find('.zh_link_add').remove();
	jQuery(tr_clone).find('select').val('- IGNORE -');
	
	jQuery(tr_element).after(tr_clone);
}

function zohoRemoveLink(element) {
	var tr_element = jQuery(element).parent().parent();
	jQuery(tr_element).remove();
}
		
function zohoDisplayLayout() {
    jQuery('.rsfz_hide').css('display', 'none');
    var selected_layout = jQuery('#zohocrmzh_layout_id').val();

    if (jQuery('.rsfz_'+selected_layout).length) {
        jQuery('.rsfz_'+selected_layout).css('display', 'table-row');
    }
}");
	}
	
	public function onRsformBackendAfterShowFormEditTabsTab() {
		echo '<li><a href="javascript: void(0);" id="zohocrm"><span class="rsficon rsficon-stack"></span><span class="inner-text">'.Text::_('RSFP_ZOHOCRM_INTEGRATION').'</span></a></li>';
	}
	
	public function onRsformFrontendBeforeStoreSubmissions($args)
	{
		$db				= Factory::getDbo();
		$formId			= (int) $args['formId'];
		$SubmissionId   = (int) $args['SubmissionId'];
		$row            = $this->getTable();
		
		if ($row && $row->load($formId) && $row->zh_published && $row->zh_merge_vars)
		{
			$form =& $args['post'];

			if ($row->zh_action == 2)
			{
				$value = '';
				if (isset($form[$row->zh_action_field]))
				{
					$value = is_array($form[$row->zh_action_field]) ? implode('', $form[$row->zh_action_field]) : $form[$row->zh_action_field];
				}

				if ($value != 'subscribe')
				{
					return;
				}
			}

			require_once JPATH_ADMINISTRATOR . '/components/com_rsform/helpers/zohocrm/zohocrmapi.php';
			$config = array(
				'grant_token' => RSFormProHelper::getConfig('zohocrm.grant_token'),
				'currentUserEmail' => RSFormProHelper::getConfig('zohocrm.user_email'),
				'client_id' => RSFormProHelper::getConfig('zohocrm.client_id'),
				'client_secret' => RSFormProHelper::getConfig('zohocrm.client_secret'),
				'apiBaseUrl' => RSFormProHelper::getConfig('zohocrm.host'),
			);

			$zohocrm = new RSFPZohoCrm($config);
			$zohocrm->debug = $row->zh_debug;
			
			$row->zh_merge_vars = @unserialize($row->zh_merge_vars);
			if ($row->zh_merge_vars === false)
				$row->zh_merge_vars = array();

			$fields_type = array();
			try {
				// get the field types from zoho
				$layouts = $zohocrm->getFields();

				if (is_array($layouts))
				{
					foreach ($layouts as $layout_id => $layout)
					{
						if ($row->zh_layout_id != $layout_id || empty($layout['sections']))
						{
							continue;
						}

						// the actual sections for the layout
						foreach ($layout['sections'] as $section)
						{
							if (is_array($section))
							{
								foreach ($section as $field)
								{
									$fields_type[$field->dv] = $field->type;
								}
							}
						}
					}
				}

				$data = array(
					'data' => array(),
					'trigger' => ($row->zh_wf_trigger ? array('workflow') : array()),
					'lar_id' => null
				);

				if ($row->zh_is_approval) {
					$data['trigger'][] = 'approval';
				}

				if (!empty($row->zh_layout_id)) {
					$data['layout_id'] = $row->zh_layout_id;
				}

				if (!empty($row->zh_lar_id)) {
					$data['lar_id'] = $row->zh_lar_id;
				}

				if (!empty($row->zh_duplicate_check)) {
					$data['duplicate_check'] = $row->zh_duplicate_check;
				}
				
				// the duplicates are checked every time according to https://www.zoho.com/crm/help/api/v2/#create-specify-records

				if (!empty($row->zh_merge_vars)) {
					$record = array();
					// extract merge_vars from proper layout id if any
					if (!empty($row->zh_layout_id)) {
						$row->zh_merge_vars = $row->zh_merge_vars[$row->zh_layout_id];
					}
					
					// get the submission values (images)
					require_once JPATH_ADMINISTRATOR . '/components/com_rsform/helpers/submissions.php';
					$submission = RSFormProSubmissionsHelper::getSubmission($SubmissionId);
					
					foreach ($row->zh_merge_vars as $tag => $field) {
						if ($field == '- IGNORE -') continue;
						
						if ($tag == 'Record_Image')
						{
							if (isset($submission->values) && isset($submission->values[$field]))
							{
								$images = RSFormProHelper::explode($submission->values[$field]);
								if ($images)
								{
									$data['record_image'] = $images[0];
								}
							}
							continue;
						}
						
						if ($tag == 'file_attachment')
						{
							if (isset($submission->values) && isset($submission->values[$field]))
							{
								$data['file_attachment'] = $submission->values[$field];
							}
							continue;
						}
						
						if ($tag == 'link_attachment')
						{
							if (is_array($field))
							{
								$links = array();
								foreach ($field as $link)
								{
									if (!empty($form[$link]))
									{
										$links[] = $form[$link];
									}
								}
								
								if (!empty($links))
								{
									$data['link_attachment'] = $links;
								}
							}
							
							continue;
						}
						
						if (!isset($form[$field]))
							$form[$field] = '';

						// workaround for the checkbox field from zohocrm
						if (isset($fields_type[$tag]))
						{
							switch ($fields_type[$tag])
							{
								case 'boolean':
									if (is_array($form[$field]))
									{
										$form[$field] = $form[$field][0];
									}

									$form[$field] = $form[$field] !== '' ? true : false;
									break;

								case 'multiselectpicklist':
									if (!is_array($form[$field]))
									{
										$form[$field] = array($form[$field]);
									}
									break;

								case 'picklist':
									if (is_array($form[$field]))
									{
										$form[$field] = array_shift($form[$field]);
									}
									break;
							}
						}

						$record[$tag] = $form[$field];
					}

					
					if (!empty($row->zh_track_ga)) {
						if ($zc_gad = Factory::getApplication()->input->getString('zc_gad')) {
							$record['$gclid'] = $zc_gad;
						}
					}

					if (!empty($record)) {
						$data['data'][] = (object)$record;
					}
				}

				$zohocrm->addLead($data);
			} catch (Exception $e) {
				Factory::getApplication()->enqueueMessage('Zoho CRM: '.$e->getMessage(), 'error');
				return false;
			}
		}
	}
	
	public function onRsformFrontendBeforeFormDisplay($args)
	{
		$formId			= (int) $args['formId'];
		$row            = $this->getTable();

		if ($row && $row->load($formId) && $row->zh_published && !empty($row->zh_track_ga))
		{
			$args['formLayout'] = str_replace('</form>', '<input type="hidden" id="zc_gad" name="zc_gad" value="" /><script type="text/javascript" src="https://crm.'.RSFormProHelper::getConfig('zohocrm.host').'/crm/javascript/zcga.js"></script></form>', $args['formLayout']);
		}
	}
	
	public function onRsformBackendAfterShowConfigurationTabs($tabs)
	{
		$tabs->addTitle(Text::_('RSFP_ZOHOCRM'), 'page-zohocrm');
		$tabs->addContent($this->configurationScreen());
	}

	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('zohocrm.%', false));
		if ($results = $db->setQuery($query)->loadObjectList())
		{
			foreach ($results as $result)
			{
				$data[$result->SettingName] = $result->SettingValue;
			}
		}

		return $data;
	}

	/**
	 * configuration screen for the V2 API
	 */
	private function configurationScreen()
	{
		ob_start();

		// Load class
		require_once JPATH_ADMINISTRATOR.'/components/com_rsform/helpers/zohocrm/zohocrmapi.php';

		// Variables
		$zohocrm 		= new RSFPZohoCrm();
		$redirect_uri 	= $zohocrm->get_redirect_uri();
		$host 			= RSFormProHelper::getConfig('zohocrm.host');
		$user_email 	= RSFormProHelper::getConfig('zohocrm.user_email');
		$client_id 		= RSFormProHelper::getConfig('zohocrm.client_id');
		$client_secret 	= RSFormProHelper::getConfig('zohocrm.client_secret');
		$data_provided	= $host && $client_id && $client_secret && $user_email;

		// Create authorization URL if all data is supplied
		if ($data_provided)
		{
			$scopes = array(
				'ZohoCRM.users.ALL',
				'Aaaserver.profile.read',
				'ZohoCRM.settings.all',
				'ZohoCRM.modules.ALL'
			);

			$authorize_url = 'https://accounts.' . $host . '/oauth/v2/auth?scope=' . implode(',', $scopes) . '&client_id=' . $client_id . '
&response_type=code&access_type=offline&prompt=consent&redirect_uri=' . $redirect_uri;

			// Let's see if we already have an Access Token
			$access_token_stats = $zohocrm->get_current_access_token($user_email, $client_id);
		}

		Text::script('RSFP_ZOHOCRM_ARE_YOU_SURE_DEAUTH');

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

		$form = Form::getInstance( 'plg_system_rsfpzohocrm.configuration', 'configuration', array('control' => 'rsformConfig'), false, false );
		$form->bind($this->loadFormData());
		?>
		<div id="page-zohocrm" class="form-horizontal">
			<?php
			if (empty($access_token_stats))
			{
				foreach ($form->getFieldsets() as $fieldset)
				{
					if ($fields = $form->getFieldset($fieldset->name))
					{
						foreach ($fields as $field)
						{
							echo str_replace('"rsformConfig[zohocrm][', '"rsformConfig[zohocrm.', $form->renderField($field->fieldname));
						}
					}
				}
				?>
				<p><strong><?php echo Text::_('RSFP_ZOHOCRM_RETURN_URI'); ?></strong> <?php echo htmlspecialchars(urldecode($redirect_uri), ENT_COMPAT, 'utf-8'); ?></p>
				<div class="alert alert-info">
					<p><strong><?php echo Text::_('RSPF_ZOHOCRM_REMEMBER_TO_PRESS_SAVE'); ?></strong></p>
				</div>
				<?php
			}
			?>
			<?php
			if (!empty($access_token_stats))
			{
				?>
				<p><strong><?php echo Text::_('RSFP_ZOHOCRM_EVERYTHING_SEEMS_SETUP_CORRECTLY'); ?></strong></p>
				<p><a onclick="return confirm(Joomla.JText._('RSFP_ZOHOCRM_ARE_YOU_SURE_DEAUTH'));" href="<?php echo Route::_('index.php?option=com_rsform&task=plugin&plugin_task=zoho_deauth'); ?>" class="btn btn-danger"><?php echo Text::_( 'RSFP_ZOHOCRM_DEAUTHORIZE' ); ?></a></p>
			<?php
			}
			elseif ($data_provided)
			{
				?>
				<p><a href="<?php echo RSFormProHelper::htmlEscape($authorize_url); ?>" class="btn btn-primary"><?php echo Text::_( 'RSFP_ZOHOCRM_GENERATE_NEW_GRANT_TOKEN_BTN' ); ?></a></p>
				<?php
			}
			?>
		</div>
		<?php
		
		$contents = ob_get_contents();
		ob_end_clean();
		return $contents;
	}

	public function onRsformBackendSwitchTasks()
	{
		$app 		 = Factory::getApplication();
		$plugin_task = $app->input->getCmd('plugin_task','');

		switch ($plugin_task)
		{
			case 'zoho_deauth':
				$config = RSFormProConfig::getInstance();

				// Delete all tokens for this Client ID
				$db = Factory::getDbo();
				$query = $db->getQuery(true)
					->delete($db->qn('#__rsform_zohocrm_oauthtokens'))
					->where($db->qn('clientid') . ' = ' . $db->q($config->get('zohocrm.client_id')));
				$db->setQuery($query)->execute();

				// Reset Client ID, Secret and Token
				$config->set('zohocrm.client_id', '');
				$config->set('zohocrm.client_secret', '');
				$config->set('zohocrm.grant_token', '');

				$app->redirect('index.php?option=com_rsform&view=configuration');
				break;

			case 'zoho_auth':
				$code = $app->input->getString('code', '');

				if ($code)
				{
					$config = RSFormProConfig::getInstance();

					$config->set('zohocrm.grant_token', $code);

					$app->enqueueMessage(Text::_('RSFP_ZOHOCRM_STORED_GRANT_TOKEN_SUCCESSFULLY'), 'success');

					// Try to store the Access Token
					try
					{
						require_once JPATH_ADMINISTRATOR . '/components/com_rsform/helpers/zohocrm/zohocrmapi.php';

						$zohocrm = new RSFPZohoCrm(array(
							'grant_token' 		=> $config->get('zohocrm.grant_token'),
							'currentUserEmail' 	=> $config->get('zohocrm.user_email'),
							'client_id' 		=> $config->get('zohocrm.client_id'),
							'client_secret' 	=> $config->get('zohocrm.client_secret'),
							'apiBaseUrl' 		=> $config->get('zohocrm.host'),
						));
						if ($token = $zohocrm->get_and_store_access_token())
						{
							// No longer need the Grant Token
							$config->set('zohocrm.grant_token', '');

							// Set email based on token
							$config->set('zohocrm.user_email', $token->getUserEmailId());

							$app->enqueueMessage(Text::_('RSFP_ZOHOCRM_STORED_ACCESS_TOKEN_SUCCESSFULLY'), 'success');
						}
					}
					catch (Exception $e)
					{
						$message = $e->getMessage();

						// if the grant token has expired or is entered wrong the error is not that pretty
						if (strpos($message, '{"error":"invalid_code"}') !== false)
						{
							$message = Text::_('RSFP_ZOHOCRM_STORED_ACCESS_TOKEN_FAIL');
						}

						if (strpos($message, '{"error":"invalid_client_secret"}') !== false)
						{
							$message = Text::_('RSFP_ZOHOCRM_ERROR_INVALID_CLIENT_SECRET');
						}

						if (strpos($message, '{"error":"no_refresh_code_detected"}') !== false)
						{
							$message = Text::_('RSFP_ZOHOCRM_STORED_ACCESS_TOKEN_FAIL_NO_REFRESH_TOKEN_PROVIDED');
						}
						$app->enqueueMessage($message, 'error');
					}
				}

				$app->redirect('index.php?option=com_rsform&view=configuration');
				break;
		}
	}
	
	public function _getFields($formId, $type = 'all')
	{
		$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'));
		
		$query->where($db->qn('c.ComponentTypeId') . ' '.($type == 'files' ? '=' : '!=').' ' . $db->q(RSFORM_FIELD_FILEUPLOAD));

		$fields = $db->setQuery($query)->loadColumn();
		array_unshift($fields, '- IGNORE -');

		return $fields;
	}
	
	public function onRsformFormDelete($formId)
	{
		if ($row = $this->getTable())
		{
			$row->delete($formId);
		}
	}
	
	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('zohocrm');
				foreach ($data as $property => $value)
				{
					$xml->add($property, $value);
				}
				$xml->add('/zohocrm');
			}
		}
	}
	
	public function onRsformFormRestore($form, $xml, $fields)
	{
		if (isset($xml->zohocrm))
		{
			$data = array(
				'form_id' => $form->FormId
			);
			
			foreach ($xml->zohocrm->children() as $property => $value)
			{
				$data[$property] = (string) $value;
			}
			
			$row = $this->getTable();
			$row->save($data);
		}
	}
	
	public function onRsformBackendFormRestoreTruncate()
	{
		Factory::getDbo()->truncateTable('#__rsform_zohocrm');
	}
}