<?php
namespace App\Amadeus\StructureParser\Structures\Ticketing;

class Itinerary extends \App\Amadeus\StructureParser\Parser\Itinerary
{
	/**
	 * (non-PHPdoc)
	 * @see \App\Amadeus\StructureParser\Parser\Itinerary::isValid()
	 */
	public function isValid()
	{
		$parsedStructure = $this->transaction->getParsedStructure();
		$indexType = $this->transaction->getIndexType();
		$index = $this->transaction->getIndex();

		if($indexType=='H'){
			if(isset($parsedStructure['H'])) {
				return true;
			}
		}

		if($indexType=='H:reissue'){
			if(isset($parsedStructure['H'])) {
				return true;
			}
		}

		if($indexType=='U:ticketing'){
			$UIndexArr = $parsedStructure['assoc:U:pax-segment'][$index->passenger];
			foreach($UIndexArr as $segIdx){
				$U = $parsedStructure['U'][$segIdx];

				if($U['_type']=='01') {
					return true;
				}
			}
		}

		return false;
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Amadeus\StructureParser\Parser\Itinerary::updateInternalSegmentData()
	 */
	protected function updateInternalSegmentData()
	{
		$indexType = $this->transaction->getIndexType();

		if($indexType=='H'){
			$ret = $this->updateInternalSegmentData_H();
			if($ret){
				return $ret;
			}
		}

		if($indexType=='H:reissue'){
			$ret = $this->updateInternalSegmentData_H();
			if($ret){
				return $ret;
			}
		}

		if($indexType=='U:ticketing'){
			$ret = $this->updateInternalSegmentData_U();
			if($ret){
				return $ret;
			}
		}
		return false;
	}


	/**
	 * Get data from a specific line
	 * @return multitype:\App\Amadeus\StructureParser\Types\ItinerarySegment
	 */
	protected function updateInternalSegmentData_H()
	{
		$parsedStructure = $this->transaction->getParsedStructure();
		$index = $this->transaction->getIndex();

		$I = $parsedStructure['I'][$index->passenger];

		$HIdx = 0;
		foreach ($parsedStructure['H'] as $Hk => $H) {
			$Y = $H['Y'][0];
			if($H['_type']!='02'){	// ignore surface segments
				$item = new \App\Amadeus\StructureParser\Types\ItinerarySegment();

				$item->addDataSource(['line' => 'I', 'index' => $index->passenger, ]);
				$item->addDataSource(['line' => 'H', 'index' => $Hk, ]);

				$SEGNBR = (int)$H['SEGNBR'];

				$item->departure->suggest('airport', 		$H['ORIGAIR']);
				$item->departure->suggest('city', 			$H['ORIGCTY']);
				$item->departure->suggest('country', 		$H['ORIGCNT']);
				$item->destination->suggest('airport', 		$H['DESTAIR']);
				$item->destination->suggest('city', 		$H['DESTCTY']);
				$item->destination->suggest('country', 		$H['DESTCNT']);

				// detect the departure airport/city/country
				$match = $item->match([
					'airportCode' => 	[$H['ORIGAIR']],
					'cityCode' => 		[$H['ORIGAIR']],
					'countryCode' => 	[$H['ORIGCNT']],
					'airportName' => 	[$H['ORIGCTY']],
					'cityName' => 		[$H['ORIGCTY']],
					'countryName' => 	[$H['ORIGCNT']],
				], false);
				$item->departure->airportCode = $match->airport??null;
				$item->departure->cityId = 		$match->city??null;
				$item->departure->countryCode = $match->country??null;
				$item->departure->terminal = 	$H['CKINTRM'];


				// detect the destination airport/city/country
				$match = $item->match([
					'airportCode' => 	[$H['DESTAIR']],
					'cityCode' => 		[$H['DESTAIR']],
					'countryCode' => 	[$H['DESTCNT']],
					'airportName' => 	[$H['DESTCTY']],
					'cityName' => 		[$H['DESTCTY']],
					'countryName' => 	[$H['DESTCNT']],
				], false);
				$item->destination->airportCode = 	$match->airport??null;
				$item->destination->cityId = 		$match->city??null;
				$item->destination->countryCode = 	$match->country??null;
				$item->destination->terminal = 		$H['ARRTRM'];

				// detect departure/arrival dates & hours
				$item->departure->date= 		$H['DEPDTE'];
				$item->departure->time= 		$H['DEPTIM'];
				$item->destination->date= 		$H['ARRDTE'];
				$item->destination->time= 		$H['ARRTIM'];

				$item->duration = 				$H['FLTDUR'];
				$item->distance = 				$H['MLTPM'];

				$item->CO2EmissionsInKg = 		$H['CO2'];

				// Stopover Indicator (X=No stopover permitted, O is stopover permitted)
				// this seems to mean that we are allowed to stop at the beginning of the segment, not at the destination, as previously thought
				$item->stopOverPermitted = 		($H['STOP']=='O');

				$item->stopCounts = 			(int)$H['NBRSTOP'];

				// transport details
				$item->supplierCode = 			rtrim((string)$H['AIRCDE']);
				$item->transportNumber = 		rtrim((string)$H['FLTNBR']);
				$item->transportModel = 		rtrim((string)$H['EQUIP']);
				$item->seatNumber = 			($I['S']['SEATINFO'][$Hk]['SEATNBR']?:$I['S']['SEATINFO'][$Hk]['RAILSEAT']);
				$item->segmentType = 			$H['_type'];

				$item->serviceClass= 			$H['CLSSVC_']['label'];
				$item->serviceClassCode = 		$H['CLSSVC_']['code'];
				$item->bookingClass = 			$H['CLSBKG_']['label'];
				$item->bookingClassCode = 		$H['CLSBKG_']['code'];

				$M = $parsedStructure['M']['FARELEM'][$HIdx];
				$item->FB_primaryCode = 		$M['PRIMCDE'];
				$item->FB_farebasis = 			$M['FAREB'];
				$item->FB_ticketDesignator = 	$M['TKTDSG'];

				$item->baggageCode = 			$H['BAGALL'];
				$item->mealCode = 			    $H['MEAL_']['code'];
				$item->mealDescription = 		$H['MEAL_']['label'];

				$item->segmentStatus = 			$H['STATUS_']['code'];
				$item->segmentStatusInPNR = 	$H['PNRSTAT_']['code'];

				if ($Y) {
					$item->operatedByCode = 		$Y['OWNER'];
					$item->operatedByName = 		$Y['OWNNAME'];
				}

				// create the SSR list
				if ($I['SSR']) {
					foreach ($I['SSR'] as $SSRLine) {

						$doAdd = true;	// if no SEGASS specified, assume its associated with all segments
						if ($SSRLine['SEGASS'] && !in_array($SEGNBR, $SSRLine['SEGASS'])) {
							$doAdd = false;
						}

						if ($doAdd) {
							$SSR = new \App\Amadeus\StructureParser\Types\SSRComponent();

							$SSR->type = $SSRLine['SSRTYPE'];
							$SSR->text = $SSRLine['FREE'];
							$SSR->status = $SSRLine['STATCDE'];

							$SSR->category = $SSRLine['category_'];
							$SSR->label = $SSRLine['label_'];

							$item->SSRList->appendSSR($SSR);
						}
					}
				}

				$this->itinerary->appendSegment($item->fixIssue_24h());
				$HIdx++;
			}
		}

		return true;
	}

	/**
	 * Get data from a specific line
	 */
	protected function updateInternalSegmentData_U()
	{
		$parsedStructure = $this->transaction->getParsedStructure();
		$index = $this->transaction->getIndex();

		if(isset($index->TSA)){
			$sourceSegments = $parsedStructure['assoc:pax:TSA-segment'][$index->passenger][$index->TSA];
		}else{
			$sourceSegments = $parsedStructure['assoc:U:pax-segment'][$index->passenger];
		}

		foreach($sourceSegments as $idx){
			$U = $parsedStructure['U'][$idx];
			if($U['_type']=='01'){	// only report ticketing segments
				$item = new \App\Amadeus\StructureParser\Types\ItinerarySegment();

				$item->addDataSource(['line' => 'I', 'index' => $index->passenger, ]);
				$item->addDataSource(['line' => 'H', 'index' => $idx, ]);

				// detect the departure airport/city/country
				$match = $item->match([
					'airportCode' => 	[$U['ORIGAIR']],
					'airportName' => 	[$U['ORIGCTY']],
					'cityCode' => 		[$U['ORIGAIR']],
					'cityName' => 		[$U['ORIGCTY']],
					'countryCode' => 	[$U['ORIGCNT']],
					'countryName' => 	[$U['ORIGCNT']],
				]);
				$item->departure->airportCode = $match->airport;
				$item->departure->cityId = 		$match->city;
				$item->departure->countryCode = $match->country;
				$item->departure->terminal = 	$U['CKINTRM'];


				// detect the destination airport/city/country
				$match = $item->match([
					'airportCode' => 	[$U['DESTAIR']],
					'airportName' => 	[$U['DESTCTY']],
					'cityCode' => 		[$U['DESTAIR']],
					'cityName' => 		[$U['DESTCTY']],
					'countryCode' => 	[$U['DESTCNT']],
					'countryName' => 	[$U['DESTCNT']],
				]);
				$item->destination->airportCode = 	$match->airport;
				$item->destination->cityId = 		$match->city;
				$item->destination->countryCode = 	$match->country;
				$item->departure->terminal = 		$U['CKINTRM'];


				// detect departure/arrival dates & hours
				$item->departure->date= 		$U['DEPDTE'];
				$item->departure->time= 		$U['DEPTIM'];
				$item->destination->date= 		$U['ARRDTE'];
				$item->destination->time = 		$U['ARRTIM'];

				$item->duration = 				$U['FLTDUR'];
				$item->distance = 				$U['MLTPM'];

				$item->CO2EmissionsInKg = 		$U['CO2'];

				// Stopover Indicator (X=No stopover permitted, O is stopover permitted)
				// this seems to mean that we are allowed to stop at the beginning of the segment, not at the destination, as previously thought
				$item->stopOverPermitted = 		($U['STOP']=='O');

				// transport details
				$item->supplierCode = 			rtrim($U['AIRCDE']);
				$item->transportNumber = 		rtrim($U['FLTNBR']);
				$item->transportModel = 		rtrim($U['EQUIP']);
				$item->segmentType = 			$U['_type'];

				$item->serviceClass= 			$U['CLSSVC_']['label'];
				$item->serviceClassCode = 		$U['CLSSVC_']['code'];
				$item->bookingClass = 			$U['CLSBKG_']['label'];
				$item->bookingClassCode = 		$U['CLSBKG_']['code'];

				$item->segmentStatus = 			$U['STATUS_']['code'];
				$item->segmentStatusInPNR = 	$U['PNRSTAT_']['code'];

				$this->itinerary->appendSegment($item->fixIssue_24h());
			}
		}

		return true;
	}
}
