<?php

namespace Mtc\Plugins\NewsletterSignup\Classes;

use DrewM\MailChimp\MailChimp as DrewMailChimp;

/**
 * Class MailChimp
 * Newsletter sign-up driver to MailChimp system
 *
 * @package Mtc\Plugins\NewsletterSignup\Classes
 * @author Ajith Wijekseara <ajith.wijesekara@mtcmedia.co.uk>
 */
class MailChimp implements SignUpInterface
{
    /**
     * @var DrewMailChimp $api the api handler
     */
    private $api;

    /**
     * MailChimp constructor.
     * Initializes the connection with MailChimp API
     *
     * @param DrewMailChimp $api
     */
    public function __construct(DrewMailChimp $api)
    {
        $this->api = $api;
    }

    /**
     * Action sign-up of a newsletter on site using CM
     *
     * @param string $email email address to sign up
     * $param array $additional_params any additional params passed to interface
     * @return bool
     */
    public function signUp($email, $additional_params = [])
    {
        if (is_null($this->api)) {
            return false;
        }

        $params = [
            'email_address' => $email,
            'status' => 'subscribed',
            'merge_fields' => [
                'FNAME' => $additional_params['first_name'] ?? '',
                'LNAME' => $additional_params['last_name'] ?? '',
            ],
        ];

        $list_id = $this->getDefaultListId();

        // Email address not found
        if (! $this->checkIfExists($email)) {
            $this->api->post('lists/'.$list_id.'/members', $params);

            return true;
        }

        return false;
    }

    /**
     * Unsubscribes email address from first list.
     *
     * @param string $email Email address to be unsubscribed
     * @return bool
     */
    public function unsubscribe($email)
    {
        if (is_null($this->api)) {
            return false;
        }

        $list_id = $this->getDefaultListId();
        $email = md5(strtolower($email));
        $params = [
            'status' => 'unsubscribed',
        ];

        $user = $this->api->patch('lists/'.$list_id.'/members/'.$email, $params);

        if (isset($user['status'])) {
            return $user['status'] === 'unsubscribed';
        } else {
            return false;
        }
    }

    /**
     * Check if user already exists in MC database
     * Used to ensure user isn't subscribed multiple times
     *
     * @param $email
     * @return bool
     */
    public function checkIfExists($email)
    {
        if (is_null($this->api)) {
            return false;
        }

        $list_id = $this->getDefaultListId();

        return $this->getSubscriptionStatus($list_id, $email) == 'subscribed';
    }

    /**
     * Returns email address subscription status in Mailchimp
     *
     * @param string $list_id
     * @param string $email
     * @return mixed
     */
    public function getSubscriptionStatus($list_id, $email)
    {
        if (is_null($this->api)) {
            return false;
        }

        return $this->api->get('lists/'.$list_id.'/members/'.md5(strtolower($email)))['status'];
    }

    /**
     * Gets the default list ID, making sure it exists in the account.
     *
     * @return string The ID of the default list
     */
    private function getDefaultListId()
    {
        $lists = $this->api->get('lists');
        if (
            ! is_null(NEWSLETTER_MAILCHIMP_LIST_ID)
            && ! empty(NEWSLETTER_MAILCHIMP_LIST_ID)
            && in_array(NEWSLETTER_MAILCHIMP_LIST_ID, array_column($lists['lists'], 'id'))
        ) {
            return NEWSLETTER_MAILCHIMP_LIST_ID;
        } else {
            return count($lists['lists']) > 0 ? $lists['lists'][0]['id'] : '';
        }
    }
}
