<?php
namespace App\Worldspan\LineParser\Types\Line;

/**
 *
 * @author Lucian Sirbu
 */
class RA extends \App\Worldspan\LineParser\Types\WorldspanBaseLine
{
	protected $extractRegexp = "/^(?P<rawData>A.+)/sm";

	protected $children = [
        /**
         * This record contains the passenger name, customer number, customer comments and the document numbers associated with this name
         * This record will also contain, an indicator to denote that a Duplicate Document Number was used and an indicator for Electronic Ticketing
         * It will also contain the settlement authorization code for Electronic Exchange or Electronic Refund from the E-ticket carrier, when applicable
         */

		[		'key' => 'key',									'type' => 'Constant',					'len' => 2,					'val' => 'A\\',			'req' => true, ],             // Record Identifier
    	[		'key' => 'NameNumber',							'type' => 'StringDelimitedByChar',		'len' => [1, 5],			'val' => '\\',			'req' => true, ],             // Surname number (See Note 18)
       	[		'key' => '#022',								'type' => 'Separator',																		'req' => true, ],             // Field Separator

      	[		'key' => 'complex:6',							'type' => 'Complex',					'merge' => true,									'req' => true,			'children' => [
			[	'key' => 'PassengerName',						'type' => 'StringDelimitedByChar',		'len' => 68,				'val' => '\\',			'req' => true, ],              // Passenger Name (See Notes 8 and 9)
           	[	'key' => '#024',								'type' => 'Constant',					'len' => 1,					'val' => '\\',			'req' => true, ],              // Field Separator
           	[	'key' => 'PassengerTypeCode',					'type' => 'StringDelimitedByChar',		'len' => 3,					'val' => '\\',			'req' => true, ],              // Passenger Type Code (PTC)
           	[	'key' => '#026',								'type' => 'Constant',					'len' => 1,					'val' => '\\',			'req' => true, ],              // Field Separator
           	[	'key' => 'CustomerNumber',						'type' => 'StringDelimitedByChar',		'len' => [0, 29],        	'val' => '\\',			'req' => true, ],              // Customer Number (Default * if not applicable)
           	[	'key' => '#029',								'type' => 'Constant',					'len' => 1,					'val' => '\\',			'req' => true, ],              // Field Separator
           	[	'key' => 'CustomerComments',					'type' => 'StringDelimitedByChar',		'len' => [0, 114],									'req' => true, ],              // Customer Comments (Default * if not applicable)
           	[	'key' => '#032',								'type' => 'Constant',					'len' => 1,					'val' => '\\',			'req' => true, ],              // Field Separator
           	[	'key' => 'DocumentNumber',						'type' => 'StringDelimitedByChar',		'len' => [0, 19],			'val' => '\\',			'req' => true, ],              // Document Number (See note 17 & CHART A) (See Note 23)
        ]],

       	// only sent for void's (Document Identifier is "V")
		[		'key' => '#035',             					'type' => 'Constant',					'len' => 1,					'val' => '\\',			'req' => false, ],             // Field Separator
		[		'key' => 'OriginalIssueDate',					'type' => 'StringDelimitedByChar',		'len' => 5,			        'val' => '\\',     		'req' => false, ], // Original Issue Date (See Note 15)

       	// only sent if a "separate invoice" option (e.g. SI-, SSI-) is used
        // [		'key' => '#037',								'type' => 'Constant',					'len' => 1,					'val' => '\\',			'req' => false, ],             // Field Separator
        // [		'key' => 'InvoiceNumber',						'type' => 'Integer',					'len' => 6,											'req' => false, ]              // Invoice Number (See Note 13)

       	[		'key' => '#039',								'type' => 'Separator',																		'req' => false, ],             // Field Separator

       	[		'key' => 'complex:8',							'type' => 'Complex',																		'req' => false,			'children' => [
        	[	'key' => 'key',									'type' => 'Constant',          			'len' => 2,					'val' => 'D-',			'req' => true, ],              // Duplicate Document Number Identifier (See Note 19)
        ]],

       	[		'key' => '#042',								'type' => 'Separator',																		'req' => false, ],             // Field Separator

		[		'key' => 'complex:10',							'type' => 'Complex', 					'merge' => true,									'req' => false,			'children' => [
        	[	'key' => 'key',									'type' => 'Constant',          			'len' => 2,					'val' => 'E-',			'req' => true, ],              // Electronic Ticket Indicator (See Note 20)
        ]],

       	[		'key' => '#044',								'type' => 'Separator',																		'req' => false, ],             // Field Separator

		[		'key' => 'complex:12',							'type' => 'Complex',					'merge' => true,									'req' => false,			'children' => [
        	[	'key' => 'key',									'type' => 'Constant',          			'len' => 4,					'val' => 'SAC-',		'req' => true, ],              // Settlement authorization code identifier
            [	'key' => 'SettlementAuthorizationCodeNumber',	'type' => 'StringDelimitedByChar',		'len' => [0, 14],			'val' => '\\',			'req' => false, ],             // Settlement authorization code number
        ]],

        [		'key' => '#047', 								'type' => 'Separator',																		'req' => false, ],             // Field Separator

		[		'key' => 'complex:14',							'type' => 'Complex',					'merge' => true,									'req' => false,			'children' => [
            [	'key' => 'key',									'type' => 'Constant',					'len' => 4,					'val' => 'SAC2-',		'req' => true, ],              // Settlement authorization code identifier
            [	'key' => 'SettlementAuthorizationCodeNumber',	'type' => 'StringDelimitedByChar',   	'len' => [0, 14],			'val' => '\\',			'req' => false, ],             // Settlement authorization code number
        ]],

        [		'key' => '#050',								'type' => 'Separator',																		'req' => false, ],             // Field Separator
        [		'key' => 'key',									'type' => 'Constant',          			'len' => 4,					'val' => 'SAC3-',		'req' => false, ],             // Settlement authorization code identifier
        [		'key' => 'SettlementAuthorizationCodeNumber',	'type' => 'StringRaw',            		'len' => [0, 14],									'req' => false, ],             // Settlement authorization code number

	];

