<?php
namespace App\Sabre\StructureParser\Structures\Base;

abstract class Remarks extends \App\Sabre\StructureParser\Structures\Base\Base
{
	/**
	 * Get the remarks data, the base call, used in ticketing & reissue operations
	 */
	protected function base_getData(\App\Sabre\StructureParser\Types\Remarks $item, $parsedStructure, $transactionType, $transactionIndexes, $internalAssociations, $sources=['M7', 'M8', 'M9', 'ME', 'MX', ])
	{
		$originalItem = clone $item;

		$xtr = new \App\Utils\BaseParser\Utils\Extractor\Single();

		// TODO km1 cannot be an array anymore
		$km1 = (is_array($transactionIndexes['km1'])?$transactionIndexes['km1']: [$transactionIndexes['km1']]);
		if (in_array('M7', $sources) && $parsedStructure['M7']) {
			foreach ($parsedStructure['M7'] as $M7) {
				$addRemark = true;
				if (!$M7['M7']['IU7RMK']) {			// remark text not present
					$addRemark = false;
				}
				elseif ($M7['M7ASP']['IU7ASP']) {	// passenger association
					$addRemark = false;
					foreach($M7['M7ASP']['IU7ASP'] as $IU7ASP) {
						foreach ($km1 as $k) {
							if ($IU7ASP['IU8ASP_PSG']===$internalAssociations['M1->IU1PNO'][$k]) {
								$addRemark = true;
								break;
							}
						}
					}
				}

				if ($addRemark) {
					$comp = new \App\Sabre\StructureParser\Types\RemarkComponent();
					$comp->type = 'itinerary';
					$comp->content = $M7['M7']['IU7RMK'];

					if ($item->remarkIsAssociated($comp, $parsedStructure, $km1)) {
						$item->append($comp);
					}
				}

			}
		}

		if (in_array('M8', $sources) && $parsedStructure['M8']) {
			/**
			 * allow manually associationg remarks with some passengers. The parsed format looks like this:
			 * REMARK:VALUE-3.1
			 * 	This means the remark is associated with pax #3.
			 * 	The '.1' is ignored for now, the format resembles the M5 line format and we don't know what it means anyway
			 *
			 * If any of the remarks in this file follow this format, then they are considered to contain manually associated remarks,
			 * 	and remarks without any association identifier will be considered 'global' and always associated.
			 *
			 * If no remarks follow this format, then they are all considered global, unless they are automatically associated via the IU8ASP_PSG mechanism
			 * 	this was the default mechanism before TD-6698
			 */
			$hasRemarksWithManualAssociation = (count(array_filter(array_map(function($M8) use ($xtr) {
				if ($M8['M8ASP']['IU8ASP']) {
					return false;
				}
				return $xtr->contains("/-[0-9]\.[0-9]$/", $M8['M8']['IU8RMK']);
			}, $parsedStructure['M8'])))!=0);

			foreach ($parsedStructure['M8'] as $M8) {
				if ($hasRemarksWithManualAssociation) {
					$addRemark = true;	// if the remark doesn;t end with '-3.1' to mean it is assigned to pas 3, then cconsider the remark global, and assign it no matter what
					if ($xtr->contains("/-[0-9]\.[0-9]$/", $M8['M8']['IU8RMK'])) {	// passenger association
						$addRemark = false;
						$IU1PNO = ltrim($parsedStructure['M1'][$transactionIndexes['km1']]['M1']['IU1PNO'], '0');
						if ($xtr->contains("/-{$IU1PNO}\.[0-9]$/", $M8['M8']['IU8RMK'])) {	// passenger association
							$addRemark = true;
						}
					}
				}
				else {
					$addRemark = true;
					if (!$M8['M8']['IU8RMK']) {			// remark text not present
						$addRemark = false;
					}
					elseif ($M8['M8ASP']['IU8ASP']) {	// passenger association
						$addRemark = false;
						foreach($M8['M8ASP']['IU8ASP'] as $IU8ASP) {
							foreach ($km1 as $k) {
								if ($IU8ASP['IU8ASP_PSG']===$internalAssociations['M1->IU1PNO'][$k]) {
									$addRemark = true;
									break;
								}
							}
						}
					}
				}
				if ($addRemark) {
					$comp = new \App\Sabre\StructureParser\Types\RemarkComponent();
					$comp->type = 'passenger';
					$comp->content = $M8['M8']['IU8RMK'];

					if ($item->remarkIsAssociated($comp, $parsedStructure, $km1)) {
						$item->append($comp);
					}
				}
			}
		}

		if (in_array('M9', $sources) && $parsedStructure['M9']) {
			foreach ($parsedStructure['M9'] as $M9) {
				if (!$xtr->contains("/^(PT-SSR|PT-OSI) .*/", $M9['M9']['IU9RMK']) && $M9['M9']['type_']!='SSR DOCS') {
					$addRemark = true;
					if (!$M9['M9']['IU9RMK']) {			// remark text not present
						$addRemark = false;
					}
					elseif ($M9['M9']['IU9ASP']) {	// passenger association
						$addRemark = false;
						foreach($M9['M9']['IU9ASP'] as $IU9ASP) {
							foreach ($km1 as $k) {
								if ($IU9ASP['IU9ASP_PSG']===$internalAssociations['M1->IU1PNO'][$k]) {
									$addRemark = true;
									break;
								}
							}
						}
					}

					if ($addRemark) {
						$comp = new \App\Sabre\StructureParser\Types\RemarkComponent();
						$comp->type = 'interface';
						$comp->content = $M9['M9']['IU9RMK'];

						if ($item->remarkIsAssociated($comp, $parsedStructure, $km1)) {
							$item->append($comp);
						}
					}
				}
			}
		}

		if (in_array('ME', $sources)) {
			$km3s = [];
			if ($transactionIndexes['km3s']) {
				$km3s = $transactionIndexes['km3s'];
			}
			elseif (is_array($transactionIndexes['km3'])) {
				$km3s = $transactionIndexes['km3'];
			}
			if ($parsedStructure['ME'] && $km3s) {
				foreach ($km3s as $km3) {
					if ($internalAssociations['M3->ME'][$km3]) {
						foreach ($internalAssociations['M3->ME'][$km3] as $kme) {
							$ME = $parsedStructure['ME']['ME'][$kme];

							foreach ($ME['IUERMK'] as $IUERMK) {
								$comp = new \App\Sabre\StructureParser\Types\RemarkComponent();
								$comp->type = 'itinerary';
								$comp->content = $IUERMK;

								$item->append($comp);
							}
						}
					}
				}
			}
		}


		// debug($transactionIndexes, $parsedStructure, $internalAssociations);

		// we need to get all associated MX lines. In order to get to that we need to go through M5->M2->MX
		if (in_array('MX', $sources) && $parsedStructure['MX']) {
			$MXs = [];
			if ($transactionIndexes['km5s']) {
				foreach ($transactionIndexes['km5s'] as $km5) {
					if ($internalAssociations['M5->M2'][$km5]) {
						foreach ($internalAssociations['M5->M2'][$km5] as $km2) {
							if ($internalAssociations['M2->MX'][$km2]) {
								foreach ($internalAssociations['M2->MX'][$km2] as $kmx) {
									$MXs[]= $parsedStructure['MX'][$kmx];
								}
							}
						}
					}
				}
			}

			$hasVCNPayment = false;
			if ($MXs) {
				foreach ($MXs as $MX) {
					if (in_array($MX['MX']['IUXTYP'], ['04', ])) {
						$hasVCNPayment = true;

						if ($MX['MX']['IUX4VAR']['IUX4CAC']) {
							$comp = new \App\Sabre\StructureParser\Types\RemarkComponent();
							$comp->type = 'custom';
							$comp->content = sprintf("VCN Customer account code:%s", $MX['MX']['IUX4VAR']['IUX4CAC']);
							$item->append($comp);
						}

						if ($MX['MX']['IUX4VAR']['IUX4DID']) {
							$comp = new \App\Sabre\StructureParser\Types\RemarkComponent();
							$comp->type = 'custom';
							$comp->content = sprintf("VCN deployment id:%s", $MX['MX']['IUX4VAR']['IUX4DID']);
							$item->append($comp);
						}
					}
				}
			}

			if ($hasVCNPayment) {
				$this->transaction->nonStructuredDataSet('commissionIncludedInSupplierPrice', false);
				$this->transaction->getMessagesCollector()->addInfo(sprintf("[%s] commission price was extracted from remarks", __METHOD__));
			}
		}

		// trigger registered plugins
		\Engine\Plugins\Manager::getInstance()->executeEvent('Sabre-StructureParser-Structures-Base-Remarks-base_getData', [
			'this' => $this,

			'originalItem' => $originalItem,
			'item' => $item,
			'parsedStructure' => $parsedStructure,
			'transactionType' => $transactionType,
			'transactionIndexes' => $transactionIndexes,
			'internalAssociations' => $internalAssociations,
			'sources' => $sources,
		]);

		return $item;
	}

}
