<?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;

require_once JPATH_ADMINISTRATOR.'/components/com_rsform/helpers/Ctct/v2/Ctct/autoload.php';
require_once dirname(__FILE__).DIRECTORY_SEPARATOR.'ccinterface.php';

use Ctct\ConstantContact;
use Ctct\Components\Contacts\Contact;
use Ctct\Components\Contacts\ContactList;
use Ctct\Components\Contacts\EmailAddress;
use Ctct\Exceptions\CtctException;
use Joomla\CMS\Language\Text;

class RSFormProConstantContactV2 implements RSFormProConstantContactInterface
{
    protected $cc;
    protected $token = '';
    protected $merge_vars = [];

    public function __construct(string $api = '', string $secret = '')
    {
        $this->cc =  new ConstantContact($api);
    }

    public function setMergeFields()
    {
        $this->merge_vars = [
            "email_address" 			=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_EMAIL_ADDRESS'),
            "first_name" 				=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_FIRSTNAME'),
            "middle_name" 				=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_MIDDLENAME'),
            "last_name" 				=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_LASTNAME'),
            "job_title" 				=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_JOBTITLE'),
            "company_name" 				=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_COMPANYNAME'),
            "home_phone" 				=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_HOMEPHONE'),
            "work_phone" 				=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_WORKPHONE'), 
            "note_note" 				=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_NOTES'),
            "address_address_type"		=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_ADDR_TYPE'),
            "address_line1" 			=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_ADDR1'),
            "address_line2" 			=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_ADDR2'),
            "address_line3" 			=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_ADDR3'),
            "address_city" 				=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_CITY'), 
            "address_state_code" 		=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_STATECODE'),
            "address_state" 			=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_STATENAME'),
            "address_country_code" 		=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_COUNTRYCODE'), 
            "address_postal_code" 		=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_POSTALCODE'),
            "address_sub_postal_code" 	=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_SUBPOSTALCODE'),
            "CustomField1" 				=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_CF1'),
            "CustomField2" 				=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_CF2'),
            "CustomField3" 				=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_CF3'),
            "CustomField4" 				=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_CF4'),
            "CustomField5" 				=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_CF5'),
            "CustomField6" 				=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_CF6'),
            "CustomField7" 				=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_CF7'),
            "CustomField8" 				=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_CF8'),
            "CustomField9" 				=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_CF9'),
            "CustomField10" 			=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_CF10'),
            "CustomField11" 			=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_CF11'),
            "CustomField12" 			=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_CF12'),
            "CustomField13" 			=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_CF13'),
            "CustomField14" 			=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_CF14'),
            "CustomField15" 			=> Text::_('PLG_SYSTEM_RSFPCONSTANTCONTACT_CF15')
        ];
    }

    public function setAccessToken(string $token = '')
    {
        $this->token = $token; 
    }

    public function getMergeFields()
    {
        return $this->merge_vars;
    }

    public function getLists()
    {
        try 
        {
            return $this->cc->getLists($this->token);
        } 
        catch (Exception $e) 
        {
            $messages = [];
            foreach ($e->getErrors() as $error)
            {
                $messages[] = $error['error_message'];
            }

            $messages = implode('<br/>', $messages);

            throw new Exception($messages);
        }
    }

    public function getContactByEmail(string $email)
    {
        static $response;

        if (is_null($response))
        {
            try 
            {
                $response = $this->cc->getContactByEmail($this->token, $email);
            }
            catch (Exception $e) 
            {
                $messages = [];
                foreach ($e->getErrors() as $error)
                {
                    $messages[] = $error['error_message'];
                }
    
                $messages = implode('<br/>', $messages);
    
                throw new Exception($messages);
            }
        }

        return $response;
    }

    public function addContact(string $email, string $list_id, array $vars = [])
    {
        try 
        {
            $contact = Contact::create($vars);
            $contact->addEmail($email);
            $contact->addList($list_id);

            $this->cc->addContact($this->token, $contact, true);
        }
        catch (Exception $e) 
        {
            $messages = [];
            foreach ($e->getErrors() as $error)
            {
                $messages[] = $error['error_message'];
            }

            $messages = implode('<br/>', $messages);

            throw new Exception($messages);
        }
    }

    public function updateContact(string $email, string $list_id, array $vars = [])
    {
        try 
        {
            // get the contact
            $response = $this->getContactByEmail($email);

            // get the actual object
            $contact = $response->results[0];

            // add the list id
            $contact->addList($list_id);

            if (!empty($vars))
            {
                foreach ($vars as $var => $value)
                {
                    $contact->$var = $value;
                }
            }

            $this->cc->updateContact($this->token, $contact, true);
        }
        catch (Exception $e) 
        {
            $messages = [];
            foreach ($e->getErrors() as $error)
            {
                $messages[] = $error['error_message'];
            }

            $messages = implode('<br/>', $messages);

            throw new Exception($messages);
        }
    }

    public function deleteContact(string $email, bool $delete_memeber = false, string $list_id = '')
    {
        try
        {
            // get the contact
            $response = $this->getContactByEmail($email);
            $contactID	= !empty($response->results) && isset($response->results[0]) ? $response->results[0]->id : null;

            // throw the error that the contact for this email does not exist 
            if (!$contactID)
            {
                throw new \Exception(Text::sprintf('PLG_SYSTEM_RSFPCONSTANTCONTACT_EMAIL_DOES_NOT_EXIST', $email));
            }

            if ($delete_memeber) 
            {
                $this->cc->deleteContactFromList($this->token, $contactID, $list_id);
            }
            else
            {
                $this->cc->deleteContact($this->token, $contactID);
            }
        }
        catch (Exception $e) 
        {
            $normal_message = $e->getMessage();

            $messages = [];
            if (strlen($normal_message))
            {
                $messages[] = $normal_message;
            }

            // add the rest
            foreach ($e->getErrors() as $error)
            {
                $messages[] = $error['error_message'];
            }

            $messages = implode('<br/>', $messages);

            throw new Exception($messages);
        }
    }
}