	/**
	 * (non-PHPdoc)
	 * @see \App\Utils\BaseParser\TextParser\BlockAbstract::postExtract()
	 */
	protected function postExtract(\App\Utils\BaseParser\TextParser\ExtractedBlock $ret)
	{
		if ($ret->extractedData['PassengerName']) {
			$ret->extractedData['PassengerName_'] = $this->doExtractPassengerName($ret->extractedData['PassengerName']);
		}

		// extract DocumentNumber
		if ($ret->extractedData['DocumentNumber']) {
			$ret->extractedData['DocumentNumber_'] = $this->doExtractDocumentNumber($ret->extractedData['DocumentNumber']);

			if ($ret->extractedData['DocumentNumber_'] === null) {
				throw new \App\Utils\BaseParser\TextParser\Exception\LineParser(sprintf("Unknwon DocumentNumber format: '%s'. Don't know how to extract the ticket number from it", $ret->extractedData['DocumentNumber']));
			}
		}


		if ($ret->extractedData['OriginalIssueDate']) {
			/*
			 * OriginalIssueDate = 12MAY
			 * we can have as hints either BookingDateAndYear or TransmittingDateAndYear
			 * 	if BookingDateAndYear is set, OriginalIssueDate's year should be after from BookingDateAndYear
			 * 	if TransmittingDateAndYear is set, OriginalIssueDate's year should be before from TransmittingDateAndYear
			 *  else throw exception
			 * */
			$dateFmt = null;

			if ($this->getBaseParent()) {
				if ($this->getBaseParent()->getStoredData('BookingDateAndYear')) {
					$dateFmt = new \App\Utils\BaseParser\TextParser\Types\Date([
						'fmt'=>'DDMMM',
						'onlyFuture' => true,
						'referenceDate'=>$this->getBaseParent()->getStoredData('BookingDateAndYear'),
					]);
				}
				elseif ($this->getBaseParent()->getStoredData('TransmittingDateAndYear')) {
					$dateFmt = new \App\Utils\BaseParser\TextParser\Types\Date([
						'fmt'=>'DDMMM',
						'onlyPast' => true,
						'referenceDate'=>$this->getBaseParent()->getStoredData('TransmittingDateAndYear'),
					]);
				}
				else {
					throw new \App\Utils\BaseParser\TextParser\Exception\LineParser("Neither BookingDateAndYear, nor TransmittingDateAndYear values are set in line R3. Don't know how to extract date from other variables.");
				}
			}
			else {
				$dateFmt = new \App\Utils\BaseParser\TextParser\Types\Date([
					'fmt'=>'DDMMM',
					'onlyPast' => true,
					'referenceDate'=> \Engine\DateTime::create()->formatDateIso(),
				]);
			}

			$dateFmt->setRawData($ret->extractedData['OriginalIssueDate']);

			$dateFmt->extract();
			$ret->extractedData['OriginalIssueDate'] = $dateFmt->getExtractedData();
		}

		return $ret;
	}

