<?php
namespace Modules\Invoices\SupplierInvoices\ImportStatements\Suppliers\Travco;

class Model extends \Modules\Invoices\SupplierInvoices\ImportStatements\Model\XlsxAbstract
{
	public $headers = [
		'REP1' => [
			'invoiceNumber' 		=> 'Invoice Number',
			'invoiceDate' 			=> 'Date',
			'invoiceDueDate' 		=> 'Due Date',
			'confirmationNumber' 	=> 'Booking Ref',
			'passengerName' 		=> 'Passenger Name',
			'currency' 				=> 'Currency',
			'priceValue' 			=> 'Total',
			'outstanding' 			=> 'Outstanding',
		],

		'REP2' => [
			'invoiceNumber' 		=> 'Invoice Number',
			'invoiceDate' 			=> 'Date',
			'invoiceDueDate' 		=> 'Due Date',
			'confirmationNumber' 	=> 'Booking Ref',
			'agent' 				=> 'Agent Ref',
			'passengerName' 		=> 'Passenger Name',
			'currency' 				=> 'Currency',
			'priceValue' 			=> 'Total',
			'settled' 				=> 'Settled',
			'outstanding'			=> 'Outstanding',
			'rmt' 					=> 'Rmt/Prt',
			'notes' 				=> 'Notes',
		],

		'REP3' => [
			'invoiceNumber' 		=> 'Invoice Number',
			'invoiceDate' 			=> 'Date',
			'invoiceDueDate' 		=> 'Due Date',
			'confirmationNumber' 	=> 'Booking Ref',
			'agent' 				=> 'Agent Ref',
			'passengerName' 		=> 'Passenger Name',
			'currency' 				=> 'Currency',
			'priceValue' 			=> 'Total',
			'settled' 				=> 'Settled',
			'outstanding'			=> 'Outstanding',
			'rmt' 					=> 'Rmt/Prt',
		],

	];

	/**
	 *
	 * {@inheritDoc}
	 * @see \Modules\Invoices\SupplierInvoices\ImportStatements\Model\GeneralAbstract::check()
	 */
	public function check():void
	{
		// check input data
		if (!$this->inputData['idSupplier']['id']) {
			throw new \Modules\Invoices\SupplierInvoices\ImportStatements\Model\Exception("Supplier not set.");
		}
		else {
			$suppObj = \Entity\Supplier::select($this->inputData['idSupplier']['id']);
			if (!$suppObj->recordExists()) {
				throw new \Modules\Invoices\SupplierInvoices\ImportStatements\Model\Exception("Supplier not valid.");
			}
		}

		if (!$this->inputData['serviceCode']) {
			throw new \Modules\Invoices\SupplierInvoices\ImportStatements\Model\Exception("Service code not set.");
		}
		else {
			if (!\App\Config\Services_Basic::getInstance()->checkService($this->inputData['serviceCode'])) {
				throw new \Modules\Invoices\SupplierInvoices\ImportStatements\Model\Exception("Service code not valid.");
			}

			if (!$this->inputData['vatQuota']) {
				throw new \Modules\Invoices\SupplierInvoices\ImportStatements\Model\Exception("VAT quota not set.");
			}
			else {
				$rowVatCfg = \App\Config\SupplierInvoice_Vats::getInstance()->getAll();
				if (!array_key_exists($this->inputData['vatQuota'], $rowVatCfg[$this->inputData['serviceCode']]['list'])) {
					throw new \Modules\Invoices\SupplierInvoices\ImportStatements\Model\Exception("VAT quota not valid.");
				}
			}
		}
	}

	/**
	 *
	 * {@inheritDoc}
	 * @see \Modules\Invoices\SupplierInvoices\ImportStatements\Model\XlsxAbstract::DetectFormat()
	 */
	protected function detectFormat(Array $rawRows):?string
	{
		$header1 = array_filter(reset(array_slice($rawRows, 12, 1)));
		$header2 = array_filter(reset(array_slice($rawRows, 14, 1)));

		foreach ($this->headers as $key => $header) {
			if ($header1 && array_values($header) == array_values($header1)) {
				return $key;
			}
			elseif ($header2 && array_values($header) == array_values($header2)) {
				return $key;
			}
		}

		return null;
	}

