<?php
namespace App\Dashboard\Widget;

abstract class ClientLastServices extends \Engine\Dashboard\Widgets\WidgetAbstract
{
	/**
	 * The default cache lifetime.
	 * @var Int
	 */
	protected $cacheLifetime=1800;

	/**
	 * The default options associated when the widget is added.
	 * @var array
	*/
	protected function getDefaultOptions()
	{
		$return = [
			'orderStartDate' => '1month',
			'servPeriod' =>		'active',
			'servCode' => 		'',
			'responsibleUser' => '',
			'columnsList' => 	['idService', 'orderDetails', 'serviceCode', 'servicePeriod', 'serviceAddDate', 'serviceStatus',
					'offerTotalValue', 'invoicedValue',
			],
			'selectLimit' => 	5,
		];
		return $return;
	}

	/**
	 * (non-PHPdoc)
	 * @see \Engine\Dashboard\Widgets\WidgetAbstract::getWidgetCacheLifeDurations()
	 */
	protected function getWidgetCacheLifeDurations()
	{
		#return array(7200, 10800, 21600, 28800, 43200, 86400);
		return parent::getWidgetCacheLifeDurations();
	}


	/**
	 * Generate the options form
	 */
	protected function populateLocalOptionsForm(\Engine\Form\Container\GeneralAbstract $form)
	{
		$calledClass = get_called_class();
		$className = stripClassNamespace($calledClass);

		// load lang
		$loaderLang = \App\Loader_Lang::getInstance();
		$loaderLang->loadAppFile("_customLoad/dashboard/widgets/_general.lang.php");
		$loaderLang->loadAppFile("_customLoad/dashboard/widgets/{$className}.lang.php");
		$loaderLang->loadAppFile("_customLoad/dashboard/widgets/ClientLastServices.lang.php");
		$_LANG = $loaderLang->getAll();

		$fieldset = \Engine\Form\Container\Fieldset::create($_LANG['dashboard']['widgets']['_GENERAL_']['formFields']['specificFieldsLegend']);

		/*-------------------------------------------*/
		// service code
		$field = new \App\Form\Input\Select_Service($_LANG['dashboard']['widgetsList']['App\Dashboard\Widget\ClientLastServices']['options']['servCode'], 'servCode', $this->getOption('servCode'));
		$fieldset->addElement($field);

		// responsibleUser
		$field = new \App\Form\Input\Autocomplete_User($_LANG['dashboard']['widgetsList']['App\Dashboard\Widget\ClientLastServices']['options']['responsibleUser'], 'responsibleUser', $this->getOption('responsibleUser'));
		$fieldset->addElement($field);

		// orderStartDate
		$field = new \Engine\Form\Input\Select($_LANG['dashboard']['widgetsList']['App\Dashboard\Widget\ClientLastServices']['options']['orderStartDate'], 'orderStartDate', $this->getOption('orderStartDate'));
		$periods = ['', '1day', '5days', '1week', '2weeks', '3weeks', '1month', '2months', '3months', '6months', '9months', '1year', '2years'];
		$vals = [];
		foreach ($periods as $per) {
			$vals[$per] = $_LANG['dashboard']['widgets']['_GENERAL_']['timePeriods'][$per];
		}
		$field->setPossibleValues($vals);
		$fieldset->addElement($field);

		// service period
		$field = new \Engine\Form\Input\Select($_LANG['dashboard']['widgetsList']['App\Dashboard\Widget\ClientLastServices']['options']['servPeriod'], 'servPeriod', $this->getOption('servPeriod'));
		$periods = ['passed', 'active', 'future'];
		$values = [];
		foreach ($periods as $period) {
			$values[$period] = $_LANG['dashboard']['widgetsList']['App\Dashboard\Widget\ClientLastServices']['options']['period'][$period];
		}
		$field->setPossibleValues($values);
		$fieldset->addElement($field);

		// listing columns
		$field = new \Engine\Form\Input\Checkboxes($_LANG['dashboard']['widgetsList']['App\Dashboard\Widget\ClientLastServices']['options']['columnsList'], 'columnsList', $this->getOption('columnsList'));
		$cols = ['idService', 'orderDetails', 'serviceCode', 'servicePeriod', 'serviceAddDate', 'serviceStatus',
					'offerTotalValue', 'invoicedValue'];
		$vals = [];

		foreach ($cols as $col) {
			$vals[$col] = $_LANG['dashboard']['widgetsList']['App\Dashboard\Widget\ClientLastServices']['options']['columnsList_options'][$col];
		}

		$field->setPossibleValues($vals);
		$fieldset->addElement($field);

		// listing limit
		$field = new \Engine\Form\Input\Select($_LANG['dashboard']['widgetsList']['App\Dashboard\Widget\ClientLastServices']['options']['selectLimit'], 'selectLimit', $this->getOption('selectLimit'));
		$vals = [
			'5' => 		$_LANG['dashboard']['widgets']['_GENERAL_']['selectLimits']['5'],
			'10' => 	$_LANG['dashboard']['widgets']['_GENERAL_']['selectLimits']['10'],
		];
		$field->setPossibleValues($vals);
		$fieldset->addElement($field);

		$form->addContainer($fieldset);
		return $form;
	}


