<?php namespace Newsletter\Model;

use Intellex\MailChimp\Client;
use Intellex\MailChimp\Resource\ResourceCampaign;

class CampaignModel {

	/** @var array The data for this model. */
	public $data;

	/** @var string[] The list of errors for each field. */
	public $errors = [];

	/** @var string[] The list of all fields. */
	private $fields = [
		'id',
		'title',
		'subject',
		'from_name',
		'from_email',
		'list_id',
		'send_time',
		'status',
		'archive_url',
		'template'
	];

	/**
	 * CampaignModel constructor.
	 *
	 * @param array $data The data for the model.
	 */
	public function __construct($data = []) {

		// Set default values
		foreach ($this->fields as $field) {
			if (!key_exists($field, $data)) {
				$data[$field] = null;
			}
		}

		$this->data = $data;
		$this->validate();
	}

	/**
	 * Create the model from the resource.
	 *
	 * @param ResourceCampaign $campaign The campaign to build from.
	 *
	 * @return CampaignModel The initialize model.
	 */
	public static function build(ResourceCampaign $campaign) {
		return new CampaignModel([
			'id'          => $campaign->id,
			'title'       => preg_replace('~^(.+)? \(([\.a-zA-Z0-9_-]*+)\)$~', '$1', $campaign->title),
			'subject'     => $campaign->subject,
			'from_name'   => $campaign->fromName,
			'status'      => $campaign->status,
			'from_email'  => $campaign->reply_to,
			'list_id'     => $campaign->listId,
			'send_time'   => $campaign->sendTime,
			'archive_url' => $campaign->archiveUrl,
			'template'    => preg_replace('~^(.+)? \(([\.a-zA-Z0-9_-]*+)\)$~', '$2', $campaign->title),
		]);
	}

	/**
	 * Validate the current state.
	 *
	 * @return bool True if there are no errors, false otherwise.
	 */
	private function validate() {
		$this->errors = [];

		return empty($this->errors);
	}

	/**
 	 * Save the current model.
	 *
	 * @param $mailChimpClient mailchimp client.
	 *
	 * @return CampaignModel The updated campaign.
	 * @throws \Exception
	 */
	public function save($mailChimpClient) {
		/** @var ResourceCampaign $response */

		// Initial validation
		$this->validate();
		if ($this->errors) {
			throw new \Exception($this->errors);
		}

		// Generate title
		$title = $this->data['title'] . ' (' . $this->data['template'] . ')';

		// Update
		$response =  $mailChimpClient->campaign()->create(
			$this->data['id'],
			$this->data['list_id'],
			$title,
			$this->data['subject'],
			$this->data['from_name'],
			$this->data['from_email']
		);

		// Set the id
		$this->data['id'] = $response->getId();
		return $this;
	}

	/**
	 * Parse the received errors.
	 *
	 * @param array $errors The list of errors, as received from the API.
	 *
	 * @return string[] The list of errors for each field.
	 */
	public function parseErrors($errors) {

		// Map the API fields
		$map = [
			'title'                 => 'title',
			'settings.reply_to'     => 'from_email',
			'settings.from_name'    => 'from_name',
			'settings.subject_line' => 'subject'
		];

		// Iterate over errors
		foreach ($errors as $error) {
			foreach ($map as $name => $field) {
				if ($name == $error['field']) {
					$this->errors[$field] = $error['message'];
					break;
				}
			}

			// If reached no fields have been recognized
			$this->errors['global'] = $error['message'];
		}

		return $this->errors;
	}

}