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

class Transaction extends \App\Utils\BaseParser\Structure\StructureParser\Structures\Transaction
{
	/**
	 * The tarnsaction document data
	 * @var \App\Sabre\StructureParser\Types\Document
	 */
	public $documents = 	null;
	/**
	 * The tarnsaction document data
	 * @var \App\Sabre\StructureParser\Types\Itinerary
	 */
	public $itinerary = 	null;
	/**
	 * The tarnsaction document data
	 * @var \App\Sabre\StructureParser\Types\Passengers
	 */
	public $passengers = 	null;
	/**
	 * The tarnsaction document data
	 * @var \App\Sabre\StructureParser\Types\Price
	 */
	public $price = 		null;
	/**
	 * The tarnsaction document data
	 * @var \App\Sabre\StructureParser\Types\Supplier
	 */
	public $supplier = 		null;

	/**
	 * The agent data
	 * @var \App\Sabre\StructureParser\Types\Agent
	 */
	public $agent = 		null;

	/**
	 * The cancellation policy
	 * @var \App\Sabre\StructureParser\Types\CancellationPolicy
	 */
	public $cancellationPolicy = null;

	/**
	 * The relations
	 * @var \App\Sabre\StructureParser\Types\Relations
	 */
	public $relations = 	null;

	/**
	 * The remarks
	 * @var \App\Sabre\StructureParser\Types\Remarks
	 */
	public $remarks = 		null;

	/**
	 * The extra data
	 * @var \App\Sabre\StructureParser\Types\Extradata
	 */
	public $extraData = 	null; // not available

	/**
	 * {@inheritDoc}
	 * @see \App\Utils\BaseParser\Structure\StructureParser\Structures\Transaction::getStorageObjInstance()
	 */
	public function getStorageObjInstance()
	{
		return \App\Sabre\Storage\StorageHandler::getInstance();
	}

