<?php

namespace Entity;

abstract class Validator_Service_BaseAbstract extends \App\Entity\Utils\Extension_ValidateDefaultAbstract
{


	/**
	 * Validates the service locations fields for service insert/update
	 * @return Boolean
	 */
	protected function check_insertUpdate_serviceLocation()
	{

		// get current fields details
		$fields=$this->entity->getFields();

		// current collected messages
		$currMessages=$this->entity->getMessages();

		// current entity id
		$currentIdEntity=$this->entity->getId();

		// current operation
		$operation=$this->entity->getOperation();

		$OK=true;

		$serviceEnt = null;

		// rewrite the fields data for the missing values if the operation is 'update'
		if ($operation=='update') {
			// if at least one location fields were changed
			if (!isset($fields['departureCityId']) and !isset($fields['departureCountryCode']) and !isset($fields['departureStationCode']) and !isset($fields['destinationCityId']) and !isset($fields['destinationCountryCode']) and !isset($fields['destinationStationCode'])) {
				return true;
			}

			$serviceEnt = Service::selectForUpdate($currentIdEntity);
			// rewrite the fields that were not set from the object
			if (!isset($fields['departureCityId'])) $fields['departureCityId']=$serviceEnt->departureCityId;
			if (!isset($fields['departureCountryCode']))$fields['departureCountryCode']=$serviceEnt->departureCountryCode;
			if (!isset($fields['departureStationCode']))$fields['departureStationCode']=$serviceEnt->departureStationCode;
			if (!isset($fields['destinationCityId']))$fields['destinationCityId']=$serviceEnt->destinationCityId;
			if (!isset($fields['destinationCountryCode']))$fields['destinationCountryCode']=$serviceEnt->destinationCountryCode;
			if (!isset($fields['destinationStationCode']))$fields['destinationStationCode']=$serviceEnt->destinationStationCode;
		}

		// determine the service code
		if (array_key_exists('serviceCode', $fields)) {
			$serviceCode = $fields['serviceCode'];
		} elseif ($operation=='update') {
			$serviceCode = $serviceEnt->serviceCode;
		} else {
			$serviceCode = '';
		}

		// CHECK DEPARTURE CITY/COUNTRY DETAILS ---------------------------------------------------
		if ($fields['departureCityId'] ) {
			$cityDet=\Entity\City::select($fields['departureCityId']);
			// check city id
			if (!$cityDet->recordExists()) {
				$currMessages->addWarningCode('cityInvalid', 'departure');
				$OK=false;
			} elseif ($cityDet->countryCode!=$fields['departureCountryCode']) {
				$currMessages->addWarningCode('cityInvalid', 'departure');
				$OK=false;
			}
		} elseif ($fields['departureCountryCode']) {
			$cntrDet=\Entity\Country::select($fields['departureCountryCode']);
			if (!$cntrDet->recordExists()) {
				$currMessages->addWarningCode('countryInvalid', 'departure');
				$OK=false;
			}
		}

		// CHECK DEPARTURE AIRPORT ----------------------------------------------------------------
		if ($fields['departureStationCode']) {
			$airpDet=\Entity\Station::select($fields['departureStationCode']);
			if ($airpDet->countryCode and $fields['departureCountryCode'] and $airpDet->countryCode!=$fields['departureCountryCode']) {
				$currMessages->addWarningCode('deptAirportInvalid', 'departure');
				$OK=false;
			}
		}

		// CHECK DESTINATION CITY/COUNTRY DETAILS -------------------------------------------------
		if ($fields['destinationCityId'] ) {
			$cityDet=\Entity\City::select($fields['destinationCityId']);
			// check city id
			if (!$cityDet->recordExists()) {
				$currMessages->addWarningCode('cityInvalid', 'destination');
				$OK=false;
			} elseif ($cityDet->countryCode!=$fields['destinationCountryCode']) {
				$currMessages->addWarningCode('cityInvalid', 'destination');
				$OK=false;
			}
		} elseif ($fields['destinationCountryCode']) {
			$cntrDet=\Entity\Country::select($fields['destinationCountryCode']);
			if (!$cntrDet->recordExists()) {
				$currMessages->addWarningCode('countryInvalid', 'destination');
				$OK=false;
			}
		}

		// CHECK DESTINATION AIRPORT --------------------------------------------------------------
		if ($fields['destinationStationCode']) {
			$airpDet=\Entity\Station::select($fields['destinationStationCode']);
			if ($airpDet->countryCode and $fields['destinationCountryCode'] and $airpDet->countryCode!=$fields['destinationCountryCode']) {
				$currMessages->addWarningCode('destAirportInvalid', 'destination');
				$OK=false;
			}
		}

		// CHECK IF THE FIELDS ARE MANDATORY ------------------------------------------------------
		if ($serviceCode) {
			$servCfg = \App\Config\Services_Fields::getInstance();
			// departure country
			if ($servCfg->getServiceFieldType($serviceCode, 'departureCountry')=='mandatory' and !$fields['departureCountryCode']) {
				$currMessages->addWarningCode('countryNotSet', 'departure');
			}
			// departure city
			if ($servCfg->getServiceFieldType($serviceCode, 'departureCity')=='mandatory' and !$fields['departureCityId']) {
				$currMessages->addWarningCode('cityNotSet', 'departure');
			}
			// departure station
			if ($servCfg->getServiceFieldType($serviceCode, 'departureStation')=='mandatory' and !$fields['departureStationCode']) {
				$currMessages->addWarningCode('stationNotSet', 'departure');
			}

			// destination country
			if ($servCfg->getServiceFieldType($serviceCode, 'destinationCountry')=='mandatory' and !$fields['destinationCountryCode']) {
				$currMessages->addWarningCode('countryNotSet', 'destination');
			}
			// destination city
			if ($servCfg->getServiceFieldType($serviceCode, 'destinationCity')=='mandatory' and !$fields['destinationCityId']) {
				$currMessages->addWarningCode('cityNotSet', 'destination');
			}
			// destination station
			if ($servCfg->getServiceFieldType($serviceCode, 'destinationStation')=='mandatory' and !$fields['destinationStationCode']) {
				$currMessages->addWarningCode('stationNotSet', 'destination');
			}
		}

		return $OK;

	}


