<?php

namespace App\ClientCollection\Corporate;

/**
 * The class analyzes the corporate details regarding collection email.
 * Correctly treats clients with profiles associated or with default profiles but it also considers
 * loading the details from corporation directly or, when empty, from collection profile setup.
 * @author Gabriel
 */
class EmailData
{

	/**
	 * Stores the corporate id.
	 * @var int
	 */
	private $idCorporate;

	/**
	 * Collected problems with the current email.
	 * @var \App\MessagesCollector
	 */
	private $messages;

	/**
	 * Email data details - cached.
	 * @var array
	 */
	private $emailData;

	public function __construct(int $idCorporate)
	{
		$this->idCorporate = $idCorporate;
	}

	/**
	 * Returns the corporate id.
	 * @return int
	 */
	public function getIdCorporate() :int
	{
		return $this->idCorporate;
	}

	/**
	 * Fills in an array of details needed for the email sending.
	 * @throws \Exception
	 * @return array
	 */
	public function getData() : array
	{

		// return from cache
		if ($this->emailData) {
			return $this->emailData;
		}

		// init messages (even if there are no messages collected)
		$this->messages = new \App\MessagesCollector();

		$return = [];

		$corporateCollectionProfileEnt = \Entity\CorporateCollection::select($this->idCorporate);

		$corporateEnt = \Entity\Corporate::select($this->idCorporate);

		///////////////////////////////////////////////////////////////////////////////////////////
		// FIRST FILLS IN THE DETAILS FROM CORPORATION COLLECTION /////////////////////////////////
		///////////////////////////////////////////////////////////////////////////////////////////
		if ($corporateCollectionProfileEnt->recordExists()) {

			// adds TO (auto) addresses
			switch ($corporateCollectionProfileEnt->toAuto) {
				// no "auto" - forces empty array
				case 'none':
					$return['toAuto'] = [];
				break;
				// loads corporate
				case 'corporateEmail':
					if ($corporateEnt->email) {
						$return['toAuto'] = [ $corporateEnt->email ];
					} else {
						$return['toAuto'] = [];
					}
				break;
				case 'corporateMainOfficeEmail':
					if ($corporateEnt->mainOffice->email) {
						$return['toAuto'] = [ $corporateEnt->mainOffice->email ];
					} else {
						$return['toAuto'] = [];
					}
				break;
				case '':
					$return['toAuto'] = null;
				break;
				default:
					throw new \Exception('Invalid toAuto (1) - '.$corporateCollectionProfileEnt->toAuto);
			}

			// adds TO (manual) addresses
			if ($corporateCollectionProfileEnt->toList) {
				$return['toManual'] = $corporateCollectionProfileEnt->toList;
			} else {
				$return['toManual'] = null;
			}

			// adds BCC addresses
			if ($corporateCollectionProfileEnt->bccList) {
				$return['bccManual'] = $corporateCollectionProfileEnt->bccList;
			} else {
				$return['bccManual'] = null;
			}

			// adds dueInDaysPeriod field (can be null)
			$return['dueInDaysPeriod'] = $corporateCollectionProfileEnt->dueInDaysPeriod;

		}

		// determine the profile code - it's either the one from the corporate details or the default one (if set)
		if ($corporateCollectionProfileEnt->profileCode) {
			$profileCode = $corporateCollectionProfileEnt->profileCode;
			$return['profileType'] = 'custom';
			$return['active'] = $corporateCollectionProfileEnt->active;
		} else {
			$profileCode = \App\Config\CorporateCollectionProfiles::getInstance()->getDefaultItem();
			if ($profileCode) {
				$return['profileType'] = 'default';
				$return['active'] = true;
			} else {
				$return['profileType'] = 'none';
				$return['active'] = false;
			}
		}
		$return['profileCode'] = $profileCode;

		///////////////////////////////////////////////////////////////////////////////////////////
		// LOAD INFO FROM THE PROFILE CODE (if set) - overwrites only the values the are not yet set
		///////////////////////////////////////////////////////////////////////////////////////////
		if ($profileCode) {

			$profileDetails = \App\Config\CorporateCollectionProfiles::getInstance()->get($profileCode);

			// adds TO (auto) addresses
			if ($return['toAuto']===null) { // only if not forced from profile
				// adds TO (auto) addresses
				switch ($profileDetails['recipientToAuto']) {
					case 'corporateEmail':
						if ($corporateEnt->email) {
							$return['toAuto'] = [ $corporateEnt->email ];
						} else {
							$return['toAuto'] = [];
						}
					break;
					case 'corporateMainOfficeEmail':
						if ($corporateEnt->mainOffice->email) {
							$return['toAuto'] = [ $corporateEnt->mainOffice->email ];
						} else {
							$return['toAuto'] = [];
						}
					break;
					case '':
						$return['toAuto'] = [];
					break;
					default:
						throw new \Exception('Invalid toAuto (2) - '.$profileDetails['recipientToAuto']);
				}
			}

			// adds TO (manual) addresses
			if ($return['toManual']===null) {
				$return['toManual'] = $profileDetails['recipientToManual'];
			}

			// adds CC addresses
			if ($return['bccManual']===null) {
				$return['bccManual'] = $profileDetails['recipientBccManual'];
			}

			// dueInDaysPeriod
			if ($return['dueInDaysPeriod']===null) {
				$return['dueInDaysPeriod'] = $profileDetails['dueInDaysPeriod'];
			}

		}

		// group email addresses
		if ($return['profileType']!='none') {
			$return['toFull'] = array_unique( array_merge((array)$return['toAuto'], (array)$return['toManual']) );
			$return['bccFull'] = array_unique( (array)$return['bccManual'] );
		}


		///////////////////////////////////////////////////////////////////////////////////////////
		// ALSO LOADS EXTRA INFO NEEDED FOR THE EMAIL SENDING - JUST FROM THE PROFILE /////////////
		///////////////////////////////////////////////////////////////////////////////////////////
		if ($profileCode) {
			$return['attachment'] = $profileDetails['attachment'];
			$return['subject'] = $profileDetails['emailSubject'];
			$return['body'] = $profileDetails['emailBody'];
		}

		///////////////////////////////////////////////////////////////////////////////////////////
		// CHECK THE RETURN CONTENT ///////////////////////////////////////////////////////////////
		///////////////////////////////////////////////////////////////////////////////////////////
		$this->checkOutput($return);

		// cache and return the output needed for the email sending
		$this->emailData = $return;
		return $return;
	}


	public function getMessages() :\App\MessagesCollector
	{

		if (!$this->messages) {
			throw new \Exception('You must call getData() before calling '.__METHOD__);
		}

		return $this->messages;
	}


	/**
	 * Checks the collected output for major issues.
	 * @param array $output
	 */
	private function checkOutput(array $output)
	{
		if ($output['profileType']=='custom' and !$output['active']) {
			$this->messages->addWarning('The profile for this company is not active.');
		}
		if ($output['profileType']=='none') {
			$this->messages->addWarning('There is no default collection profile to be applied on this company.');
		}

		if (!$output['toFull']) {
			$this->messages->addWarning('No email adddress(es) (auto or manual) for this company - please check the company profile.');
		}

		if ($output['dueInDaysPeriod']===null) {
			$this->messages->addWarning('The field `Days until due date reached` is not filled in neither in company details nor in collection profile.');
		}
	}

}