	public function getData()
	{
		switch ($this->transactionType) {
			case 'ticketing':
				$this->remarks = 	$this->extractAs("\App\Sabre\StructureParser\Structures\Ticketing\Remarks");
				$this->documents = 	$this->extractAs("\App\Sabre\StructureParser\Structures\Ticketing\Documents");
				$this->passengers = $this->extractAs("\App\Sabre\StructureParser\Structures\Ticketing\Passengers");
				$this->itinerary = 	$this->extractAs("\App\Sabre\StructureParser\Structures\Ticketing\Itinerary");
				$this->supplier = 	$this->extractAs("\App\Sabre\StructureParser\Structures\Ticketing\Supplier");
				$this->agent = 		$this->extractAs("\App\Sabre\StructureParser\Structures\Ticketing\Agent");
				$this->price = 		$this->extractAs("\App\Sabre\StructureParser\Structures\Ticketing\Price");

				if ($this->price) {
					$this->price->checkIntegrity([], $this->messages, $this);
				}
			break;

			case 'NDCTicketing':
				$this->remarks = 	$this->extractAs("\App\Sabre\StructureParser\Structures\NDCTicketing\Remarks");
				$this->documents = 	$this->extractAs("\App\Sabre\StructureParser\Structures\NDCTicketing\Documents");
				$this->passengers = $this->extractAs("\App\Sabre\StructureParser\Structures\NDCTicketing\Passengers");
				$this->itinerary = 	$this->extractAs("\App\Sabre\StructureParser\Structures\NDCTicketing\Itinerary");
				$this->supplier = 	$this->extractAs("\App\Sabre\StructureParser\Structures\NDCTicketing\Supplier");
				$this->agent = 		$this->extractAs("\App\Sabre\StructureParser\Structures\NDCTicketing\Agent");
				$this->price = 		$this->extractAs("\App\Sabre\StructureParser\Structures\NDCTicketing\Price");

				if ($this->price) {
					$this->price->checkIntegrity([], $this->messages, $this);
				}
			break;

			case 'LCCTicketing':
				$this->remarks = 	$this->extractAs("\App\Sabre\StructureParser\Structures\LCCTicketing\Remarks");
				$this->documents = 	$this->extractAs("\App\Sabre\StructureParser\Structures\LCCTicketing\Documents");
				$this->passengers = $this->extractAs("\App\Sabre\StructureParser\Structures\LCCTicketing\Passengers");
				$this->itinerary = 	$this->extractAs("\App\Sabre\StructureParser\Structures\LCCTicketing\Itinerary");
				$this->supplier = 	$this->extractAs("\App\Sabre\StructureParser\Structures\LCCTicketing\Supplier");
				$this->agent = 		$this->extractAs("\App\Sabre\StructureParser\Structures\LCCTicketing\Agent");
				$this->price = 		$this->extractAs("\App\Sabre\StructureParser\Structures\LCCTicketing\Price");

				if ($this->price) {
					$this->price->checkIntegrity([], $this->messages, $this);
				}
			break;

			case 'reissue':
				$this->remarks = 	$this->extractAs("\App\Sabre\StructureParser\Structures\Reissue\Remarks");
				$this->documents = 	$this->extractAs("\App\Sabre\StructureParser\Structures\Reissue\Documents");
				$this->passengers = $this->extractAs("\App\Sabre\StructureParser\Structures\Reissue\Passengers");
				$this->itinerary = 	$this->extractAs("\App\Sabre\StructureParser\Structures\Reissue\Itinerary");
				$this->supplier = 	$this->extractAs("\App\Sabre\StructureParser\Structures\Reissue\Supplier");
				$this->agent = 		$this->extractAs("\App\Sabre\StructureParser\Structures\Reissue\Agent");
				$this->price = 		$this->extractAs("\App\Sabre\StructureParser\Structures\Reissue\Price");


				$this->relations = 	$this->extractAs("\App\Sabre\StructureParser\Structures\Reissue\Relations");

				if ($this->price) {
					$this->price->checkIntegrity([], $this->messages, $this);
				}
			break;

			case 'void':
				$this->documents = 	$this->extractAs("\App\Sabre\StructureParser\Structures\Void\Documents");
			break;

			case 'refundRaw':
				$this->remarks = 	$this->extractAs("\App\Sabre\StructureParser\Structures\RefundRaw\Remarks");
				$this->documents = 	$this->extractAs("\App\Sabre\StructureParser\Structures\RefundRaw\Documents");
				$this->passengers = $this->extractAs("\App\Sabre\StructureParser\Structures\RefundRaw\Passengers");
				$this->agent = 		$this->extractAs("\App\Sabre\StructureParser\Structures\RefundRaw\Agent");
				$this->price = 		$this->extractAs("\App\Sabre\StructureParser\Structures\RefundRaw\Price");

				if ($this->price) {
					$this->price->checkIntegrity(['negativeTotal'=>true, 'negativeSupplier'=>true], $this->messages, $this);
				}
			break;

			case 'refund':
				$this->remarks = 	$this->extractAs("\App\Sabre\StructureParser\Structures\Refund\Remarks");
				$this->documents = 	$this->extractAs("\App\Sabre\StructureParser\Structures\Refund\Documents");
				$this->passengers = $this->extractAs("\App\Sabre\StructureParser\Structures\Refund\Passengers");
				$this->agent = 		$this->extractAs("\App\Sabre\StructureParser\Structures\Refund\Agent");
				$this->price = 		$this->extractAs("\App\Sabre\StructureParser\Structures\Refund\Price");

				if ($this->price) {
					$this->price->checkIntegrity(['negativeTotal'=>true, 'negativeSupplier'=>true], $this->messages, $this);
				}
			break;

			case 'hotel':
				$this->remarks = 			$this->extractAs("\App\Sabre\StructureParser\Structures\Hotel\Remarks");
				$this->documents = 			$this->extractAs("\App\Sabre\StructureParser\Structures\Hotel\Documents");
				$this->passengers = 		$this->extractAs("\App\Sabre\StructureParser\Structures\Hotel\Passengers");
				$this->itinerary = 			$this->extractAs("\App\Sabre\StructureParser\Structures\Hotel\Itinerary");
				$this->supplier = 			$this->extractAs("\App\Sabre\StructureParser\Structures\Hotel\Supplier");
				$this->agent = 				$this->extractAs("\App\Sabre\StructureParser\Structures\Hotel\Agent");
				$this->price = 				$this->extractAs("\App\Sabre\StructureParser\Structures\Hotel\Price");
				$this->extraData = 			$this->extractAs("\App\Sabre\StructureParser\Structures\Hotel\Extradata");
				$this->cancellationPolicy = $this->extractAs("\App\Sabre\StructureParser\Structures\Hotel\CancellationPolicy");
				if ($this->price) {
					$this->price->checkIntegrity([], $this->messages, $this);
				}
			break;

			case 'car':
				$this->remarks = 	$this->extractAs("\App\Sabre\StructureParser\Structures\Car\Remarks");
				$this->documents = 	$this->extractAs("\App\Sabre\StructureParser\Structures\Car\Documents");
				$this->passengers = $this->extractAs("\App\Sabre\StructureParser\Structures\Car\Passengers");
				$this->supplier = 	$this->extractAs("\App\Sabre\StructureParser\Structures\Car\Supplier");
				$this->itinerary = 	$this->extractAs("\App\Sabre\StructureParser\Structures\Car\Itinerary");
				$this->price = 		$this->extractAs("\App\Sabre\StructureParser\Structures\Car\Price");
				$this->agent = 		$this->extractAs("\App\Sabre\StructureParser\Structures\Car\Agent");

				if ($this->price) {
					$this->price->checkIntegrity([], $this->messages, $this);
				}
			break;

			case 'train':
				$this->remarks = 	$this->extractAs("\App\Sabre\StructureParser\Structures\Train\Remarks");
				$this->documents = 	$this->extractAs("\App\Sabre\StructureParser\Structures\Train\Documents");
				$this->passengers = $this->extractAs("\App\Sabre\StructureParser\Structures\Train\Passengers");
				$this->supplier = 	$this->extractAs("\App\Sabre\StructureParser\Structures\Train\Supplier");
				$this->itinerary = 	$this->extractAs("\App\Sabre\StructureParser\Structures\Train\Itinerary");
				$this->price = 		$this->extractAs("\App\Sabre\StructureParser\Structures\Train\Price");
				$this->agent = 		$this->extractAs("\App\Sabre\StructureParser\Structures\Train\Agent");

				if ($this->price) {
					$this->price->checkIntegrity([], $this->messages, $this);
				}
			break;

			case 'airTaxi':
				$this->remarks = 	$this->extractAs("\App\Sabre\StructureParser\Structures\AirTaxi\Remarks");
				$this->documents = 	$this->extractAs("\App\Sabre\StructureParser\Structures\AirTaxi\Documents");
				$this->passengers = $this->extractAs("\App\Sabre\StructureParser\Structures\AirTaxi\Passengers");
				$this->supplier = 	$this->extractAs("\App\Sabre\StructureParser\Structures\AirTaxi\Supplier");
				$this->agent = 		$this->extractAs("\App\Sabre\StructureParser\Structures\AirTaxi\Agent");
				$this->price = 		$this->extractAs("\App\Sabre\StructureParser\Structures\AirTaxi\Price");

				if ($this->price) {
					$this->price->checkIntegrity([], $this->messages, $this);
				}
			break;

			case 'EMD':
				$this->remarks = 	$this->extractAs("\App\Sabre\StructureParser\Structures\EMD\Remarks");
				$this->documents = 	$this->extractAs("\App\Sabre\StructureParser\Structures\EMD\Documents");
				$this->relations = 	$this->extractAs("\App\Sabre\StructureParser\Structures\EMD\Relations");
				$this->passengers = $this->extractAs("\App\Sabre\StructureParser\Structures\EMD\Passengers");
				$this->itinerary = 	$this->extractAs("\App\Sabre\StructureParser\Structures\EMD\Itinerary");
				$this->supplier = 	$this->extractAs("\App\Sabre\StructureParser\Structures\EMD\Supplier");
				$this->agent = 		$this->extractAs("\App\Sabre\StructureParser\Structures\EMD\Agent");
				$this->price = 		$this->extractAs("\App\Sabre\StructureParser\Structures\EMD\Price");
				$this->extraData = 	$this->extractAs("\App\Sabre\StructureParser\Structures\EMD\Extradata");

				// if ($this->price) {	// TODO: App/Sabre/90.ImportedOrder/SA-Fursan-testcases/+K7, EMD, VAT change/ failes with this enabled
				// 	$this->price->checkIntegrity([], $this->messages, $this);
				// }
			break;

			case 'EMDForGroup':
				$this->remarks = 	$this->extractAs("\App\Sabre\StructureParser\Structures\EMDForGroup\Remarks");
				$this->documents = 	$this->extractAs("\App\Sabre\StructureParser\Structures\EMDForGroup\Documents");
				$this->relations = 	$this->extractAs("\App\Sabre\StructureParser\Structures\EMDForGroup\Relations");
				$this->passengers = $this->extractAs("\App\Sabre\StructureParser\Structures\EMDForGroup\Passengers");
				$this->itinerary = 	$this->extractAs("\App\Sabre\StructureParser\Structures\EMDForGroup\Itinerary");
				$this->supplier = 	$this->extractAs("\App\Sabre\StructureParser\Structures\EMDForGroup\Supplier");
				$this->agent = 		$this->extractAs("\App\Sabre\StructureParser\Structures\EMDForGroup\Agent");
				$this->price = 		$this->extractAs("\App\Sabre\StructureParser\Structures\EMDForGroup\Price");
				$this->extraData = 	$this->extractAs("\App\Sabre\StructureParser\Structures\EMDForGroup\Extradata");

				// if ($this->price) {	// this is disabled because the test for EMD is also disabled
				// 	$this->price->checkIntegrity([], $this->messages, $this);
				// }
			break;

			case 'MCO':
				$this->remarks = 	$this->extractAs("\App\Sabre\StructureParser\Structures\MCO\Remarks");
				$this->documents = 	$this->extractAs("\App\Sabre\StructureParser\Structures\MCO\Documents");
				$this->relations = 	$this->extractAs("\App\Sabre\StructureParser\Structures\MCO\Relations");
				$this->passengers = $this->extractAs("\App\Sabre\StructureParser\Structures\MCO\Passengers");
				$this->itinerary = 	$this->extractAs("\App\Sabre\StructureParser\Structures\MCO\Itinerary");
				$this->supplier = 	$this->extractAs("\App\Sabre\StructureParser\Structures\MCO\Supplier");
				$this->agent = 		$this->extractAs("\App\Sabre\StructureParser\Structures\MCO\Agent");
				$this->price = 		$this->extractAs("\App\Sabre\StructureParser\Structures\MCO\Price");
				$this->extraData = 	$this->extractAs("\App\Sabre\StructureParser\Structures\MCO\Extradata");

				if ($this->price) {
					$this->price->checkIntegrity([], $this->messages, $this);
				}
			break;

			case 'documentIssue':
				$this->remarks = 	$this->extractAs("\App\Sabre\StructureParser\Structures\DocumentIssue\Remarks");
				$this->documents = 	$this->extractAs("\App\Sabre\StructureParser\Structures\DocumentIssue\Documents");
				$this->passengers = $this->extractAs("\App\Sabre\StructureParser\Structures\DocumentIssue\Passengers");
				$this->itinerary = 	$this->extractAs("\App\Sabre\StructureParser\Structures\DocumentIssue\Itinerary");
				$this->supplier = 	$this->extractAs("\App\Sabre\StructureParser\Structures\DocumentIssue\Supplier");
				$this->agent = 		$this->extractAs("\App\Sabre\StructureParser\Structures\DocumentIssue\Agent");
				$this->price = 		$this->extractAs("\App\Sabre\StructureParser\Structures\DocumentIssue\Price");
				$this->extraData = 	$this->extractAs("\App\Sabre\StructureParser\Structures\DocumentIssue\Extradata");

				// if ($this->price) {	// aallow negative & positive prices
				// 	$this->price->checkIntegrity([], $this->messages, $this);
				// }
			break;

			default:
				throw new \Exception("Invalid transaction type: {$this->transactionType}");
		}

		// post-processing
		$this->internal_extract_company($this->passengers, $this->remarks, $this->processor->getParsedStructure());

		$this->internal_fillCCIRemark($this->price, $this->remarks);

		return $this;
	}

