<?php

class Am_Newsletter_Plugin_Mailerlite extends Am_Newsletter_Plugin
{

    const
        ENDPOINT = 'https://api.mailerlite.com/api/v2';

    function _initSetupForm(\Am_Form_Setup $form)
    {
        $form->addSecretText('api_key', array('class' => 'am-el-wide'))
            ->setLabel(___("MailerLite API key\n"
                    . "API key can be obtained from Integrations page when you are logged into MailerLite application"));
        $form->addAdvCheckbox('debug')
            ->setLabel("Debug logging\nRecord debug information in the log");
    }

    function isConfigured()
    {
        return $this->getConfig('api_key');
    }

    public
        function changeSubscription(\User $user, array $addLists, array $deleteLists)
    {
        foreach ($addLists as $list)
        {
            $this->getApi()->post(sprintf('groups/%s/subscribers', $list), $this->getUserInfoArray($user));
        }

        foreach ($deleteLists as $list)
        {
            $this->getApi()->delete(sprintf('groups/%s/subscribers/%s', $list, $user->email));
        }
        return true;
    }
    
    function changeEmail(User $user, $oldEmail, $newEmail)
    {
        $lists = $this->getDi()->newsletterUserSubscriptionTable->getSubscribedIds($user->pk());
        $campaigns = array();
        foreach($lists as $v){
            $list = $this->getDi()->newsletterListTable->load($v);
            $campaigns[] = $list->plugin_list_id;
        }

        $user->email = $oldEmail;
        try{
            $this->changeSubscription($user, array(), $campaigns);
        }
        catch(Am_Exception_InternalError $e)
        {
            $this->getDi()->logger->error($e->getMessage());
        }
        $user->email = $newEmail;
        try{
            $this->changeSubscription($user, $campaigns, array());
        }
        catch(Am_Exception_InternalError $e)
        {
            $this->getDi()->logger->error($e->getMessage());
        }        
    }
    
    function getUserInfoArray(User $user)
    {
        return array(
            'email' => $user->getEmail(),
            'fields' => array(
                'name' => $user->name_f,
                'last_name' => $user->name_l,
                'country' => $user->country,
                'city' => $user->city,
                'state' => $user->state,
                'zip' => $user->zip,
                'phone' => $user->phone
            ),
            'resubscribe' => true,
            'autoresponders' => true,
        );
    }

    function getLists()
    {
        $ret = array();
        foreach ($this->getApi()->get('groups') as $gr)
        {
            $ret[$gr['id']] = array('title' => $gr['name']);
        }
        return $ret;
    }

    function getApi()
    {
        $api = new Am_Mailerlite_Request(self::ENDPOINT, $this->getConfig('api_key'), $this);
        return $api;
    }
    
    public function onGetFlexibleActions(Am_Event $event)
    {
        try
        {
            $lists = $this->getDi()->cacheFunction->call([$this, 'getLists'], [], [], 60);
        } catch (Am_Exception $e) {
            return;
        }
        foreach($lists as $list_id=>$list)
        {
            $event->addReturn(new Am_FlexibleAction_MailerliteListAdd($list_id, $list['title'], $this));
            $event->addReturn(new Am_FlexibleAction_MailerliteListDelete($list_id, $list['title'], $this));
        }
    }
    

}

class Am_Mailerlite_Request extends Am_HttpRequest
{

    protected
        $api_key, $endpoint, $plugin;

    function __construct($endpoint, $key, Am_Newsletter_Plugin $plugin)
    {
        $this->api_key = $key;
        $this->endpoint = $endpoint;
        $this->plugin = $plugin;
        parent::__construct();
    }

    function send()
    {
        $this->setHeader("X-MailerLite-ApiKey", $this->api_key);
        $ret = parent::send();
        $this->plugin->debug($this, $ret);
        return $ret;
    }

    function getEndpoint($method, $params = array())
    {

        return $this->endpoint . '/' . $method . (!empty($params) ? '?' . http_build_query($params) : '');
    }

    function __call($name, $arguments)
    {
        if (!in_array($name, array('post', 'put', 'get', 'delete')))
            throw new Am_Exception_InternalError('MailerLite Request: unknown method ' . $name);

        $this->setUrl($this->getEndpoint($arguments[0]));

        $this->setMethod(strtoupper($name));
        if (!empty($arguments[1]))
        {
            $this->setHeader('Content-Type', 'application/json');
            $this->setBody(json_encode($arguments[1]));
        }

        return $this->prepareResponse($this->send());
    }

    function prepareResponse(HTTP_Request2_Response $resp)
    {
        if (!in_array($resp->getStatus(), array(200, 201, 204)))
            throw new Am_Exception_InternalError(sprintf("MailerLite Response Status: %s. Response Body: %s", $resp->getStatus(), $resp->getBody()));

        $ret = json_decode($resp->getBody(), true);
        if (@$ret['error'])
            throw new Am_Exception_InternalError(sprintf("MailerLite Error: %s - %s", $ret['error']['code'], $ret['error']['message']));
        return $ret;
    }

}

if (interface_exists('Am_FlexibleAction_Interface', true)):
    abstract class Am_FlexibleAction_Mailerlite implements Am_FlexibleAction_Interface
    {
        /**
         * @var Am_Newsletter_Plugin_Mailerlite $plugin
         */
        protected $plugin;
        protected $list_id , $title;
        
        
        function __construct($list_id, $title, Am_Newsletter_Plugin_Mailerlite $plugin)
        {
            $this->plugin = $plugin;
        }
        
        function commit()
        {
            // TODO: Implement commit() method.
        }
    }

    class Am_FlexibleAction_MailerliteListAdd extends Am_FlexibleAction_Mailerlite
    {
    
        function run(User $user)
        {
            $this->plugin->getApi()->post(sprintf('groups/%s/subscribers', $this->list_id), $this->plugin->getUserInfoArray($user));
        }
        function getTitle()
        {
            return "MailerLite: Add to List: " . Am_Html::escape($this->title);
        }
        function getId() {
            return 'mailerlite-list-add-' . $this->list_id;
        }
    }
    class Am_FlexibleAction_MailerliteListDelete extends Am_FlexibleAction_Mailerlite
    {
        
        function run(User $user)
        {
            $this->plugin->getApi()->delete(sprintf('groups/%s/subscribers/%s', $this->list_id, $user->email));
            
        }
        function getTitle()
        {
            return "MailerLite: Delete from List: " . Am_Html::escape($this->title);
        }
        function getId() {
            return 'mailerlite-list-delete-' . $this->list_id;
        }
    }

endif;

