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

class Itinerary extends \App\Sabre\StructureParser\Structures\Base\Itinerary
{
	/**
	 *
	 * {@inheritDoc}
	 * @see \App\Utils\BaseParser\Structure\StructureParser\Structures\Base\Itinerary::_getData()
	 */
	protected function _getData()
	{
		list($parsedStructure, $transactionType, $transactionIndexes, $internalAssociations) = $this->getTransactionDetails();

		$item = new \App\Sabre\StructureParser\Types\Itinerary();

		$MG = $parsedStructure['MG'][$transactionIndexes['kmg']];

		// load the itinerary from the MG line, if it's filled in and airports are different
		if (!$item->hasSegments()
			&& array_filter([ $MG['MG']['IUGOTV'], $MG['IUGCIN'][0]['IUGCIN']['IUGCSD'], $MG['MG']['IUGDTV'], $MG['IUGCIN'][0]['IUGCIN']['IUGCDT'],])
			&& $MG['MG']['IUGOTV'] != $MG['MG']['IUGDTV']) {

			$this->transaction->getMessagesCollector()->addInfo("Loading itinerary from MG line"); // TODO: [cleanMsgs-transactionGDSs] refactor this from GDSs

			$segment = new \App\Sabre\StructureParser\Types\ItinerarySegment();
			// departure
			$dep = new \App\Sabre\StructureParser\Types\ItineraryLocation();
			$match = $this->match([
					'airportCode' => [
						$MG['MG']['IUGOTV'],
					],
				]);
			$dep->airportCode = 	$MG['MG']['IUGOTV'];
			$dep->cityId = 			$match->cityId;
			$dep->countryCode = 	$match->countryCode;
			$dep->date = 			$MG['IUGCIN'][0]['IUGCIN']['IUGCSD'];

			$segment->departure = $dep;


			// destination
			$dest = new \App\Sabre\StructureParser\Types\ItineraryLocation();
			$match = $this->match([
					'airportCode' => [
						$MG['MG']['IUGDTV'],
					],
				]);
			$dest->airportCode = 	$MG['MG']['IUGDTV'];
			$dest->cityId = 		$match->cityId;
			$dest->countryCode = 	$match->countryCode;
			$dest->date = 			$MG['IUGCIN'][0]['IUGCIN']['IUGCDT'];

			$segment->destination = $dest;

			$segment->supplier->codeAirline = 	$MG['IUGCIN'][0]['IUGCIN']['IUGEMA'];

			$item->appendSegment($segment);
		}

		// no EMD itinerary, try to load "marked for ticketing" segments
		if (!$item->hasSegments() && $parsedStructure['M3']) {
			$this->transaction->getMessagesCollector()->addInfo("Loading itinerary from M3 lines (these are marked for ticketing segments)"); // TODO: [cleanMsgs-transactionGDSs] refactor this from GDSs
			foreach ($parsedStructure['M3'] as $km3=>$M3) {
				if ($M3['M3Air'] && !trim($M3['M3Air']['IU3TKT'])) {			// ignore non ticketing segments
					$segment = new \App\Sabre\StructureParser\Types\ItinerarySegment();
					$segment = $this->fillItinerarySegment($segment, $km3, $M3, $parsedStructure, $transactionType, $transactionIndexes, $internalAssociations);
					// $tempItem->appendSegment($segment);
					$item->appendSegment($segment);
				}
			}
		}

		// no EMD itinerary, try to load any segments
		if (!$item->hasSegments() && $parsedStructure['M3']) {
			$this->transaction->getMessagesCollector()->addInfo("Loading itinerary from M3 line (these are ticketing segments)"); // TODO: [cleanMsgs-transactionGDSs] refactor this from GDSs
			foreach ($parsedStructure['M3'] as $km3=>$M3) {
				if ($M3['M3Air']) {			// ignore non ticketing segments
					$segment = new \App\Sabre\StructureParser\Types\ItinerarySegment();
					$segment = $this->fillItinerarySegment($segment, $km3, $M3, $parsedStructure, $transactionType, $transactionIndexes, $internalAssociations);
					// $tempItem->appendSegment($segment);
					$item->appendSegment($segment);
				}
			}
		}

		return $item;
	}