	protected function internal_extract_company(?\App\Sabre\StructureParser\Types\Passengers $passengers, ?\App\Sabre\StructureParser\Types\Remarks $remarks, $parsedStructure)
	{
		if ($passengers) {
			foreach ($passengers->passengers as $pax) {
				if (!$pax->companyId && $remarks) {
					$processedRemarks = $remarks->getProcessedRemarks();
					if ($processedRemarks['corporateCode']) {
						$pax->companyId = $processedRemarks['corporateCode'];
					}
				}

				if (!$pax->companyId && $parsedStructure['M0']['M0']['IU0DKN']['IU0DKB']) {
					$pax->companyId = 	sprintf("%s%s", $parsedStructure['M0']['M0']['IU0DKN']['IU0DKB'], $parsedStructure['M0']['M0']['IU0DKN']['IU0DKC']);
				}
			}
		}
	}

	public function internal_fillCCIRemark($price, $remarks)
	{
		if ($price and $price->formOfPayment and $price->formOfPayment->isPaidWith('CC')) {
			$formOfPaymentComponent = $price->formOfPayment->getPaymentByType('CC', 0);

			if ($formOfPaymentComponent->ccCompanyIndicator and $formOfPaymentComponent->ccNumber) {
				$newRemarkComponent = new \App\Sabre\StructureParser\Types\RemarkComponent();
				$newRemarkComponent->type = 'custom';
				$newRemarkComponent->content = sprintf("CCI %s %s", $formOfPaymentComponent->ccCompanyIndicator, substr($formOfPaymentComponent->ccNumber, -4));

				$remarks->append($newRemarkComponent);
			}
		}
	}

	public function isTicketingIssue($parsedStructure, $transactionType, $transactionIndexes)
	{
		if ($transactionIndexes['km5']!==null) {
			return (bool)$parsedStructure['M5'][$transactionIndexes['km5']];
		}
		return false;
	}
}