<?php

class EventsStatistics extends Event {
	
	public $count;
	
	public $referenceDate;
	
	public $rejectionReason;
	
	public $gateDescription;
	
	public static function model($className=__CLASS__) {
		return parent::model($className);
	}
	
	public function getEventsCountByOccurenceDateTime(
		$startDateTime,
		$endDateTime,
		$additionalFilters = array())
	{
		
		$model = EventsStatistics::model();
		
		$model->setDbCriteria(new CDbCriteria());
		
		$this->applyFilters($model, $additionalFilters);
		
		$model->setReferenceDateField('StartTime');
		
		$model->startDateAfter($startDateTime);
		
		$model->startDateBefore($endDateTime);
		
		$dataProvider = $model->getData();
		
		$statistic = $this->packData(
			$startDateTime, $endDateTime, $dataProvider
		);
		
		return $statistic;
	}
	
	public function getEventsCountByValidationDateTime(
			$validationStartDateTime,
			$validationEndDateTime,
			$additionalFilters = array())
	{
		$model = EventsStatistics::model();
		
		$model->setDbCriteria(new CDbCriteria());
		
		$this->applyFilters($model, $additionalFilters);
		
		$model->setReferenceDateField('ValidationTime');
		
		$model->validatedAfter($validationStartDateTime);
		
		$model->validatedBefore($validationEndDateTime);
		
		$dataProvider = $model->getData();
		
		$statistic = $this->packData(
			$validationStartDateTime, $validationEndDateTime, $dataProvider
		);
		
		return $statistic;
	}
	
	public function getEventsCountByGate(
			$additionalFilters = array())
	{
		$statistic = array();
		
		$gateModel = Gate::model();
		
		if (isset($additionalFilters['gates'])) {
			$gates = $gateModel->findAllByPk($additionalFilters['gates']);
		}
		else {
			$gates = $gateModel->findAll();
		}
		
		foreach ($gates as $gate) {
			$statistic[$gate->Descrizione] = 0;
		}
		
		$model = EventsStatistics::model();
		
		$model->setDbCriteria(new CDbCriteria());
		
		$this->applyFilters($model, $additionalFilters);
		
		$model->with('gate');
		
		$criteria = $model->getDbCriteria();
		
		$criteria->mergeWith(
			array(
				'select' => array(
					"COUNT(*) AS count",
					"gate.Descrizione AS gateDescription"
				),
				'group' => 'gateDescription'
			)
		);
		
		$dataProvider = $model->getData();
		foreach ($dataProvider->getData() as $eventsCountByGate) {
			$statistic[$eventsCountByGate->gateDescription] = $eventsCountByGate->count;
		}
		
		return $statistic;
	}
	
	public function getValidationDecisionsByValidationDateTime(
			$validationStartDateTime,
			$validationEndDateTime,
			$additionalFilters = array())
	{
		$statistic = array();
		
		//
		// get approved violations count first
		//
		
		$model = EventsStatistics::model();
		
		$model->setDbCriteria(new CDbCriteria());
		
		$this->applyFilters($model, $additionalFilters);
		
		$model->validatedAfter($validationStartDateTime);
		
		$model->validatedBefore($validationEndDateTime);
		
		$approvedViolations = $model->with(
			'eventBehaviors:approved',
			'eventBehaviors.gateBehavior:toValidate'
		)->findAll(
			new CDbCriteria(
				array('condition' => 't.Gate = GateBehavior.id_gate')
			)
		);
		
		$approvedViolationsCount = count($approvedViolations);
		
		$statistic[t('Approved Violations')] = $approvedViolationsCount;
		
		//
		// then get invalid violations count with rejecting reason
		//
		
		// prepare an array with all rejection reasons
		$eventBehaviorModel = EventBehavior::model();
		
		$rejectionReasons = $eventBehaviorModel->findAll(
			array(
				'select' => 'comment',
				'distinct' => true
			)
		);
		
		foreach ($rejectionReasons as $rejectionReason) {
			$statistic[$rejectionReason->comment] = 0;
		}
		
		// fill the array with data
		$model->setDbCriteria(new CDbCriteria());
		
		$this->applyFilters($model, $additionalFilters);
				
		$model->validatedAfter($validationStartDateTime);
		
		$model->validatedBefore($validationEndDateTime);
		
		$model->with('eventBehaviors:invalid', 'eventBehaviors.gateBehavior:toValidate');
		
		$dbCriteria = $model::getDbCriteria();
		
		$dbCriteria->mergeWith(
			array(
				'select' => array(
					'eventBehaviors.comment as rejectionReason',
					'COUNT(*) AS count'
				),
				'group' => 'rejectionReason',
				'condition' => 't.Gate = GateBehavior.id_gate'
			)
		);
		
		$dataProvider = new CActiveDataProvider(
			'EventsStatistics',
			array(
				'pagination' => false
			)
		);
		$dataProvider->criteria = $dbCriteria;
		
		foreach ($dataProvider->getData() as $data) {
			$statistic[$data->rejectionReason] = $data->count;
		}
		
		return $statistic;
	}
	
