<?php

namespace Modules\Utils\RemarksAssistedInputs;

/**
 * This class is used for creating the new remark text displayed in the textarea by composing the modified existing remarks (if the values have been changed)
 * with the new assisted remarks added.
 *
 * The flow for filling the textarea with the new text for the remarks values is:
 *
 * - split the input (remarksValues) in two arrays (values and keys) which will be used later when composing the new remarks text.
 * - scan all lines found in the textarea, process the current line and, for the assisted vars found, create the new remark line and replace it
 * 		- if the remark type is blank and the value from th form is 0 (`No`), then we will skip that remark completely
 * - save the new lines in an special finalRemarksList array
 *
 * - scan the remaining assisted remarks (the ones set in the form, but not found in the textarea)
 * 		- if the remark has been found and is not (`only default value` and set to 0), then compose new line
 * 		- else skip the line
 *
 *	- the unassisted remarks added in the textarea will remain on their current line
 *
 * @author LauraMotoc
 *
 */
class Model extends \App\Mvc\ModelAbstract
{
	/**
	 * variable used for storing the remarks type
	 * @var string
	 */
	private $remarksType = '';

	/**
	 * variable used for storing the remarks from the textarea
	 * @var string
	 */
	private $remarksBulk = '';

	public function __construct($remarksType, $remarksBulk)
	{

		if (!$remarksType) {
			throw new \RuntimeException("The remarks type is not set");
		}

		if ($remarksType) {
			// check if remarks type is valid
			if (!in_array($remarksType, \App\Config\Remarks::getInstance()->getValidRemarkTypes())) {
				throw new \RuntimeException("The remarks type is not valid");
			}

			// check if remarks are set
			if (!\App\Config\Remarks::getInstance()->getAllRemarksFromCategory($remarksType)) {
				throw new \RuntimeException("There is no remark configured");
			}

			// check if any assisted remarks are set
			if (!\App\Config\Remarks::getInstance()->remarkTypeHasAssistedRemarks($remarksType)) {
				throw new \RuntimeException("There is no assisted remark configured");
			}

			$this->remarksType = $remarksType;
		}

		if ($remarksBulk) {
			$this->remarksBulk = $remarksBulk;
		}

		parent::__construct();

	}

	/**
	 * Fill remarks values for textarea without changing the order of the existing remarks
	 * @param array $remarksValues
	 * @return string
	 */
	public function fillRemarksValues(Array $remarksValues)
	{
 		$remarksProcessObj = \App\Config\Remarks::getInstance();

 		$remarksConfig = $remarksProcessObj->getAllRemarksFromCategory($this->remarksType);

		$finalRemarksList = [];

		$remarksLines = explodeClean("\n", $this->remarksBulk);

		// These two arrays will be used later to change the value of the remarks using str_replace on the format of the remark
		$remarkReplacingValues_vars = array_map(function($remarkName) { return "[".$remarkName."]";}, array_keys($remarksValues));
		$remarkReplacingValues_values = array_values($remarksValues);

		// clone remarkValues array
		$assistedRemarksValues = $remarksValues;

		// scan the lines of the textarea and update values where needed
		foreach ($remarksLines as $remarkLine) {

			$remarkLine = trim($remarkLine);

			if (!$remarkLine) {
				break;
			}

			// get the processed remarks values
			$remarkLineVars = $remarksProcessObj->getProcessedRemarksDetailed($remarkLine, $remarksConfig);

			$finalRemarkLine = $remarkLine;


			foreach ($remarkLineVars as $remarkLineVarName => $remarkLineVar) {
				// if we find the remark in the assisted remarks returned by the form
				if (isset($assistedRemarksValues[$remarkLineVarName])) {

					// if the remark type is `blank` (`only default value`) and its vaue is 0 (`No`), then we overwrite the line with ''
					if ($remarkLineVar['var']['type'] == 'blank' && $assistedRemarksValues[$remarkLineVarName] == 0) {
						$finalRemarkLine = '';
					}
					else { // otherwise we compose the new remark line by changing the value of the remark
						$finalRemarkLine = str_replace($remarkReplacingValues_vars, $remarkReplacingValues_values, $remarkLineVar['originalRemark']['format']);
					}

 					unset($assistedRemarksValues[$remarkLineVar['var']['name']]);
				}

			}

			if ($finalRemarkLine) {
				$finalRemarksList[]= trim($finalRemarkLine);
			}
		}

		// if there are any assisted remarks not found / set in the textarea
		if ($assistedRemarksValues) {
			foreach ($remarksConfig as $thisRemark) {

				if ($thisRemark['hasAssistedInputs']) {
					$foundRemarkVar = false;
					$onlyDefaultValueTypeRemark = false;

					foreach ($thisRemark['vars'] as $remarkVar) {
						if (isset($assistedRemarksValues[$remarkVar['name']])) {

							if ($remarkVar['type'] == 'blank' && $assistedRemarksValues[$remarkVar['name']] == 0) {
								$onlyDefaultValueTypeRemark = true;
							}

							$foundRemarkVar = true;
							break;
						}
					}

					if ($foundRemarkVar) {
						if (!$onlyDefaultValueTypeRemark) {
							$finalRemarkLine = str_replace($remarkReplacingValues_vars, $remarkReplacingValues_values, $thisRemark['format']);
							$finalRemarksList[]= trim($finalRemarkLine);
						}
						unset($assistedRemarksValues[$remarkVar['name']]);
					}
 				}

				if (!$assistedRemarksValues) {
					break;
				}
			}
		}

		return implode("\r\n", array_unique($finalRemarksList));
	}
}