<?php

namespace Modules\Admin\ImportEntities\Model\Import;

class ImportedServicesUpdate extends \Modules\Admin\ImportEntities\Model\ImportAbstract
{

	/**
	 * The fields that can be imported for this entity
	 * @var array
	 */
	protected $fields = [
		'serviceId', 'serviceType', 'offerStatus',
		'departureCityName', 'departureCityCode','departureCountryCode', 'departureStationCode',
		'destinationCityName', 'destinationCityCode', 'destinationCountryCode', 'destinationStationCode',
		'startDate', 'endDate', 'supplierProductSystemId', 'supplierProductName', 'category', 'productType', 'multiplierCount', 'multiplierValue',
		'companyOwner', 'companySystemId', 'externalSystemId', 'externalSystemDate', 'confirmationNumber', 'optionDate',
		'supplierPrice', 'commission', 'commissionable', 'discount', 'serviceFee', 'taxes', 'taxDetails', 'currency', 'ignoreSupplierOnDocuments', 'ticketsDate',
		'supplierName', 'supplierSystemId', 'responsibleUserSystemId', 'responsibleOfficeSystemId', 'formOfPayment', 'formOfCashing', 'remarks',
	];

	/**
	 * This entity uses the date format`
	 * @var Boolean
	 */
	protected $useDateFormat = true;

	/**
	 *
	 * {@inheritDoc}
	 * @see \Modules\Admin\ImportEntities\Model\ImportAbstract::process()
	 * @return \App\MessagesCollector
	 */
	public function process(): \App\MessagesCollector
	{
		$_LANG = \App\Loader_Lang::getInstance()->getGlobal();

		$messagesFromImport = new \App\MessagesCollector();

		// LOOP THROUGH EACH ROW
		foreach ($this->fileData as $row) {

			try {
				\DB::startTransaction();

				$importedOrderObj = new \App\ImportedOrder\Order();
				$this->populateImportedOrder($row, $importedOrderObj);

				$importedOrderEnt = \Entity\ImportedOrder::insert();
				$importedOrderEnt->order = $importedOrderObj;
				$importedOrderEnt->applyMode = 'merge';

				$importedOrderEnt->save();

				\DB::commitTransaction();
				$messagesFromImport->addSuccess(sprintf($_LANG['Admin']['ImportEntities']['index']['msgs']['services']['saveOk'], $importedOrderEnt->getId()));

			} catch (\App\Entity\Exception $e) {
				$messagesFromImport->addWarning(sprintf($_LANG['Admin']['ImportEntities']['index']['msgs']['services']['saveError'], $row['serviceId']));
				$messagesFromImport->appendMessages($e->getMessagesCollector());
				\DB::rollbackTransaction();
			}
		}

		return $messagesFromImport;

	}

