<?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('Restricted access');

if (!file_exists(JPATH_ADMINISTRATOR.'/components/com_rsform/helpers/Ctct/autoload.php')) {
	return;
}

require_once JPATH_ADMINISTRATOR.'/components/com_rsform/helpers/Ctct/autoload.php';
use Ctct\ConstantContact;
use Ctct\Components\Contacts\Contact;
use Ctct\Components\Contacts\ContactList;
use Ctct\Components\Contacts\EmailAddress;
use Ctct\Exceptions\CtctException;

class plgSystemRsfpconstantcontact extends JPlugin
{
	protected $autoloadLanguage = true;

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

	public function onRsformFormSave($form)
	{
		$data 			 = JFactory::getApplication()->input->get('ccontact', array(), 'array');
		$data['form_id'] = JFactory::getApplication()->input->getInt('formId',0);
		$row 			 = $this->getTable();
		
		if (!$row)
		{
			return false;
		}
		
		return $row->save($data);
	}
	
	public function onRsformBackendFormCopy($args)
	{
		$formId = $args['formId'];
		$newFormId = $args['newFormId'];

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

				$row->check();

				return $row->store();
			}
		}
	}
	
	public function onRsformBackendAfterShowFormEditTabs()
	{
		$formId = JFactory::getApplication()->input->getInt('formId',0);
		$row	= $this->getTable();
		$fields = array();
		
		if (!$row) {
			return;
		}
		
		$row->load($formId);
		$row->cc_merge_vars = @unserialize($row->cc_merge_vars);
		if ($row->cc_merge_vars === false) {
			$row->cc_merge_vars = array();
		}
		
		$cc_action = array(
			JHtml::_('select.option', 1, JText::_('RSFP_CC_ACTION_SUBSCRIBE')),
			JHtml::_('select.option', 0, JText::_('RSFP_CC_ACTION_UNSUBSCRIBE')),
			JHtml::_('select.option', 2, JText::_('RSFP_CC_LET_USER_DECIDE'))
		);
		
		$fields_array = $this->_getFields($formId);
		$fields[] = JHtml::_('select.option', '', JText::_('RSFP_CC_IGNORE'));
		foreach ($fields_array as $field) {
			$fields[] = JHtml::_('select.option', $field, $field);
		}
		
		$cc_email_type = array(
			JHtml::_('select.option', 'HTML', JText::_('RSFP_CC_HTML')),
			JHtml::_('select.option', 'Text', JText::_('RSFP_CC_TEXT')),
			JHtml::_('select.option', 'user', JText::_('RSFP_CC_LET_USER_DECIDE'))
		);
		
		$merge_vars = array(
			"email_address" 			=> JText::_('RSFP_CC_EMAIL_ADDRESS'),
			"first_name" 				=> JText::_('RSFP_CC_FIRSTNAME'),
			"last_name" 				=> JText::_('RSFP_CC_LASTNAME'),
			"middle_name" 				=> JText::_('RSFP_CC_MIDDLENAME'),
			"home_phone" 				=> JText::_('RSFP_CC_HOMEPHONE'),
			"company_name" 				=> JText::_('RSFP_CC_COMPANYNAME'),
			"job_title" 				=> JText::_('RSFP_CC_JOBTITLE'),
			"work_phone" 				=> JText::_('RSFP_CC_WORKPHONE'),
			"note_note" 				=> JText::_('RSFP_CC_NOTES'),
			"address_address_type"		=> JText::_('RSFP_CC_ADDR_TYPE'),
			"address_line1" 			=> JText::_('RSFP_CC_ADDR1'),
			"address_line2" 			=> JText::_('RSFP_CC_ADDR2'),
			"address_line3" 			=> JText::_('RSFP_CC_ADDR3'),
			"address_city" 				=> JText::_('RSFP_CC_CITY'), 
			"address_state_code" 		=> JText::_('RSFP_CC_STATECODE'),
			"address_state" 			=> JText::_('RSFP_CC_STATENAME'),
			"address_country_code" 		=> JText::_('RSFP_CC_COUNTRYCODE'), 
			"address_postal_code" 		=> JText::_('RSFP_CC_POSTALCODE'),
			"address_sub_postal_code" 	=> JText::_('RSFP_CC_SUBPOSTALCODE'),
			"CustomField1" 				=> JText::_('RSFP_CC_CF1'),
			"CustomField2" 				=> JText::_('RSFP_CC_CF2'),
			"CustomField3" 				=> JText::_('RSFP_CC_CF3'),
			"CustomField4" 				=> JText::_('RSFP_CC_CF4'),
			"CustomField5" 				=> JText::_('RSFP_CC_CF5'),
			"CustomField6" 				=> JText::_('RSFP_CC_CF6'),
			"CustomField7" 				=> JText::_('RSFP_CC_CF7'),
			"CustomField8" 				=> JText::_('RSFP_CC_CF8'),
			"CustomField9" 				=> JText::_('RSFP_CC_CF9'),
			"CustomField10" 			=> JText::_('RSFP_CC_CF10'),
			"CustomField11" 			=> JText::_('RSFP_CC_CF11'),
			"CustomField12" 			=> JText::_('RSFP_CC_CF12'),
			"CustomField13" 			=> JText::_('RSFP_CC_CF13'),
			"CustomField14" 			=> JText::_('RSFP_CC_CF14'),
			"CustomField15" 			=> JText::_('RSFP_CC_CF15')
		);
		
		// Enable integration
		$lists['cc_published'] = RSFormProHelper::renderHTML('select.booleanlist','ccontact[cc_published]', '', $row->cc_published);
		
		// Action
		$lists['cc_action'] = JHtml::_('select.genericlist', $cc_action, 'ccontact[cc_action]', 'onchange="ccChangeAction(this.value);"', 'value', 'text', $row->cc_action);
		
		// Action field
		$lists['cc_action_field'] = JHtml::_('select.genericlist', $fields, 'ccontact[cc_action_field]', $row->cc_action != 2 ? 'disabled="disabled"' : '', 'value', 'text', $row->cc_action_field);
		
		// Delete
		$lists['cc_delete_member'] = RSFormProHelper::renderHTML('select.booleanlist','ccontact[cc_delete_member]','',$row->cc_delete_member);
		
		// Lists
		$lists['cc_list_id'] = JHtml::_('select.genericlist', $this->getLists(), 'ccontact[cc_list_id]', 'onchange="ccShowVars(this.value)"', 'value', 'text', $row->cc_list_id);
		
		// Update existing contact
		$lists['cc_update'] = RSFormProHelper::renderHTML('select.booleanlist','ccontact[cc_update]','',$row->cc_update);
		
		// Fields
		$lists['cc_fields'] = array();
		if (is_array($merge_vars)) {
			foreach ($merge_vars as $merge_var => $title) {
				$lists['cc_fields'][$merge_var] = JHtml::_('select.genericlist', $fields, 'ccontact[cc_merge_vars]['.$merge_var.']', null, 'value', 'text', isset($row->cc_merge_vars[$merge_var]) ? $row->cc_merge_vars[$merge_var] : null);
			}
		}

		JFactory::getDocument()->addScriptDeclaration("
function ccShowVars(val) {
	document.getElementById('merge_vars_cc').style.display = val === '0' ? 'none' : '';
}

function ccChangeAction(value) {
	document.getElementById('ccontactcc_action_field').disabled = value !== '2';
}

window.addEventListener('DOMContentLoaded', function() {
	ccShowVars(document.getElementById('ccontactcc_list_id').value);
});");
		?>
		<div id="constantcontactdiv">
			<h3 class="rsfp-legend"><?php echo JText::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_NAME'); ?></h3>
			<div class="alert alert-info"><?php echo JText::_('RSFP_CONSTANTCONTACT_DESC'); ?></div>
			<table class="table table-bordered">
				<tr>
					<td><?php echo JText::_('RSFP_CC_USE_INTEGRATION'); ?></td>
					<td><?php echo $lists['cc_published']; ?></td>
				</tr>
				<tr>
					<td>
						<span class="hasTip" title="<?php echo JText::_('RSFP_CC_ACTION_DESC'); ?>"><?php echo JText::_('RSFP_CC_ACTION'); ?></span>
					</td>
					<td><?php echo $lists['cc_action']; ?> <?php echo $lists['cc_action_field']; ?>
					<p><?php echo JText::_('RSFP_CC_ACTION_WARNING'); ?></p></td>
				</tr>
				<tr>
					<td><?php echo JText::_('RSFP_CC_LIST_ID'); ?></td>
					<td><?php echo $lists['cc_list_id']; ?></td>
				</tr>
				<tr>
					<td><?php echo JText::_('RSFP_CC_UPDATE_CONTACT'); ?></td>
					<td><?php echo $lists['cc_update']; ?></td>
				</tr>
			</table>

			<h3 class="rsfp-legend"><?php echo JText::_('RSFP_CC_UNSUBSCRIBE_OPTIONS'); ?></h3>
			<table class="table table-bordered">
				<tr>
					<td>
						<span class="hasTip" title="<?php echo JText::_('RSFP_CC_DELETE_MEMBER_DESC'); ?>"><?php echo JText::_('RSFP_CC_DELETE_MEMBER'); ?></span>
					</td>
					<td><?php echo $lists['cc_delete_member']; ?></td>
				</tr>
			</table>

			<div id="merge_vars_cc">
				<h3 class="rsfp-legend"><?php echo JText::_('RSFP_CC_MERGE_VARS'); ?></h3>
				<p><?php echo JText::_('RSFP_CC_MERGE_VARS_DESC'); ?></p>
				<table class="table table-bordered">
					<tbody>
					<?php if (is_array($merge_vars)) { ?>
						<?php foreach ($merge_vars as $merge_var => $title) { ?>
							<tr>
								<td><?php echo $title; ?></td>
								<td><?php echo $lists['cc_fields'][$merge_var]; ?></td>
							</tr>
						<?php } ?>
					<?php } ?>
					</tbody>
				</table>
			</div>
		</div>
		<?php
	}
	
	protected function getLists() {
		$api 	= RSFormProHelper::getConfig('cc.api');
		$token 	= RSFormProHelper::getConfig('cc.token');
		$lists	= array(JHtml::_('select.option', '0', JText::_('RSFP_PLEASE_SELECT_LIST')));
		$cc		= new ConstantContact($api);
		
		if ($api && $token)
		{
			try {
				if ($cclists = $cc->getLists($token)) {
					foreach ($cclists as $cclist) {
						$lists[] = JHtml::_('select.option', $cclist->id, $cclist->name);
					}
				}
			} catch (Exception $e) {
				foreach ($e->getErrors() as $error) {
					JFactory::getApplication()->enqueueMessage('ConstantContact: '.$error['error_message'], 'warning');
				}
			}
		}
		
		return $lists;
	}
	
	public function onRsformBackendAfterShowFormEditTabsTab()
	{
		echo '<li><a href="javascript: void(0);" id="constantcontact"><span class="rsficon rsficon-envelope"></span><span class="inner-text">'.JText::_('RSFP_CONSTANTCONTACT_INTEGRATION').'</span></a></li>';
	}
	
	public function onRsformFrontendAfterFormProcess($args)
	{
		$formId	= (int) $args['formId'];
		$row	= $this->getTable();

		if ($row && $row->load($formId))
		{
			if (!$row->cc_published || !$row->cc_list_id)
			{
				return;
			}
			
			$row->cc_merge_vars = @unserialize($row->cc_merge_vars);
			if ($row->cc_merge_vars === false) {
				$row->cc_merge_vars = array();
			}
			
			if (!isset($row->cc_merge_vars['email_address'])) {
				return;
			}
			
			$form	= JFactory::getApplication()->input->get('form', array(), 'array');
			$email	= isset($form[$row->cc_merge_vars['email_address']]) ? $form[$row->cc_merge_vars['email_address']] : null;
			
			if (!$email) {
				return;
			}
			
			$subscribe = true;
			if ($row->cc_action == 1) {
				$subscribe = true;
			} elseif ($row->cc_action == 0) {
				$subscribe = false;
			} elseif ($row->cc_action == 2 && isset($form[$row->cc_action_field])) {
				$subscribe = null;
				if (is_array($form[$row->cc_action_field])) {
					foreach ($form[$row->cc_action_field] as $i => $value) {
						$value = strtolower(trim($value));
						if ($value == 'subscribe') {
							$subscribe = true;
							break;
						} elseif ($value == 'unsubscribe') {
							$subscribe = false;
							break;
						}
					}
				} else {
					$form[$row->cc_action_field] = strtolower(trim($form[$row->cc_action_field]));
					if ($form[$row->cc_action_field] == 'subscribe') {
						$subscribe = true;
					} elseif ($form[$row->cc_action_field] == 'unsubscribe') {
						$subscribe = false;
					} else {
						$subscribe = null;
					}
				}
			}
			
			$merge_vars = array();
			$merge_vars['addresses'][] = array();
			$merge_vars['notes'][] = array();
			
			foreach ($row->cc_merge_vars as $tag => $field) {
				if (empty($tag)) continue;
				if ($tag == 'email_address') continue;
				
				if (!isset($form[$field]))
					$form[$field] = '';
				
				if (is_array($form[$field]))
				{
					array_walk($form[$field], array($this, '_escapeCommas'));
					$form[$field] = implode(',', $form[$field]);
				}
				
				if (strncmp($tag, 'CustomField', strlen('CustomField')) === 0) {
					$merge_vars['custom_fields'][] = array('name' => $tag, 'value' => $form[$field]);
				} elseif (strncmp($tag, 'note', strlen('note')) === 0) {
					if (!empty($form[$field])) {
						$merge_vars['notes'][0][str_replace('note_','',$tag)] = $form[$field];
					}
				} elseif (strncmp($tag, 'address_', strlen('address_')) === 0) {
					$merge_vars['addresses'][0][substr($tag, strlen('address_'))] = $form[$field];
				} else {
					$merge_vars[$tag] = $form[$field];
				}
			}
			
			if (empty($merge_vars['notes'][0])) {
				unset($merge_vars['notes']);
			}
			
			$address_type = &$merge_vars['addresses'][0]['address_type'];
			
			if (empty($address_type) || !in_array($address_type, array('PERSONAL', 'BUSINESS'))) {
				$address_type = 'PERSONAL';
			}
			
			$api 	= RSFormProHelper::getConfig('cc.api');
			$token 	= RSFormProHelper::getConfig('cc.token');
			$cc		= new ConstantContact($api);
			
			if (!$api || !$token)
			{
				return;
			}
			
			if ($subscribe) {
				try {
					$response = $cc->getContactByEmail($token, $email);
					
					// Add contact
					if (empty($response->results)) {
						$contact = Contact::create($merge_vars);
						$contact->addEmail($email);
						$contact->addList($row->cc_list_id);
						
						$cc->addContact($token, $contact, true);
					} else {
						// Update contact
						if ($row->cc_update) {
							$contact = $response->results[0];
							$contact->addList($row->cc_list_id);
							
							if (!empty($merge_vars)) {
								foreach ($merge_vars as $var => $value) {
									$contact->$var = $value;
								}
							}
							
							$cc->updateContact($token, $contact, true);
						} else {
							JFactory::getApplication()->enqueueMessage(JText::sprintf('RSFP_CC_EMAIL_COULD_NOT_UPDATE', $email), 'warning');
						}
					}
				} catch (Exception $e) {
					foreach ($e->getErrors() as $error) {
						JFactory::getApplication()->enqueueMessage('ConstantContact: '.$error['error_message'], 'warning');
					}
				}
			} elseif ($subscribe === false) {
				try {
					$response	= $cc->getContactByEmail($token, $email);
					$contactID	= !empty($response->results) && isset($response->results[0]) ? $response->results[0]->id : null;

					if ($contactID) {
						if ($row->cc_delete_member) {
							$cc->deleteContactFromList($token, $contactID, $row->cc_list_id);
						} else {
							$cc->deleteContact($token, $contactID);
						}
					} else {
						JFactory::getApplication()->enqueueMessage(JText::sprintf('RSFP_CC_EMAIL_DOES_NOT_EXIST', $email), 'warning');
					}
				} catch (Exception $e) {
					foreach ($e->getErrors() as $error) {
						JFactory::getApplication()->enqueueMessage('ConstantContact: '.$error['error_message'], 'warning');
					}
				}
			}
		}
	}
	
	public function onRsformBackendAfterShowConfigurationTabs($tabs)
	{
		$tabs->addTitle(JText::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_NAME'), 'form-constantcontact');
		$tabs->addContent($this->configurationScreen());
	}
	
	protected function configurationScreen()
	{
		ob_start();

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

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

		?>
		<div id="page-constantcontact" class="form-horizontal">
			<p><?php echo JText::_('RSFP_CC_API_KEY_REQUEST'); ?></p>
			<?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 	= JFactory::getDbo();

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

		return $data;
	}
	
	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('constantcontact');
				foreach ($data as $property => $value)
				{
					$xml->add($property, $value);
				}
				$xml->add('/constantcontact');
			}
		}
	}
	
	public function onRsformFormRestore($form, $xml, $fields)
	{
		if (isset($xml->constantcontact))
		{
			$data = array(
				'form_id' => $form->FormId
			);
			
			foreach ($xml->constantcontact->children() as $property => $value)
			{
				$data[$property] = (string) $value;
			}
			
			$row = $this->getTable();
			$row->save($data);
		}
	}
	
	public function onRsformBackendFormRestoreTruncate() {
		JFactory::getDbo()->truncateTable('#__rsform_constantcontact');
	}
	
	protected function _getFields($formId)
	{
		$db    = JFactory::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();
	}
	
	protected function _escapeCommas(&$item) {
		$item = str_replace(',', '\,', $item);
	}
}