	/**
	 * Check if format is supported and cleanup rows
	 * {@inheritDoc}
	 * @see \Modules\Invoices\SupplierInvoices\ImportStatements\Model\XlsxAbstract::getCleanedRows()
	 */
	protected function getCleanedRows(Array $rawRows):array
	{
		$cleanedRows = [];

		foreach ($rawRows as $row) {
			if ($this->detectedFormat == 'REP3') {
				$row = array_slice($row, 0, 11);
			}

			// we check $row[0] and $row[1] because apart from the header and the actual values the rest of the rows have either or both null
			if ($row[0] and $row[1] and $row != array_values($this->headers[$this->detectedFormat])) {
				$cleanedRows[] = $row;
			}
		}

		return $cleanedRows;
	}

	/**
	 *
	 * {@inheritDoc}
	 * @see \Modules\Invoices\SupplierInvoices\ImportStatements\Model\XlsxAbstract::getGroupedRows()
	 */
	protected function getGroupedRows(Array $processedRows):array
	{
		$groupedRows = [];
		foreach ($processedRows as $row) {
			$groupedRows[$row['invoiceNumber']][] = $row;
		}

		return $groupedRows;
	}

	/**
	 *
	 * {@inheritDoc}
	 * @see \Modules\Invoices\SupplierInvoices\ImportStatements\Model\XlsxAbstract::addSupplierInvoices()
	 */
	protected function populateSupplierInvoices():array
	{
		$suppInvEntList = [];

		foreach ($this->invoicesData as $invoiceNo => $invRows) {

			// get supplier invoice rows vat cfgs
			$rowVatCfg = \App\Config\SupplierInvoice_Vats::getInstance()->getAll();

			$suppInvEnt = \Entity\SupplierInvoice::insert();

			$suppInvEnt->invoiceNumber = 	$invoiceNo;
			$suppInvEnt->idSupplier	= 		$this->inputData['idSupplier']['id'];
			$suppInvEnt->idUser	= 			CURRENT_ID_USER;
			$suppInvEnt->idOffice	= 		CURRENT_ID_OFFICE;

			$rows = [];

			foreach ($invRows as $invRow) {
				$suppInvEnt->invoiceDate = 	\Engine\DateTime::createFromFormat('d/m/Y', $invRow['invoiceDate'])->formatDateIso();
				$suppInvEnt->dueDate = 		\Engine\DateTime::createFromFormat('d/m/Y', $invRow['invoiceDueDate'])->formatDateIso();

				$suppInvEnt->currency = 	$invRow['currency'];


				$row = \Entity\SupplierInvoiceRow::insert();
				$row->confirmationNumber = 	$this->getCleanConfirmationNumber((string)$invRow['confirmationNumber']);

				if ($invRow['passengerName']) {
					$customerName = explode(" ", $invRow['passengerName']);
					// remove title from passenger name
					array_pop($customerName);

					$customer = array_filter($customerName);
					$customerEntMatch = new \App\EntityMatch\Customer('intersect');
					$customerEntMatch->setName(reset($customer), end($customer));
					$customerEntMatch->search();

					if ($customerEntMatch->getResultsCount()==1) {
						$passenger = $customerEntMatch->getFirstMatchDetails();
						$row->idPassenger = $passenger['id'];
					}
				}

				$row->quantity = 			1;
				$row->serviceCode = 		$this->inputData['serviceCode'];
				$row->checkIn =				\Engine\DateTime::createFromFormat('d/m/Y', $invRow['invoiceDate'])->formatDateIso();
				$row->rowType = 			'price';
				$row->vatText = 			$this->inputData['vatQuota'];

				$vatPercent = $rowVatCfg[$this->inputData['serviceCode']]['list'][$this->inputData['vatQuota']];

				$val = round($invRow['priceValue']*100/(100 + $vatPercent), 2);
				$vat = round($invRow['priceValue'] - $val, 2);

				$row->priceValue = $val;
				$row->vatValue = $vat;

				$rows[] = $row;
			}

			$suppInvEnt->rows = $rows;
			$suppInvEntList[]= $suppInvEnt;

		}

		return $suppInvEntList;
	}

	/**
	 * Cleans the confNo by elimianting everything after the first "/".
	 * @param string $confirmationNumber
	 * @return string
	 */
	private function getCleanConfirmationNumber(string $confirmationNumber) :string
	{
		$pos = strpos($confirmationNumber, '/');
		if (!$pos) { // not found or on first position
			return $confirmationNumber;
		}
		else {
			return substr($confirmationNumber, 0, $pos);
		}
	}

}