	// @see \App\Sabre\StructureParser\Structures\Ticketing\Itinerary::fillItinerarySegment()
	protected function fillItinerarySegment(\App\Sabre\StructureParser\Types\ItinerarySegment $segment, $km3, $M3, $parsedStructure, $transactionType, $transactionIndexes, $internalAssociations)
	{
		// $M4 = $parsedStructure['M4'][$transactionIndexes['km1']];
		$M4 = $parsedStructure['M4'][$internalAssociations['M3->M4'][$km3][0]];

		$processedRemarks = $this->transaction->remarks->getProcessedRemarks();

		$IU4CNI = $parsedStructure['M4'][$internalAssociations['M3->M4'][$km3][0]+1]['IU4CNI'];	// the stopOver flag should be read from the previous segment

		// departure
		$dep = new \App\Sabre\StructureParser\Types\ItineraryLocation();
		$match = $this->match([
			'airportCode' => [$M3['M3Air']['IU3DCC'],],
			'airportName' => [$M3['M3Air']['IU3DCY'],],
		]);

		$dep->suggest("airportCode", $M3['M3Air']['IU3DCC']);
		$dep->suggest("airportName", $M3['M3Air']['IU3DCY']);

		$dep->airportCode = $match->airportCode;
		$dep->cityId = 		$match->cityId;
		$dep->countryCode = $match->countryCode;
		$dep->date = 		$M3['M3Air']['IU3DDT_'];
		$dep->time = 		$M3['M3Air']['IU3DTM'];

		$dep->terminal = 	$M3['M3Air']['IU3TRM'];

		$segment->departure = $dep;


		// destination
		$dest = new \App\Sabre\StructureParser\Types\ItineraryLocation();
		$match = $this->match([
			'airportCode' => [$M3['M3Air']['IU3ACC'],],
			'airportName' => [$M3['M3Air']['IU3ACY'],],
		]);

		$dest->suggest("airportCode", $M3['M3Air']['IU3ACC']);
		$dest->suggest("airportName", $M3['M3Air']['IU3ACY']);

		$dest->airportCode = 	$match->airportCode;
		$dest->cityId = 		$match->cityId;
		$dest->countryCode = 	$match->countryCode;
		$dest->date = 			$M3['M3Air']['IU3ADT_'];
		$dest->time = 			$M3['M3Air']['IU3ATM'];

		$dest->terminal = 		$M3['M3Air']['IU3TMA'];

		$segment->destination = $dest;

		// $segment->stopOverPermitted = ($M3['M3Air']['IU3NOS']>0);
		switch ($IU4CNI) {
			case 'O':
				$segment->stopOverPermitted = true;
			break;
			case 'X':
				$segment->stopOverPermitted = false;
			break;
			default:
				$segment->stopOverPermitted = null;
		}

		if (is_int($M3['M3Air']['IU3NOS'])) {
			$segment->stopCounts = 		$M3['M3Air']['IU3NOS'];
		}

		if ($M3['M3Air']['IU3SCC_']) {
			$segment->stopLocations = [];
			foreach ($M3['M3Air']['IU3SCC_'] as $IU3SCC) {
				$stop = new \App\Sabre\StructureParser\Types\ItineraryLocation();
				$stop->airportCode = $IU3SCC;
				$segment->stopLocations[] = $stop;
			}
		}

		$segment->duration = 	$M3['M3Air']['IU3ELT_'];
		$segment->distance = 	$M3['M3Air']['IU3ARM'];

		$segment->supplier->codeAirline = 	$M3['M3Air']['IU3CAR'];

		if ($processedRemarks['OPERATEDBY_SUPPLIER']) {
			// $segment->operatedBy->code3 = $M3['M3Air']['IU3CRT']; // Diana doesn't want this field to be used
			$segment->operatedBy->name = $processedRemarks['OPERATEDBY_SUPPLIER'];
		}

		$segment->serviceClassCode = 		$M3['M3Air']['IU3CLS_']['code'];
		$segment->serviceClass = 			$M3['M3Air']['IU3CLS_']['label'];
		$segment->segmentStatus = 			$M3['M3Air']['IU3AAC'];

		if ($M3['M3Air']['IU3MLI_']) {
			$segment->mealCodes =			array_map(function($a){
				return $a['code'];
			}, $M3['M3Air']['IU3MLI_']);

			$segment->mealLabels =			array_map(function($a){
				return $a['label'];
			}, $M3['M3Air']['IU3MLI_']);
		}

		if (!$segment->fareBasis && $M4['IU4FB2']) {
			$segment->fareBasis = $M4['IU4FB2'];
		}
		if (!$segment->fareBasis && $M4['IU4FBS']) {
			$segment->fareBasis = $M4['IU4FBS'];
		}

		if (!$segment->ticketDesignator && $M4['IU4TD2']) {
			$segment->ticketDesignator = $M4['IU4TD2'];
		}
		if (!$segment->ticketDesignator && $M4['IU4FBS']) {
			$segment->ticketDesignator = explode('/', (string)$M4['IU4FBS'])[1];
		}

		$segment->transportNumber = 		$M3['M3Air']['IU3FLT'];
		$segment->transportModel = 			$M3['M3Air']['IU3EQP'];

		$segment->baggageAllowance = 		$M4['IU4AWL'];

		$segment->supplierRecordLocator = 	$M3['M3Air']['IU3OAL'];

		if ($M3['M3AirVar']['IU3SST_']) {
			foreach ($M3['M3AirVar']['IU3SST_'] as $IU3SST) {
				if ($internalAssociations['IU1PNO->M1'][$IU3SST['paxIdx']]===$transactionIndexes['km1']) {
					$segment->transportSeatNumber = $IU3SST['seatNumber'];
				}
			}
		}

		return $segment;
	}
}