	public function getUsersValidationDecisionsByValidationDateTime(
		$validationStartDateTime,
		$validationEndDateTime,
		$additionalFilters = array())
	{
		$statistic = array();
		
		$userModel = User::model();
		
		$users = $userModel->findAll();
		
		foreach ($users as $user) {
			
			$data = $this->getValidationDecisionsByValidationDateTime(
				$validationStartDateTime,
				$validationEndDateTime,
				array_merge(
					array('validatedByUser' => $user),
					$additionalFilters
				)
			);
			
			$statistic[] = array (
				'user' => array(
					'name' => $user->last_name . " " . $user->first_name,
					'id' => $user->id
				),
				'data' => $data
			); 
			
		}
		
		return $statistic;
	}
	
	public function getViolationsCountByOccurenceDateTime(
			$startDateTime,
			$endDateTime,
			$additionalFilters = array())
	{
		
		$model = EventsStatistics::model();
		
		$model->setDbCriteria(new CDbCriteria());
		
		$this->applyFilters($model, $additionalFilters);
		
		$model->setReferenceDateField('StartTime');
		
		$model->startDateAfter($startDateTime);
		
		$model->startDateBefore($endDateTime);
		
		$model->with('eventBehaviors.gateBehavior:toValidate');
		
		$criteria = $model->getDbCriteria();
		
		$criteria->mergeWith(
			array(
				'condition' => 't.Gate = GateBehavior.id_gate'
			)
		);
		
		$dataProvider = $model->getData();
		
		$statistic = $this->packData(
			$startDateTime, $endDateTime, $dataProvider
		);
		
		return $statistic;
	}
	
	public function getViolationsCountByValidationDateTime(
			$validationStartDateTime,
			$validationEndDateTime,
			$additionalFilters = array())
	{
		
		$model = EventsStatistics::model();
		
		$model->setDbCriteria(new CDbCriteria());
		
		$this->applyFilters($model, $additionalFilters);
		
		$model->setReferenceDateField('ValidationTime');
		
		$model->validatedAfter($validationStartDateTime);
		
		$model->validatedBefore($validationEndDateTime);
		
		$model->with('eventBehaviors.gateBehavior:toValidate');
		
		$criteria = $model->getDbCriteria();
		
		$criteria->mergeWith(
			array(
				'condition' => 't.Gate = GateBehavior.id_gate'
			)
		);
		
		$dataProvider = $model->getData();
		
		$statistic = $this->packData(
			$validationStartDateTime, $validationEndDateTime, $dataProvider
		);
		
		return $statistic;
	}
	
	public function getUsersViolationsCountByValidationDateTime(
			$validationStartDateTime,
			$validationEndDateTime,
			$additionalFilters = array())
	{
		
		$statistic = array();
		
		$userModel = User::model();
		
		$users = $userModel->findAll();
		
		foreach ($users as $user) {
			
			$data = $this->getViolationsCountByValidationDateTime(
				$validationStartDateTime,
				$validationEndDateTime,
				array_merge(
					array('validatedByUser' => $user),
					$additionalFilters
				)
			);
			
			$index = $user->last_name . " " . $user->first_name;
			
			$statistic[$index] = array_sum($data);
			
		}
		
		return $statistic;
		
	}
	
	public function getViolationsCountByGate(
		$additionalFilters = array())
	{
		$statistic = array();
		
		$gateModel = Gate::model();
		
		if (isset($additionalFilters['gates'])) {
			$gates = $gateModel->findAllByPk($additionalFilters['gates']);
		}
		else {
			$gates = $gateModel->findAll();
		}
		
		foreach ($gates as $gate) {
			$statistic[$gate->Descrizione] = 0;
		}
		
		$model = EventsStatistics::model();
		
		$model->setDbCriteria(new CDbCriteria());
		
		$this->applyFilters($model, $additionalFilters);
		
		$model->with('gate', 'eventBehaviors.gateBehavior:toValidate');
		
		$criteria = $model->getDbCriteria();
		
		$criteria->mergeWith(
			array(
				'condition' => 't.Gate = GateBehavior.id_gate'
			)
		);
		
		$criteria->mergeWith(
			array(
				'select' => array(
					"COUNT(*) AS count",
					"gate.Descrizione AS gateDescription"
				),
				'group' => 'gateDescription'
			)
		);
		
		$dataProvider = $model->getData();
		foreach ($dataProvider->getData() as $eventsCountByGate) {
			$statistic[$eventsCountByGate->gateDescription] = $eventsCountByGate->count;
		}
		
		return $statistic;
	}
	