	/**
	 *
	 * @param array $row
	 * @param \App\ImportedOrder\Order $importedOrderObj
	 * @return void
	 */
	private function populateImportedOrder(array $row, \App\ImportedOrder\Order $importedOrderObj): void
	{

		// config
		$CFG  = \Engine\Loader_Cfg::getInstance()->getGlobal();

		// MAIN IO OBJECTS //////////////////////////////////////////////////////////////////
		$importedOrderObj->externalSystemCode = $CFG['Admin']['ImportEntities']['ImportedServicesInsert']['system']['default'];

		// IMPORTED SERVICE OBJECT ////////////////////////////////////////////////////////////////
		$importedServiceObj = new \App\ImportedOrder\Service();
		$serviceIdSystem =						$row['serviceId'];
		$importedServiceObj->idSystem =			$serviceIdSystem;
		$importedServiceObj->operation =		'update';
		$importedServiceObj->forceOperation =	false;

		// set supplier
		$supplierObj = null;
		if ($row['supplierName'] or $row['supplierSystemId']) {
			$supplierObj = new \App\ImportedOrder\Supplier();
			if ($row['supplierName']){
				$supplierObj->name = $row['supplierName'];
			}
			if ($row['supplierSystemId']) {
				$supplierObj->idSystem = $row['supplierSystemId'];
			}

			$importedOrderObj->addSupplier($supplierObj);
		}

		$supplierProductObj = null;
		// product name
		if ($row['supplierProductName'] || $row['supplierProductSystemId']) {
			$supplierProductObj = new \App\ImportedOrder\SupplierProduct();
			if ($row['supplierProductName']) {
				$supplierProductObj->name = $row['supplierProductName'];
			}

			if ($row['supplierProductSystemId']) {
				$supplierProductObj->idSystem = $row['supplierProductSystemId'];
			}

			$importedOrderObj->addSupplierProduct($supplierProductObj);
			$importedServiceObj->addSupplierProduct($supplierProductObj);
		}

		// owner corporate
		if ($row['companyOwner'] or $row['companySystemId']) {
			$ownerCorpObj = new \App\ImportedOrder\Corporate();

			if ($row['companyOwner']) {
				$ownerCorpObj->idSystem = $row['companyOwner'];
				$ownerCorpObj->nameStandard = $row['companyOwner'];
			}

			if ($row['companySystemId']) {
				$ownerCorpObj->idTina = $row['companySystemId'];
			}

			$importedOrderObj->addCorporate($ownerCorpObj);
			$importedOrderObj->ownerCorporate = $ownerCorpObj;
		}

		// service type
		$serviceTypeObj = null;
		if ($row['serviceType']) {
			$serviceTypeObj = new \App\ImportedOrder\ServiceType();
			$serviceTypeObj->codeSystem =	$row['serviceType'];
			$serviceTypeObj->name =			$row['serviceType'];

			$importedServiceObj->serviceType = $serviceTypeObj;
		}

		// DEPARTURE DATETIME
		if ($row['startDate']) {
			$startDate = \Engine\DateTime::createFromFormat($this->dateFormat, $row['startDate'])->formatDateIso();

			$departureStartDateObj = new \App\ImportedOrder\DateTime();
			$departureStartDateObj->dateStart = $startDate;
			$departureStartDateObj->dateEnd = $startDate;

			$importedServiceObj->departureDateTime = $departureStartDateObj;
		}

		// DESTINATION DATETIME
		if ($row['endDate']) {
			$endDate = \Engine\DateTime::createFromFormat($this->dateFormat, $row['endDate'])->formatDateIso();

			$destinationEndDateObj = new \App\ImportedOrder\DateTime();
			$destinationEndDateObj->dateStart = $endDate;
			$destinationEndDateObj->dateEnd = $endDate;

			$importedServiceObj->destinationDateTime = $destinationEndDateObj;
		}

		// DEPARTURE PLACE
		$departurePlaceObj = null;
		if ($row['departureStationCode'] or $row['departureCityName'] or $row['departureCityCode'] or $row['departureCountryCode']) {
			# departure station
			$departurePlaceObj = new \App\ImportedOrder\Place();
			$departureStationObj = new \App\ImportedOrder\Station();

			if ($row['departureStationCode']) {
				$departureStationObj->code3 = $row['departureStationCode'];
			}
			$departurePlaceObj->station = $departureStationObj;

			# departure city
			if ($row['departureCityName'] or $row['departureCityCode'] or $row['departureCountryCode']) {
				$departureCityObj = new \App\ImportedOrder\City();
				if ($row['departureCityCode']) {
					$departureCityObj->code3 = $row['departureCityCode'];
				}
				if ($row['departureCityName']) {
					$departureCityObj->name = $row['departureCityName'];
				}
				$departureStationObj->city = $departureCityObj;

				# departure country
				if ($row['departureCountryCode']) {
					$departureCountryObj = new \App\ImportedOrder\Country();
					$departureCountryObj->code2 = $row['departureCountryCode'];
					$departureCityObj->country = $departureCountryObj;
				}
			}

			$importedServiceObj->departurePlace = $departurePlaceObj;
		}

		// DESTINATION PLACE
		$destinationPlaceObj = null;
		# destination place
		if ($row['destinationStationCode'] or $row['destinationCityName'] or $row['destinationCityCode'] or $row['destinationCountryCode']) {
			# destination station
			$destinationPlaceObj = new \App\ImportedOrder\Place();
			$destinationStationObj = new \App\ImportedOrder\Station();

			if ($row['destinationStationCode']) {
				$destinationStationObj->code3 = $row['destinationStationCode'];
			}
			$destinationPlaceObj->station = $destinationStationObj;

			# destination city
			if ($row['destinationCityName'] or $row['destinationCityCode'] or $row['destinationCountryCode']) {
				$destinationCityObj = new \App\ImportedOrder\City();
				if ($row['destinationCityCode']) {
					$destinationCityObj->code3 = $row['destinationCityCode'];
				}
				if ($row['destinationCityName']) {
					$destinationCityObj->name = $row['destinationCityName'];
				}
				$destinationStationObj->city = $destinationCityObj;

				if ($row['destinationCountryCode']) {
					$destinationCountryObj = new \App\ImportedOrder\Country();
					$destinationCountryObj->code2 = $row['destinationCountryCode'];
					$destinationCityObj->country = $destinationCountryObj;
				}
			}

			$importedServiceObj->destinationPlace = $destinationPlaceObj;
		}

		// remarks
		$remarks = (string)$row['remarks'];
		if ($row['remarks'] == 'blank') {
			$importedServiceObj->remarks = '';
		}
		else {
			foreach ($row as $name=>$value) {
				if (str_starts_with($name, 'remark:') and strlen($value)) {
					$rem = str_replace('remark:', '', $name);
					$remarks .= "\n" . sprintf($rem, $value);
				}
			}

			$externalSystemCode = $CFG['Admin']['ImportEntities']['ImportedServicesInsert']['system']['default'];
			$serviceDetails = \Entity\ImportedService::getDetailsByServiceExtSys($row['serviceId'], \Entity\ExtResSystem::getSystemIdByCode($externalSystemCode), true);

			$remarksMergerObj = new \Modules\Utils\AddRemarksBulk\Model('service', $serviceDetails['remarks'], trim($remarks));
			$serviceRemarksFinal = $remarksMergerObj->processRemarks();

			$importedServiceObj->remarks = $serviceRemarksFinal;
		}

		// multiplier
		if (is_numeric($row['multiplierCount'])) {
			if ($row['multiplierValue']) {
				$importedServiceObj->addMultiplierItem($row['multiplierCount'], $row['multiplierValue'], $row['multiplierValue']);
			}
			else {
				$importedServiceObj->multipliers = $row['multiplierCount'];
			}
		}

		// category
		if ($row['category']) {
			$importedServiceObj->addCategory($row['category'], $row['category']);
		}

		// product type
		if ($row['productType']) {
			$importedServiceObj->addProductType($row['productType'], $row['productType']);
		}

		// resp user
		if ($row['responsibleUserSystemId']) {
			$respUserObj = new \App\ImportedOrder\User();
			$respUserObj->idSystem = $row['responsibleUserSystemId'];

			$importedServiceObj->respUser = $respUserObj;
		}

		// resp office
		if ($row['responsibleOfficeSystemId']) {
			$respOfficeObj = new \App\ImportedOrder\Office();
			$respOfficeObj->idSystem = $row['responsibleOfficeSystemId'];

			$importedServiceObj->respOffice = $respOfficeObj;
		}

		$offerStatus = strtolower($row['offerStatus']);

		// STATUS CONFIRMED => offer
		if ($offerStatus == 'confirmed' or $offerStatus == 'notconfirmed') {
			$importedOfferObj = new \App\ImportedOrder\Offer();
			$importedOfferObj->idSystem = $serviceIdSystem;

			// product name
			if ($supplierProductObj) {
				$importedOfferObj->supplierProduct = $supplierProductObj;
			}

			// departure datetime
			if ($row['startDate']) {
				$importedOfferObj->departureDateTime = \Engine\DateTime::createFromFormat($this->dateFormat, $row['startDate']);
			}

			// departure place
			if ($departurePlaceObj) {
				$importedOfferObj->departurePlace = $departurePlaceObj;
			}

			// destination datetime
			if ($row['endDate']) {
				$importedOfferObj->destinationDateTime = \Engine\DateTime::createFromFormat($this->dateFormat, $row['endDate']);
			}

			// destination place
			if ($destinationPlaceObj) {
				$importedOfferObj->destinationPlace = $destinationPlaceObj;
			}

			// external system date
			if ($row['externalSystemDate']) {
				if ( $row['externalSystemDate'] == 'blank' ) {
					$importedOfferObj->externalSystemReservationDate = "";
				} else {
					$importedOfferObj->externalSystemReservationDate = \Engine\DateTime::createFromFormat($this->dateFormat, $row['externalSystemDate'])->formatDateIso();
				}
			}

			// external system id
			if ($row['externalSystemId']) {
				if ( $row['externalSystemId'] == 'blank' ) {
					$importedOfferObj->externalSystemReservationId = "";
				} else {
					$importedOfferObj->externalSystemReservationId = $row['externalSystemId'];
				}
			}

			// supplier
			if ($supplierObj) {
				$importedOfferObj->supplier = $supplierObj;
			}

			// service type
			if ($serviceTypeObj) {
				$importedOfferObj->serviceType = $serviceTypeObj;
			}

			// category
			if ($row['category']) {
				$importedOfferObj->setCategory($row['category'], $row['category']);
			}

			// product type
			if ($row['productType']) {
				$importedOfferObj->setProductType($row['productType'], $row['productType']);
			}

			// multiplier
			if (is_numeric($row['multiplierCount'])) {
				if ($row['multiplierValue']) {
					$importedOfferObj->addMultiplierItem($row['multiplierCount'], $row['multiplierValue'], $row['multiplierValue']);
				}
				else {
					$importedOfferObj->multipliers = $row['multiplierCount'];
				}
			}

			// option date
			if ($row['optionDate']) {
				if ( $row['optionDate'] == 'blank' ) {
					$importedOfferObj->optionDate = "";
				} else {
					$importedOfferObj->optionDate = \Engine\DateTime::createFromFormat($this->dateFormat, $row['optionDate'])->formatDateIso();
				}
			}

			// confirmation number
			if ($row['confirmationNumber']) {
				if ( $row['confirmationNumber'] == 'blank' ) {
					$importedOfferObj->confirmationNumber = "";
				} else {
					$importedOfferObj->confirmationNumber = $row['confirmationNumber'];
				}
			}

			// total currency
			if ($row['currency']) {
				$importedOfferObj->totalCurrency = $row['currency'];
			}
			if (strlen($row['commissionable'])) {
				$importedOfferObj->commissionable = (bool)$row['commissionable'];
			}
			if (strlen($row['ignoreSupplierOnDocuments'])) {
				$importedOfferObj->ignoreSupplierOnDocuments = (bool)$row['ignoreSupplierOnDocuments'];
			}

			// supplier price
			if (strlen($row['supplierPrice'])) {
				$importedOfferObj->servicePriceTotal = $row['supplierPrice'];
				$importedOfferObj->servicePriceCurrency = $row['currency'];
			}

			// commission
			if (strlen($row['commission'])) {
				$importedOfferObj->commissionTotal = $row['commission'];
				$importedOfferObj->commissionCurrency = $row['currency'];
			}

			// discount
			if (strlen($row['discount'])) {
				$importedOfferObj->discountTotal = $row['discount'];
				$importedOfferObj->discountCurrency = $row['currency'];
			}

			// service fee
			if (strlen($row['serviceFee'])) {
				$importedOfferObj->serviceFeeTotal = $row['serviceFee'];
				$importedOfferObj->serviceFeeCurrency = $row['currency'];
			}

			// taxes
			if (strlen($row['taxes'])) {
				$importedOfferObj->taxTotal = $row['taxes'];
				$importedOfferObj->taxCurrency = $row['currency'];
			}

			// tax details
			if ($row['taxDetails']) {
				foreach ( explodeClean('/', $row['taxDetails']) as $thisTax) {
					$thisTaxClean = trim($thisTax);
					$taxCode = substr($thisTaxClean, 0, 2);
					$taxValue = substr($thisTaxClean, 2);
					$importedOfferObj->addTaxCode($taxCode, $taxValue, $row['currency']);
				}
			}

			// tickets date
			if ($row['ticketsDate']) {
				if ( $row['ticketsDate'] == 'blank' ) {
					$importedOfferObj->ticketDate = "";
				} else {
					$importedOfferObj->ticketDate = \Engine\DateTime::createFromFormat($this->dateFormat, $row['ticketsDate'])->formatDateIso();
				}
			}

			// FOP and FOC
			if ($row['formOfPayment']) {
				if ($row['formOfPayment'] == 'blank') {
					$importedOfferObj->formOfPayment = "";
				} else {
					$importedOfferObj->formOfPayment = $row['formOfPayment'];
				}
			}
			if ($row['formOfCashing']) {
				if ($row['formOfCashing'] == 'blank') {
					$importedOfferObj->formOfCashing = "";
				} else {
					$importedOfferObj->formOfCashing = $row['formOfCashing'];
				}
			}

			$importedServiceObj->chosenOffer = $importedOfferObj;
			$importedServiceObj->chosenOfferConfirmed = ($offerStatus=='confirmed');

		}

		// ADD THE SERVICE TO ORDER
		$importedOrderObj->addService($importedServiceObj);

	}
}
