<?php

namespace Modules\Utils\GdsProfileFill;

/**
 * Merges the original remarks (normal remarks text, multi-line) with some manually set remark vars.
 * @author Gabriel Grosu
 */
class MergeRemarks
{

	/**
	 * Remark type (service, invoice, corporate, etc).
	 * @var string
	 */
	private $remarkType;


	/**
	 * The original remarks (lines).
	 * @var string
	 */
	private $originalRemarks;

	/**
	 * The associative array of remarks vars to be added to the current remarks
	 * @var array
	 */
	private $remarksVars;


	public function __construct($remarkType, $originalRemarks, array $remarksVars)
	{
		$this->remarkType = $remarkType;
		$this->originalRemarks = $originalRemarks;
		$this->remarksVars = $remarksVars;

		$remarksCfg = \App\Config\Remarks::getInstance();
		if (!in_array($this->remarkType, $remarksCfg->getValidRemarkTypes())) {
			throw new \Exception("The remarks type is not valid");
		}

	}

	/**
	 * Merges the remark vars into the original remarks and returns the new remarks text.
	 * The original remarks are first cleaned of the lines that point to one of the remark vars (to
	 * avoid duplicating them) and then adds new remark lines corresponding to the manually set
	 * remark vars.
	 * @return string
	 */
	public function getMergedRemarks()
	{

		// if nothing else to set - return the original remarks.
		if (!$this->remarksVars) {
			return $this->originalRemarks;
		}

		// split remark lines
		$originalRemarksLines = explodeClean("\n", $this->originalRemarks);

		// start populating new remark lines, by including only remarks that have nothing to do with remarkVars
		$newRemarksLines = [];
		foreach ($originalRemarksLines as $rmLine) {
			// parse current rm line
			$remarkVars = \App\Config\Remarks::process($rmLine, $this->remarkType);
			if ( !$remarkVars or !array_intersect(array_keys($remarkVars), array_keys($this->remarksVars)) ) {
				$newRemarksLines[] = trim($rmLine);
			}
		}

		$remarkVars = $this->remarksVars;

		// adds new remark lines corresponding to remarkVars
		foreach (\App\Config\Remarks::getInstance()->getAllRemarksFromCategory('service') as $remarkFormat) {

			$replaceValues = [];
			$allVarsFound = true; // indicate that for multiple vars in the same remark format
			$cleanRmVars = []; // cleans the remarks so it's faster on next formats and avoid duplicates
			foreach($remarkFormat['vars'] as $varDet) {
				$currentRmVar = $varDet['name'];

				if ( array_key_exists($currentRmVar, $remarkVars) and strlen($remarkVars[$currentRmVar]) ) {
					$replaceValues['['.$currentRmVar.']'] = $remarkVars[$currentRmVar];
					$cleanRmVars[] = $currentRmVar;
				} else {
					$allVarsFound = false;
				}
			}

			// if the remark format was (fully) covered by current remark values
			if ($replaceValues and $allVarsFound) {
				$newRemarksLines[] = str_replace(array_keys($replaceValues), array_values($replaceValues), $remarkFormat['format']);
				// we may have multiple remarks formats pointing to the same var - eliminate the found vars
				foreach($cleanRmVars as $rmVar) {
					unset($remarkVars[$rmVar]);
				}
			}


		}

		return implode("\r\n", $newRemarksLines);

	}

}
