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

class Model extends \Modules\Invoices\SupplierInvoices\ImportStatements\Model\XlsxAbstract
{
	public $headers = [
		'REP1' => [
			'confirmationNumber'	=>	'Booking Number',	// Confirmation number
			'bookingId'				=>	'Booking ID',
			'agencyReference'		=>	'Agency Reference',
			'userName'				=>	'User Name',
			'checkInDate'			=>	'Check in',			// Check-In
			'checkOutDate'			=>	'Check out',
			'cxlDeadline'			=>	'CXL DeadLine',
			'priceValue'			=>	'Amount due',		// Supplier invoice row value
			'paidAmount'			=>	'Amount paid',
			'currency'				=>	'Currency',			// supplier invoice currency
			'passengerName'			=>	'Lead Name',		// Passenger (try to match with a passenger from TINA)
			'cityName'				=>	'City',				// Location (try to match with the country from TINA and if it is not matched, leave blank)
			'supplierProductName'	=>	'Hotel',			// Supplier product (try to match it with the supplier product from TINA)
			'agencyName'			=>	'Agency Name',
			'status'				=>	'Status',
			'displayMarkup' 		=>	'Display MarkUp',
			'sellingPrice' 			=>	'Selling Price',
			'dueDate' 				=>	'Payment Due Date',	// supplier invoice due date
		],

		'REP2' => [
			'statementId'			=>	'Statement Id',
			'confirmationNumber'	=>	'Booking Number',
			'bookingId'				=>	'Booking Id',
			'agentReference'		=>	'Agent Reference',
			'cityName'				=>	'City',				// Location (try to match with the country from TINA and if it is not matched, leave blank)
			'supplierProductName'	=>	'Hotel',			// Supplier product (try to match it with the supplier product from TINA)
			'passengerName'			=>	'Lead Name',		// Passenger (try to match with a passenger from TINA)
			'cxlDeadline'			=>	'CXL DeadLine',
			'checkInDate'			=>	'Check in',			// Check-In
			'checkOutDate'			=>	'Check out',
			'priceValue'			=>	'Amount paid',
			'currency'				=>	'Paid Currency',	// supplier invoice currency
			'paidBy' 				=>	'Paid By',
			'agencyName'			=>	'Agency Name',
			'userName'				=>	'User Name',
			'status'				=>	'Status',
		],
	];

	/**
	 * {@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.");
				}
			}
		}

		if (!$this->inputData['invoiceNumber']) {
			throw new \Modules\Invoices\SupplierInvoices\ImportStatements\Model\Exception("Invoice number not set.");
		}

		if (!$this->inputData['invoiceDate']) {
			throw new \Modules\Invoices\SupplierInvoices\ImportStatements\Model\Exception("Invoice date not set.");
		}

		if (!$this->inputData['dueDate'] and $this->detectedFormat == 'REP2') {
			throw new \Modules\Invoices\SupplierInvoices\ImportStatements\Model\Exception("Due date not set.");
		}
	}


	/**
	 * {@inheritDoc}
	 * @see \Modules\Invoices\SupplierInvoices\ImportStatements\Model\XlsxAbstract::detectFormat()
	 */
	protected function detectFormat(Array $rawRows):?string
	{

		$header1 = reset(array_filter($rawRows));

		foreach ($this->headers as $key => $header) {
			if (array_values($header) == array_values($header1)) {
				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 ($row[0] && $row != array_values($this->headers[$this->detectedFormat])) {
				$cleanedRows[] = $row;
			}
		}

		return $cleanedRows;
	}

	/**
	 * {@inheritDoc}
	 * @see \Modules\Invoices\SupplierInvoices\ImportStatements\Model\GeneralAbstract::getGroupedRows()
	 */
	protected function getGroupedRows(Array $processedRows):array
	{
		return $processedRows;
	}

	/**
	 * {@inheritDoc}
	 * @see \Modules\Invoices\SupplierInvoices\ImportStatements\Model\GeneralAbstract::populateSupplierInvoices()
	 */
	protected function populateSupplierInvoices():array
	{
		// get supplier invoice rows vat cfgs
		$rowVatCfg = \App\Config\SupplierInvoice_Vats::getInstance()->getAll();

		$suppInvEnt = \Entity\SupplierInvoice::insert();
		$suppInvEnt->invoiceNumber = $this->inputData['invoiceNumber'];
		$suppInvEnt->invoiceDate =   $this->inputData['invoiceDate'];
		$suppInvEnt->idSupplier	=    $this->inputData['idSupplier']['id'];
		$suppInvEnt->currency =		 $this->invoicesData[0]['currency'];

		if ($this->detectedFormat == 'REP2') {
			$suppInvEnt->dueDate = $this->inputData['dueDate'];
		}
		else {
			// get minimum due date from the rows - although they should be the same
			$dueDates = array_filter(array_unique(array_map(function($col){
				return $col['dueDate'];
			}, $this->invoicesData)));

			$suppInvEnt->dueDate = \Engine\DateTime::createFromFormat('d/m/Y', min($dueDates))->formatDateIso();
		}

		$suppInvEnt->idUser	= 		CURRENT_ID_USER;
		$suppInvEnt->idOffice	= 	CURRENT_ID_OFFICE;

		$rows = [];
		foreach ($this->invoicesData as $rawRow) {
			$row = \Entity\SupplierInvoiceRow::insert();
			$row->checkIn = \Engine\DateTime::createFromFormat('d/m/Y', $rawRow['checkInDate'])->formatDateIso();
			$row->confirmationNumber = $rawRow['confirmationNumber'];

			$row->quantity = 			1;
			$row->serviceCode = 		$this->inputData['serviceCode'];
			$row->rowType = 			'price';
			$row->vatText = 			$this->inputData['vatQuota'];

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

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

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

			if ($rawRow['cityName']) {
				$matchCity = new \App\EntityMatch\City('intersect');
				$matchCity->setName($rawRow['cityName']);
				$matchCity->search();
				if ($matchCity->getResultsCount()==1) {
					$row->cityId = $matchCity->getFirstMatchId();
					$row->countryCode = \Entity\City::select($matchCity->getFirstMatchId())->countryCode;
				}
			}

			if ($rawRow['supplierProductName']) {
				$matchSupplierProduct = new \App\EntityMatch\SupplierProduct('intersect');
				$matchSupplierProduct->setProductName($rawRow['supplierProductName'], false);
				$matchSupplierProduct->search();
				$row->idSupplierProduct = $matchSupplierProduct->getFirstMatchId();
			}

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

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

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

			$rows[] = $row;
		}

		$suppInvEnt->rows = $rows;

		//var_dump($this->inputData, $this->invoicesData, $suppInvEnt); die;
		return [$suppInvEnt];
	}
}