	/**
	 * Extract data from the form return($R) and sets internal configs($this->options) accordingly
	 */
	protected function extractFormOptions($formData)
	{
		$options = [];

		$options['orderStartDate'] = 	$formData['orderStartDate'];
		$options['servPeriod'] =		$formData['servPeriod'];
		$options['responsibleUser'] = 	$formData['responsibleUser']['id'];

		if ($formData['columnsList'] && is_array($formData['columnsList'])) {
			$options['columnsList'] = array_keys($formData['columnsList']);
		}
		else {
			$options['columnsList'] = [];
		}

		$options['servCode'] = 			$formData['servCode'];
		$options['selectLimit'] = 		$formData['selectLimit'];

		$this->setOptions($options);
	}


	/**
	 * Sets the collected processed data.
	 * @return Array
	 */
	protected function getData()
	{
		// if no columns selected - do not go on
		if (!$this->getOption('columnsList') or !is_array($this->getOption('columnsList'))) {
			return false;
		}

		// get columns in an associative array
		$colsAssoc = array_combine($this->getOption('columnsList'), array_fill(0, count($this->getOption('columnsList')), true));

		$calledClass = get_called_class();
		$className = stripClassNamespace($calledClass);
		$loaderLang = \App\Loader_Lang::getInstance();
		$loaderLang->loadAppFile("_customLoad/dashboard/widgets/_general.lang.php");
		$loaderLang->loadAppFile("_customLoad/dashboard/widgets/{$className}.lang.php");
		$loaderLang->loadAppFile("_customLoad/dashboard/widgets/ClientLastServices.lang.php");
		$_LANG = $loaderLang->getAll();

		$output = [];

		// validate customer
		if ($this->getOption_rec('idCustomer')) {
			$customerEntity = \Entity\Customer::select($this->getOption_rec('idCustomer'));

			if (!$customerEntity->recordExists()) {
				$output['errorMessage'] = $_LANG['dashboard']['widgetsList'][$calledClass]['messages']['invalidIdCustomer'];
			}
			elseif ($customerEntity->deleted) {
				$output['errorMessage'] = $_LANG['dashboard']['widgetsList'][$calledClass]['messages']['customerDeleted'];
			}
		}

		// validate corporate
		if ($this->getOption_rec('idCorporate')) {
			$corporateEntity = \Entity\Corporate::select($this->getOption_rec('idCorporate'));

			if (!$corporateEntity->recordExists()) {
				$output['errorMessage'] = $_LANG['dashboard']['widgetsList'][$calledClass]['messages']['invalidIdCorporate'];
			}
			elseif ($corporateEntity->deleted) {
				$output['errorMessage'] = $_LANG['dashboard']['widgetsList'][$calledClass]['messages']['corporateDeleted'];
			}
		}

		if (!$output['errorMessage']) {

			// GET THE RESERVATIONS LIST //////////////////////////////////////////////////////////////
			$orderListObj = new \App\EntityList\OrderServices();

			// APPLY CERTAIN FILTERS ON THE RESERVATIONS ----------------------------------------------
			if ($this->getOption('responsibleUser')) {
				$orderListObj->setFilter('serv.idUser', '=', $this->getOption('responsibleUser'));
			}

			// apply reservation date filter
			if ($this->getOption('orderStartDate')) {
				$orderDate = \Engine\DateTime::create()->modify("-{$this->getOption('orderStartDate')}")->formatDateIso();
			}
			else {
				$orderDate = TODAY_ISO;
			}
			$orderListObj->setFilter('res.date', '>=', $orderDate);

			// apply serviceCode filter
			if ($this->getOption('servCode')) {
				$orderListObj->setFilter('serv.serviceCode', '=', $this->getOption('servCode'));
			}

			// check owner corporate
			if ($this->getOption_rec('idCorporate')) {
				$orderListObj->setFilter('res.idCorporates', 'LIKE', "%|{$this->getOption_rec('idCorporate')}|%");
			}
			elseif ($this->getOption_rec('idCustomer')) {
				$orderListObj->setFilter('serv.idCustomers', 'LIKE', "%|".$this->getOption_rec('idCustomer')."|%");
			}
			else {
				throw new \Exception("No option specified");
			}

			if ($this->getOption('servPeriod') == 'passed') {
				$orderListObj->setFilter('serv.chosenOfferId', '!=', 0);
				$orderListObj->setCustomFilter('
						(off.endDatetime != ? AND off.endDatetime < ?) OR (off.endDatetime = ? AND off.startDatetime < ?)',
						['0000-00-00 00:00:00', DATETIME, '0000-00-00 00:00:00', DATETIME]
				);
			}
			elseif ($this->getOption('servPeriod') == 'active') {
				$orderListObj->setFilter('serv.chosenOfferId', '!=', 0);

				$orderListObj->setCustomFilter('
						DATE(off.startDatetime) <= ? AND ((off.endDatetime != ? AND off.endDatetime >= ?) OR (off.endDatetime = ? AND DATE(off.startDatetime) >= ?))
					',
						[TODAY_ISO, '0000-00-00 00:00:00', DATETIME, '0000-00-00 00:00:00', TODAY_ISO]
				);
			}
			elseif ($this->getOption('servPeriod') == 'future') {
				$orderListObj->setCustomFilter('
						(off.startDatetime IS NOT NULL AND off.startDatetime > ?) OR
						(off.startDatetime IS NULL AND serv.startDate != ? AND serv.startDate > ?)
					',
					[DATETIME, '0000-00-00', TODAY_ISO]);
			}

			// ASSOCIATE COLUMNS FOR THIS LISTING -----------------------------------------------------
			$orderListObj->setColumns([
				'serv.id' => 				'idService',
				'res.id' =>					'idOrder',
				'res.convertedId',
				'res.reservationNumber' => 	'orderNumber',
				'res.date' =>				'orderDate',
				'serv.service',
				'serv.startDate',
				'serv.endDate',
				'serv.addTime',
				'serv.statusOp',
				'serv.statusFin',
				'serv.offerTotal',
				'serv.offerTotalCurrency',
				'off.startDatetime',
				'off.endDatetime',
			]);

			// OTHER CLAUSES --------------------------------------------------------------------------
			$orderListObj->setOrderBy('addTime', 'DESC');
			$orderListObj->setLimit($this->getOption('selectLimit'));

			// apply user restriction
			$orderListObj->applyUserRestriction(true);

			// get the reservations list
			$ordersList = $orderListObj->exportRecords();

			// ADD NEW INFO TO THE LIST OF ORDERS
			foreach ($ordersList as $orderKey => $orderDetails) {
				$serviceEntity = \Entity\Service::select($orderDetails['idService']);

				foreach ($serviceEntity->invoiceRowsList as $invRow) {
					// populate invoice total value
					$orderDetails['invoiceTotalValue'][$invRow['currency']] += $invRow['pricePrintValue'] + $invRow['vatPrintValue'];
				}

				// rewrite the original row
				$ordersList[$orderKey] = $orderDetails;
			}

			// ASSOCIATE THE DATA FOR THE LISTING /////////////////////////////////////////////////////
			$output['ordersList'] = $ordersList;
		}

		// ASSOCIATE OTHER INFO ///////////////////////////////////////////////////////////////////
		$output['columnsListAssoc'] = $colsAssoc;

		return $output;
	}

	/**
	 * (non-PHPdoc)
	 * @see \Engine\Dashboard\Widgets\WidgetAbstract::loadLangs()
	 */
	public function loadLangs()
	{
		$thisClass = stripClassNamespace(get_called_class());

		// load langs
		$loaderLang = \App\Loader_Lang::getInstance();
		$loaderLang->loadAppFile("_customLoad/dashboard/widgets/_general.lang.php");
		$loaderLang->loadAppFile("_customLoad/dashboard/widgets/".$thisClass.".lang.php");
		$loaderLang->loadAppFile("_customLoad/dashboard/widgets/ClientLastServices.lang.php");
	}
}