	protected function doExtractDocumentNumber($documentNumber)
	{
		$return = null;

		// Worldspan Generated ARC/BSP Ticket (e.g. EZ)
		// Manual ARC/BSP Ticket (e.g. EZLI#4T, EZI#4T)
		if (!$return && $m=$this->getExtractor()->findAndStore("/^(?P<docNumber>[0-9]{10})(?P<endDocNumber>[0-9\s]{3})?$/", $documentNumber)) {
			$return = [
				'type' => 			'Worldspan Generated ARC/BSP Ticket, Manual ARC/BSP Ticket',
				'docNumber' => 		$m->docNumber,
				'endDocNumber' => 	$m->endDocNumber,
			];
		}

		// Prepaid (e.g. EZLI#PT, EZI#PT)
		if (!$return && $m=$this->getExtractor()->findAndStore("/^P(?P<docNumber>[0-9]{10})$/", $documentNumber)) {
			$return = [
				'type' => 			'Prepaid',
				'docNumber' => 		$m->docNumber,
			];
		}

		// Non-ARC/BSP Document (e.g. EZLI#NT, EZI#NT)
		if (!$return && $m=$this->getExtractor()->findAndStore("/^N(?P<docNumber>[0-9]{16})$/", $documentNumber)) {
			$return = [
				'type' => 			'Non-ARC/BSP Document',
				'docNumber' => 		$m->docNumber,
			];
		}

		// Non-ARC/BSP Document (e.g. EZLI#NT, EZI#NT)
		if (!$return && $m=$this->getExtractor()->findAndStore("/^N(?P<docNumber>[0-9]{16})$/", $documentNumber)) {
			$return = [
				'type' => 			'Non-ARC/BSP Document',
				'docNumber' => 		$m->docNumber,
			];
		}

		// Back-Office Generated OPTAT Ticket (e.g. EZI)
		if (!$return && $m=$this->getExtractor()->findAndStore("/^C(?P<docNumber>[0-9]{11})$/", $documentNumber)) {
			$return = [
				'type' => 			'Back-Office Generated OPTAT Ticket',
				'docNumber' => 		$m->docNumber,
			];
		}

		if (!$return && $m=$this->getExtractor()->findAndStore("/^C(?P<docNumber>[0-9]{11})(-(?P<endDocNumber>[0-9]{4}))$/", $documentNumber)) {
			$return = [
				'type' => 			'Back-Office Generated OPTAT Ticket',
				'docNumber' => 		$m->docNumber,
				'endDocNumber' => 	$m->endDocNumber,
			];
		}

		// Back-Office Generated ATB Ticket (e.g. EZI)
		if (!$return && $m=$this->getExtractor()->findAndStore("/^A (?P<FCI>.)(?P<docNumber>[0-9]{11})(-(?P<endDocNumber>[0-9]{4}))$/", $documentNumber)) {
			$return = [
				'type' => 			'Back-Office Generated ATB Ticket',
				'FCI' => 			$m->FCI,
				'docNumber' => 		$m->docNumber,
				'endDocNumber' => 	$m->endDocNumber,
			];
		}

		// Back-Office Generated ATB Boarding-Pass-Only (EZB)
		if (!$return && $m=$this->getExtractor()->findAndStore("/^ABP$/", $documentNumber)) {
			$return = [
				'type' => 			'Back-Office Generated ATB Boarding-Pass-Only',
			];
		}

		// Void Document (DDV)
		if (!$return && $m=$this->getExtractor()->findAndStore("/^V(?P<docNumber>[0-9]{10})(?P<endDocNumber>[0-9\s]{3})?$/", $documentNumber)) {
			$return = [
				'type' => 			'Void Document',
				'docNumber' => 		$m->docNumber,
				'endDocNumber' => 	$m->endDocNumber,
			];
		}

		// Electronic Miscellaneous Document (EMD) (standalone without a ticket being issued at same time) (Using the EMDI entry to issue the EMD)
		if (!$return && $m=$this->getExtractor()->findAndStore("/^J$/", $documentNumber)) {
			$return = [
				'type' => 			'EMD',
			];
		}

		// ??? Pocket LLI (printed on ATB stock)
		// found this in 08414602.prt, example file from worldspan
		if (!$return && $m=$this->getExtractor()->findAndStore("/^L(?P<docNumber>[0-9]{10})$/", $documentNumber)) {
			$return = [
				'type' => 			'Pocket LLI',
				'docNumber' => 		$m->docNumber,
			];
		}

		/*
		 * Automated MCOs
		 *
		 * docs: When issuing an interface message for an Automated MCO (as a stand-alone with no tickets being issued), the document number field of the A Record will show the alpha ‘O’ in place of the document number.
		 *
		 * Alina Fatu:  In cazurile in care primim un fisier unde in locul nr. de bilet avem \O - se emite initial MCO-ul astfel este generat un fisier iar biletul este emis mai tarziu
		 * 	(pt cazul verificat de mine biletul a fost emis dupa 4h) iar la emitere se genereaza un alt fisier unde avem si nr de bilet
		 *
		 @see downtown US/2019-10-08/20554412.prt
		 * */
		if (!$return && $m=$this->getExtractor()->findAndStore("/^O$/", $documentNumber)) {
			$return = [
				'type' => 			'Automated MCO, without issued ticket',
				'docNumber' => 		null,
			];
		}


		return $return;
	}
}
