<?php

class ReportController extends Controller
{
  
  public function actionCreate()
  {
    if (! isset ( $_REQUEST ['workPeriodID'] ))
      throw new CHttpException ( 400, Yii::app ( 't', 'workPeriodID is required.' ) );
    
    $workPeriodID = ( int ) $_REQUEST ['workPeriodID'];
    
    $this->showReport ( $workPeriodID, false );
  }

  public function actionPreview()
  {
    if (! isset ( $_REQUEST ['workPeriodID'] ))
      throw new CHttpException ( 400, Yii::app ( 't', 'workPeriodID is required.' ) );
    
    $workPeriodID = ( int ) $_REQUEST ['workPeriodID'];
    
    $this->showReport ( $workPeriodID, true );
  }

  /**
   *
   * @param integer $workPeriodID          
   * @param boolean $preview          
   */
  protected function showReport($workPeriodID, $preview)
  {
    $period = $this->loadWorkPeriod ( $workPeriodID );
    
    $report = new Report ( $period, false ); // approved and invalid
    
    if (! $preview)
    {
      $events = EventTagger::tag ( $report->repository->all );
    }
    else
    {
      $events = array_convert ( $report->repository->all, function (Event $e)
      {
        $e->ext_code = $e->validation_result == 'approved' ? 'DEMO' : ExtCode::NULL_EXT_CODE;
        return $e;
      } );
    }
    
//    if ($period->report_generation_date == NULL)
    {
      $converterEventToId = function (Event $e)
      {
        return $e->ID;
      };
      
      $reportApproved = new Report ( $period, true ); // approved only
      $eventsApproved = $reportApproved->repository->all;
      
	  if (! $preview)
      {
      	$period->report_generation_date = new DateTime ();
        $period->events_count = count ( $eventsApproved );
        $period->events_ids = implode ( ",", array_convert ( $eventsApproved, $converterEventToId ) );
        $period->activateRegistration();
        $period->save ();
      }
    }
    
    $this->registerAllExportCounters();

    $eventsByGateGroup = GroupEventsByGateGroup::run ( $events );
    
    // this will hold data we will pass to views for rendering
    $reportData = array(
    	'user' => $period->user,
    	'period' => $period,
    	'generationTime' => DateHelper::formatDateTime($period->report_generation_date)
    );
    
    $reportPrinter = ReportPrinterFactory::getReportPrinter();
    foreach ($eventsByGateGroup as $aGroup) {
    	
    	$gateGroup = $aGroup['gateGroup'];
    	$events = $aGroup['events'];
    	$events = array_sort($events, function($a,$b){ $a = new DateTimeEx($a->StartTime); return $a->compare(new DateTimeEx($b->StartTime)); });
    	$totalEvents = count($events);
    	$validEvents = array_filter($events, function($e){return $e->ext_code != ExtCode::NULL_EXT_CODE;});
    	$firstEvent = array_first($validEvents);
    	$lastEvent = array_last($validEvents);
    	$gates = $gateGroup->gates;
    	
    	// fill report data to render
    	$reportData['counterOK'] = 0;
    	$reportData['counterNO'] = 0;
    	foreach($events as $event) {
    		if ($event->ext_code != ExtCode::NULL_EXT_CODE) {
    			$reportData['counterOK']++;
    		}
    		else {
    			$reportData['counterNO']++;
    		}
    	}
    	$reportData['gateGroup'] = $aGroup['gateGroup'];
    	$reportData['events'] = $aGroup['events'];
    	$reportData['events'] = $events;
    	$reportData['totalEvents'] = count($events);
    	$reportData['validEvents'] = $validEvents;
    	$reportData['firstEvent'] = $firstEvent;
    	$reportData['lastEvent'] = $lastEvent;
    	$reportData['gates'] = $gateGroup->gates;
    	
    	// build a temporary ReportDocument to use,
    	// we will persist it later if necessary
    	$reportDocument = new ReportDocument();
    	$reportDocument->UserID = $period->id_user;
    	$reportDocument->PeriodID = $period->id;
    	$reportDocument->GroupID = $gateGroup->ID;
    	$reportDocument->CreationTime = $period->report_generation_date;
    	$reportDocument->MinExtcode = $firstEvent->ext_code;
    	$reportDocument->MaxExtcode = $lastEvent->ext_code;
    	
    	// get the report title
    	$title = $reportDocument->getTitle();
    	
    	// build the PDF report and store it in an
    	// array we will pass to the view
    	$pdfs[$reportData['gateGroup']->name] = $reportPrinter->printReport($title, $reportData);
    	if (!$preview) {
    		
    		// set the PDF content
    		$reportDocument->Document = end($pdfs);
    		
    		// persist document on DB
    		$reportDocument->save();
    		
    	}
    	
    }
    
    if (!$preview && !$period->closed) {
    	
    	// force user logout
    	Yii::app ()->user->logout();
    	
    	// redirect to login page
    	$this->redirect(array("session/login/"));
    	
    }
    else if (!$preview) {
    	
    	// redirect to report archive view
    	$this->redirect(array("reportArchive/index/"));
    	
    }
    else {
    	
    	// render report preview page
    	$this->render('sessionReportsPreviewViewer', array('pdfs' => $pdfs, 'workPeriod' => $period));
    	
    }
    
  }
  