	public function getViolationsManagementByGateStatisticsCSV(
		$additionalFilters = array())
	{
		$violationsManagementStatisticsByGates = array();
		
		$violationsCountByGate = $this->getViolationsCountByGate(
			$additionalFilters
		);
		
		$approvedViolationsCountByGate = $this->getViolationsCountByGate(
			array_merge($additionalFilters,
				array(
					'approvedViolations' => TRUE
				)
			)
		);
		
		$invalidViolationsCountByGate = $this->getViolationsCountByGate(
			array_merge($additionalFilters,
				array(
					'invalidViolations' => TRUE
				)
			)
		);
		
		$exportedEventsCountByGate = $this->getEventsCountByGate(
			array_merge($additionalFilters,
				array(
					'exportedEvents' => TRUE
				)
			)
		);
		
		foreach($violationsCountByGate as $gateDescription => $value) {
			
			$violationsManagementStatisticsByGates[] = array (
				''							=> $gateDescription,
				t('Approved Violations')	=> $approvedViolationsCountByGate[$gateDescription],
				t('Invalid Violations')		=> $invalidViolationsCountByGate[$gateDescription],
				t('Exported Violations')	=> $exportedEventsCountByGate[$gateDescription],
				t('Total Violations')		=> $violationsCountByGate[$gateDescription]
			);
			
		}
		
		return $violationsManagementStatisticsByGates;
		
	}
	
	public function getData()
	{
		$model = EventsStatistics::model();
		
		$dbCriteria = $model->getDbCriteria();
		
		$dataProvider = new CActiveDataProvider(
			'EventsStatistics',
			array(
				'pagination' => false
			)
		);
		$dataProvider->criteria = $dbCriteria;
		
		return $dataProvider;
	}
	
	protected function setReferenceDateField($referenceDateField)
	{
		$model = EventsStatistics::model();
		
		$dbCriteria = $model->getDbCriteria();
		
		$dbCriteria->mergeWith(
			array(
				'select' => array(
					"DATE($referenceDateField) AS referenceDate",
					"COUNT(*) AS count"
				),
				'order' => 'referenceDate ASC'
			)
		);
		
		SQLGroupByDays::group($dbCriteria, $referenceDateField);
	}
	
	protected function packData($startDateTime, $endDateTime, $dataProvider)
	{
		$interval = new DateInterval('P1D');
		
		$daterange = new DatePeriod($startDateTime, $interval , $endDateTime);
		
		$packedData = array();
		foreach ($daterange as $date) {
			$packedData[DateHelper::formatISO9075Date($date)] = 0;
		}
		foreach ($dataProvider->getData() as $countByDateTime) {
			$packedData[$countByDateTime->referenceDate] = $countByDateTime->count;
		}
		
		return $packedData;
	}
	
	protected function applyFilters($model, $filters)
	{
		if (!$filters) {
			return;
		}
		
		// filters on Event
		if (isset($filters['eventStartDateTime'])) {
			
			$model->startDateAfter($filters['eventStartDateTime']);
			
		}
		if (isset($filters['eventEndDateTime'])) {
			
			$model->startDateBefore($filters['eventEndDateTime']);
			
		}
		if (isset($filters['validationStartDateTime'])) {
			
			$model->validatedAfter($filters['validationStartDateTime']);
			
		}
		if (isset($filters['validationEndDateTime'])) {
			
			$model->validatedBefore($filters['validationEndDateTime']);
			
		}
		if (isset($filters['approvedEvents'])
			&& $filters['approvedEvents'] == TRUE) {
				
			$model->approved();
			
		}
		if (isset($filters['invalidEvents'])
			&& $filters['invalidEvents'] == TRUE) {
			
			$model->invalid();
			
		}
		if (isset($filters['pendingEvents'])
			&& $filters['pendingEvents'] == TRUE) {
				
			$model->pending();
			
		}
		if (isset($filters['exportedEvents'])
			&& $filters['exportedEvents'] == TRUE) {
				
			$model->exported();
			
		}
		if (isset($filters['validatedEvents'])
			&& $filters['validatedEvents'] == TRUE) {
			
			$model->validated();
			
		}
		if (isset($filters['validatedByUser'])) {
			
			$model->byValidator($filters['validatedByUser']);
			
		}
		if (isset($filters['gates'])) {
			
			$model->byGatesId($filters['gates']);
			
		}
		if (isset($filters['timeSlot'])
			&& isset($filters['timeSlot']['startTimeSlot'])
			&& isset($filters['timeSlot']['endTimeSlot'])
			) {
				
			$model->startTimeAfter($filters['timeSlot']['startTimeSlot']);
			$model->startTimeBefore($filters['timeSlot']['endTimeSlot']);
			
		}
		
		// filters on eventBehaviors relation of Event
		if (isset($filters['approvedViolations'])
			&& $filters['approvedViolations'] == TRUE) {
				
			$model->with('eventBehaviors:approved');
			
		}
		if (isset($filters['invalidViolations'])
			&& $filters['invalidViolations'] == TRUE) {
				
			$model->with('eventBehaviors:invalid');
			
		}
		if (isset($filters['pendingViolations'])
			&& $filters['pendingViolations'] == TRUE) {
				
			$model->with('eventBehaviors:pending');
			
		}
		if (isset($filters['toValidateViolations'])
			&& $filters['toValidateViolations'] == TRUE) {
				
			$model->with('eventBehaviors:toValidate');
			
		}
		if (isset($filters['validatedViolations'])
			&& $filters['validatedViolations'] == TRUE) {
				
			$model->with('eventBehaviors:validated');
			
		}
		
	}
	
}

?>