	/**
	 * Validates the service period fields for service insert/update
	 */
	protected function check_insertUpdate_servicePeriod() {

		// configs
		$cfg=$this->entity->getCFG();

		// get current fields details
		$fields=$this->entity->getFields();

		// current collected messages
		$currMessages=$this->entity->getMessages();

		// current entity id
		$currentIdEntity=$this->entity->getId();

		// current operation
		$operation=$this->entity->getOperation();

		// rewrite the fields data for the missing values if the operation is 'update'
		if ($operation=='update') {
			// if at least one date/time fields were changed
			if (!isset($fields['startDatetime']) and !isset($fields['endDatetime'])) {
				return true;
			}

			$serviceEnt = Service::selectForUpdate($currentIdEntity);
			// rewrite the fields that were not set from the object
			if (!isset($fields['startDatetime'])) $fields['startDatetime']=$serviceEnt->startDatetime;
			if (!isset($fields['endDatetime'])) $fields['endDatetime']=$serviceEnt->endDatetime;
			$fields['serviceCode']=$serviceEnt->serviceCode;
		}

		// CHECK START / END DATES ----------------------------------------------------------------
		if (!$fields['startDatetime']) {
			$currMessages->addWarningCode('startDateNotSet', 'dateInterval');
		} elseif (!\Engine\Validator::set($fields['startDatetime'], ['type'=>'datetime'])->check()) {
			$currMessages->addWarningCode('startDateInvalid', 'dateInterval');
		}
		if ($fields['endDatetime'] and !\Engine\Validator::set($fields['endDatetime'], ['type'=>'datetime'])->check()) {
			$currMessages->addWarningCode('endDateInvalid', 'dateInterval');
		} elseif (!$fields['endDatetime'] and $fields['serviceCode'] and \App\Config\Services_Fields::getInstance()->getServiceFieldType($fields['serviceCode'], 'endDatetime')=='mandatory') {
			$currMessages->addWarningCode('endDateNotSet', 'dateInterval');
		}

		// check start after end
		if ($fields['startDatetime'] and $fields['endDatetime']) {
			// if ($fields['startDatetime']>$fields['endDatetime']) {
			// due to different timezone, the start date is compared with the end date + 2 hours
			$endDatetime = \Engine\DateTime::createFromIsoDateOrDatetime($fields['endDatetime'])->modify('+2 hours')->formatDatetimeIso();
			if ($fields['startDatetime']>$endDatetime) {
				$currMessages->addWarningCode('endDateBeforeStartDate', 'dateInterval');
			}
		}
		// check minStartDate / maxStartDate / maxEndDate
		if ($fields['startDatetime'] and $fields['startDatetime']<$cfg['period']['validation']['minValue']) {
			$currMessages->addWarningCode('periodBeforeLimit', 'dateInterval', \Engine\DateTime::isoToStd($cfg['period']['validation']['minValue']));
		}
		if ( ($fields['startDatetime'] and $fields['startDatetime']>$cfg['period']['validation']['maxValue']) or ($fields['endDatetime'] and $fields['endDatetime']>$cfg['period']['validation']['maxValue']) ) {
			$currMessages->addWarningCode('periodAfterLimit', 'dateInterval', \Engine\DateTime::isoToStd($cfg['period']['validation']['maxValue']));
		}

	}

}