  public function actionDoRegisterAllExportCounters()
  {
  	$this->registerAllExportCounters();
  }
  
  public function actionConfirm($workPeriodID)
  {
  	$checkExpDay = paramdeep ( 'security', 'export_expiry_date_check' );
  	
  	if(!isEmpty($checkExpDay) && $checkExpDay)
  	{
	  	$EventServerReg = EventServerRegistration::model()->byMe()->find();
	  	
	  	if(isEmpty($EventServerReg))
	  	{
	  		$this->renderPartial ( '_licenseConnectionFailed');
	  		return;
	  	}
	  	
	  	
	  	if(isEmpty($EventServerReg->export_expiry_date))
	  	{
	  		$this->renderPartial ( '_licenseExpired');
	  		return;
	  		
	  	}
	  	$nowDate = DateTimeEx::now();
	  	
	  	if($nowDate > $EventServerReg->export_expiry_date)
	  	{
	  		$this->renderPartial ( '_licenseExpired');
	  	}
  	}
  	
    // ensure work period really exists
    $workPeriod = $this->loadWorkPeriod ( $workPeriodID );
    
    $this->renderPartial ( '_confirm', array (
        'workPeriodID' => $workPeriod->id,
        'workPeriodClosed' => $workPeriod->closed 
    ) );
  }

  public function actionViewSummary($workPeriodID)
  {
    $period = $this->loadWorkPeriod ( $workPeriodID );
    $report = new Report ( $period );
    $this->renderPartial ( '/workPeriod/_summary', array (
        'workPeriodID' => $workPeriodID,
        'repository' => $report->repository 
    ) );
  }

  /**
   *
   * @param integer $id          
   * @throws CHttpException
   * @return WorkPeriod
   */
  public function loadWorkPeriod($id)
  {
    $period = WorkPeriod::model ()->findByPk ( $id );
    if ($period === null)
      throw new CHttpException ( 404, Yii::t ( 'app', 'The requested page does not exist.' ) );
    return $period;
  }
  
  public function registerAllExportCounters()
  {
  	$sendExp = paramdeep ( 'security', 'send_export_registration' );
  	if(isEmpty($sendExp) || $sendExp == false)
  		return true;
  	
  		$workPeriods = WorkPeriod::model()->to_register()->findAll();
  		foreach($workPeriods as $wp)
  		{
  			$report = new Report ( $wp, false ); // approved and invalid
  			
  			if($this->registerExportCounters($report->repository->all, $wp->user, $wp->report_generation_date, $wp->id))
  			{
 		        $wp->confirmRegistration();
		        $wp->save ();
  			}
  		}
  }
  
  public function registerExportCounters($events, $user, $ext_code_time, $id_work_period)
  {
  	set_time_limit(60);
  	
  	if(count($events) <= 0)
  		return  true;

  	$gates = Gate::model()->findAll();

  	foreach($gates as $gate)
  	{
  		$gateConters[$gate->Gate]['description'] = $gate->Descrizione;
  		$gateConters[$gate->Gate]['exported'] = 0;
  		$gateConters[$gate->Gate]['gate_sn'] = $gate->Gate;
  		$gateConters[$gate->Gate]['gate_type'] = $gate->GateType;
  		$gateConters[$gate->Gate]['gate_model'] = $gate->device_model;
  		$gateConters[$gate->Gate]['deleted'] = 0;
  		$gateConters[$gate->Gate]['plate_changed'] = 0;
  		$gateConters[$gate->Gate]['min_ext_code'] = 0;
  		$gateConters[$gate->Gate]['max_ext_code'] = 0;  		
  	}
  	
  	$gateConters[$event->Gate]['deleted'] = 0;
  	$gateConters[$event->Gate]['plate_changed'] = 0;
  	$gateConters[$event->Gate]['min_ext_code'] = 0;
  	$gateConters[$event->Gate]['max_ext_code'] = 0;
  	$gateConters[$event->Gate]['num_of_events'] = 0;

  	foreach($events as $event)
  	{
  		if ($event->ext_code != ExtCode::NULL_EXT_CODE)  
  		{
  			$gateConters[$event->Gate]['exported'] += 1;
  			
  			if($gateConters[$event->Gate]['min_ext_code'] === 0)
  			{
  				$gateConters[$event->Gate]['min_ext_code'] = $event->ext_code;
  				$gateConters[$event->Gate]['max_ext_code'] = $event->ext_code;
  			}
  			else 
  			{
  				$gateConters[$event->Gate]['min_ext_code'] = min($event->ext_code, $gateConters[$event->Gate]['min_ext_code'] );
  				$gateConters[$event->Gate]['max_ext_code'] = max($event->ext_code, $gateConters[$event->Gate]['max_ext_code'] );
  			}
  		}
  		
  		if ($event->ext_code == ExtCode::NULL_EXT_CODE)
  			$gateConters[$event->Gate]['deleted'] += 1;
  		
  		if (!isEmpty($event->ExtPlate) && $event->ExtPlate != $event->Plate)
  			$gateConters[$event->Gate]['plate_changed'] += 1;
  		
  		$gateConters[$event->Gate]['num_of_events'] += 1;
  	}
  	

  	
  	$eventReg = EventServerRegistration::model()->byMe()->find();
  	
  	if(isEmpty($eventReg))
  		return false;
  	
  		
  	$resSave = true;
  	
  	foreach($gateConters as $gateC)
  	{
  		if($gateC['num_of_events'] > 0)
  		{
  			$expExisting = ExportedEvents::model()->byServer($eventReg->id)->byGate($gateC['gate_sn'])->byWorkPeriod($id_work_period)->count();
             
  			if($expExisting > 0)
            {
            	$expEv = ExportedEvents::model()->byServer($eventReg->id)->byGate($gateC['gate_sn'])->byWorkPeriod($id_work_period)->find();
            	
            	$expEv->export_time = $ext_code_time;
            	$expEv->exported_events =$gateC['exported'] ;
            	$expEv->deleted_events = $gateC['deleted'];
            	$expEv->plate_changes = $gateC['plate_changed'];
            	$expEv->min_ext_code = $gateC['min_ext_code'];
            	$expEv->max_ext_code = $gateC['max_ext_code'];
            	$expEv->id_event_server = $eventReg->id;
            	$expEv->user_name = $user->first_name ." " . $user->last_name;
            	$expEv->gate_sn = $gateC['gate_sn'];
            	$expEv->gate_type = $gateC['gate_type'];
            	$expEv->gate_model = $gateC['gate_model'];
            	$expEv->gate_description = $gateC['description'];
            	$expEv->validated_events = $gateC['num_of_events'] ;
            	$expEv->id_work_period = $id_work_period;
            	
            	if(!$expEv->save())
            		$resSave = false;
            }
            else
            {
  			
		  		$expEv = new ExportedEvents;
		
		  		$expEv->export_time = $ext_code_time;
		  		$expEv->exported_events =$gateC['exported'] ;
		  		$expEv->deleted_events = $gateC['deleted'];
		  		$expEv->plate_changes = $gateC['plate_changed'];
		  		$expEv->min_ext_code = $gateC['min_ext_code'];
		  		$expEv->max_ext_code = $gateC['max_ext_code'];
		  		$expEv->id_event_server = $eventReg->id;
		  		$expEv->user_name = $user->first_name ." " . $user->last_name;
		  		$expEv->gate_sn = $gateC['gate_sn'];
		  		$expEv->gate_type = $gateC['gate_type'];
		  		$expEv->gate_model = $gateC['gate_model'];
		  		$expEv->gate_description = $gateC['description'];
		  		$expEv->validated_events = $gateC['num_of_events'] ;
		  		$expEv->id_work_period = $id_work_period;
		  		
		  		if(!$expEv->save())
		  			$resSave = false;
            }
  		}
  	}
  	
  	return $resSave;
  	
  }
}
