<?php

namespace Modules\TaskManagement\Tasks;

class Controller extends \App\Mvc\Controller\Window\PaginatedListing\PaginatedEntityListing
{

	/**
	 * Indicates if the entity execution should use or not a transaction.
	 * @var Boolean
	 */
	protected $useSqlTransaction=true;

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\PaginatedListing::initialize()
	 */
	protected function initialize()
	{
		parent::initialize();

		$this->actionsCfg['insert'] =         ['checkSection' => false,  'checkOption' => true,];
		$this->actionsCfg['update'] =         ['checkSection' => false,  'checkOption' => false,];
		$this->actionsCfg['delete'] =         ['checkSection' => false, 'checkOption' => false,];
		$this->actionsCfg['taskHistory'] =    ['checkSection' => true,  'checkOption' => false,];
		$this->actionsCfg['changeStatus'] =   ['checkSection' => true,  'checkOption' => false,];
		$this->actionsCfg['downloadFile'] =   ['checkSection' => true,  'checkOption' => false,];
	}

	/**
	 * The list of columns which support ordering.
	 * @var array
	 */
	protected $listOrderingColumns = ['description', 'priority', 'deadline', 'addTime'];

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\ListingAbstract::optionDefineParams()
	 */
	protected function optionDefineParams(\App\Mvc\View\Utils\RowOptions\Option\Option $option, $selection)
	{
		switch($option->getId()){
			case 'insert':
				if (!\App\UserAccess\CurrentUserAccessFast::getInstance()->hasAccessToOption("Modules/TaskManagement/Tasks-insert")) {
					$option->setDisabled();
				}
			break;

			case 'taskHistory':
			break;

			case 'changeStatus':
				foreach($selection as $idRow) {
					if (!$option->determineOperationAvailability(\Entity\Task::changeStatus($idRow))) {
						break;
					}
				}
			break;

			case 'update':
				foreach($selection as $idRow) {
					if (!$option->determineOperationAvailability(\Entity\Task::update($idRow))) {
						break;
					}
				}
			break;

			case 'delete':
				foreach($selection as $idRow) {
					if (!$option->determineOperationAvailability(\Entity\Task::delete($idRow))) {
						break;
					}
				}
			break;
		}

		return true;

	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\ListingAbstract::optionGetEntityName()
	 */
	protected function optionGetEntityName($id)
	{
		return \Entity\Task::select($id)->description;
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\ListingAbstract::alterListParams()
	 */
	protected function index_alterListParams($R)
	{
		$filters = [];

		// overwrite the responsible user and date interval
		if ($R['listing']['paramsSlot'] == 1 && $R['filters']['idPivot'] && $R['filters']['pivot']) {
			$filters['idResponsibleUser']['id'] = '';
			$filters['idDepartment']['id'] = '';
			$filters['idOffice']['id'] = '';
			$filters['taskDate'] = [
				'start' 	=> '',
				'end' 		=> ''
			];
		}

		if ($filters) {
			$this->listingParams->mergeFilters($filters);
			$this->listingParams->save();
		}
	}


	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\PaginatedListing::insert_getDefaultFormData()
	 */
	protected function insert_getDefaultFormData($R)
	{

		$formData = [];
		$filters = $this->loadListingParams($R)->getListingParams()->getFilters();

		if ($filters['pivot']) {
			$formData['pivot'] = $filters['pivot'];
 		}
 		else {
 			$formData['pivot'] = $R['task']['pivot'];
 		}

 		if ($filters['idPivot']) {
 			$formData['idPivot'] = $filters['idPivot'];
 		}
 		else {
 			$formData['idPivot'] = $R['task']['idPivot'];
 		}

		$formData['priority'] = 3;
		$formData['idOffice']['id'] = CURRENT_ID_OFFICE;
		$formData['idDepartment']['id'] = CURRENT_ID_DEPT;
		$formData['deadline'] = \Engine\DateTime::create("+1 days")->format(MYSQL_FORMAT." 15:00:00");

		return $formData;
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\PaginatedEntityListing::insert_createEntityObject()
	 */
	protected function insert_createEntityObject($formData)
	{
		$task = \Entity\Task::insert();

		$task->idCategory = $formData['idCategory'];
		$task->description = $formData['description'];
		$task->priority = $formData['priority'];
		$task->idOffice = $formData['idOffice']['id'];
		$task->idDepartment = $formData['idDepartment']['id'];
		$task->idAssignorUser = $formData['idAssignorUser']['id'];
		$task->idResponsibleUser = $formData['idResponsibleUser']['id'];
		$task->free = ($formData['free']?1:0);
		$task->pivot = $formData['pivot'];
		$task->idPivot = $formData['idPivot'];
		$task->comments = $formData['comments'];
		$task->idOperationType = $formData['idOperationType'];

		$deadline = \Engine\DateTime::createFromIsoDateOrDatetime($formData['deadline']);
		if ($deadline->isValid() && !$deadline->isEmpty()) {
			$task->deadline = \Engine\DateTime::createFromIsoDatetime($formData['deadline']);
		}

		// files
		$filesWithPath = [];
		foreach ($_FILES as $fileCode => $fileDetails) {
			$uploadedFile = new \App\Form\UploadedFiles\File($fileCode);
			if ($uploadedFile->hasValidFile()) {
				$filesWithPath[$uploadedFile->getName()] = $uploadedFile->getTempName();
			}
		}

		$task->filesWithPath = $filesWithPath;

		// events
		$task->noResponsibleNote = $formData['events']['noResponsibleNote'];
		$task->responsibleInstantNote  = $formData['events']['responsibleInstantNote'];
		$task->responsibleDeadlineNote = $formData['events']['responsibleDeadlineNote'];

		return $task;
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\PaginatedListing::update_getDefaultFormData()
	 */
	protected function update_getDefaultFormData($idEntity)
	{

		$task = \Entity\Task::select($idEntity);
		if (!$task->recordExists()) {
			return null;
		}

		$formData = [];

		$formData['idCategory'] = $task->idCategory;
		$formData['description'] = $task->description;
		$formData['priority'] = $task->priority;
		$formData['idOffice']['id'] = $task->idOffice;
		$formData['idDepartment']['id'] = $task->idDepartment;
		$formData['idAssignorUser']['id'] = $task->idAssignorUser;
		$formData['idResponsibleUser']['id'] = $task->idResponsibleUser;
		$formData['free'] = $task->free;
		$formData['pivot'] = $task->pivot;
		$formData['idPivot'] = $task->idPivot;
		$formData['comments'] = $task->comments;
		$formData['deadline'] = \Engine\DateTime::createFromTimestamp($task->deadline)->format(DATETIME_FORMAT);
		$formData['idOperationType'] = $task->idOperationType;

		// files
		$formData['filesList'] = $task->filesList;
		$formData['filesPath'] = $task->filesPath;

		return $formData;
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\PaginatedEntityListing::update_createEntityObject()
	 */
	protected function update_createEntityObject($formData)
	{
		$task = \Entity\Task::update($formData['id']);

		$task->idCategory = $formData['idCategory'];
		$task->description = $formData['description'];
		$task->priority = $formData['priority'];
		$task->idOffice = $formData['idOffice']['id'];
		$task->idDepartment = $formData['idDepartment']['id'];
		$task->idAssignorUser = $formData['idAssignorUser']['id'];
		$task->idResponsibleUser = $formData['idResponsibleUser']['id'];
		$task->free = ($formData['free']?1:0); // TODO field could be empty because the user doesn't have 'taskSetAsFree' permission, and this will change existing 1 to 0 anyways <- BUG
		$task->pivot = $formData['pivot'];
		$task->idPivot = $formData['idPivot'];
		$task->comments = $formData['comments'];
		$task->idOperationType = $formData['idOperationType'];

		$deadline = \Engine\DateTime::createFromIsoDateOrDatetime($formData['deadline']);
		if ($deadline->isValid() && !$deadline->isEmpty()) {
			$task->deadline = \Engine\DateTime::createFromIsoDatetime($formData['deadline']);
		}

		// files
		$unlinkFiles	= [];
		$filesWithPath  = [];
		foreach ($_FILES as $fileCode => $fileDetails) {
			// if the file is deleted
			if (!$formData[$fileCode.'_keepFile']) {
				// unlink the file
				if ($formData['files'][$fileCode]) {
					$unlinkFiles[] = $formData['files'][$fileCode];
				}

				$uploadedFile = new \App\Form\UploadedFiles\File($fileCode);
				if ($uploadedFile->hasValidFile()) {
					$filesWithPath[$uploadedFile->getName()] = $uploadedFile->getTempName();
				}

			}
		}

		$task->unlinkFiles = $unlinkFiles;
		$task->filesWithPath = $filesWithPath;

		return $task;
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\PaginatedEntityListing::delete_createEntityObject()
	 */
	protected function delete_createEntityObject($idRecord)
	{
		return \Entity\Task::delete($idRecord);
	}

	/**
	 * Task history
	 * @return \Engine\Mvc\Response\Html
	 */
	public function actionTaskHistory($R)
	{
		$msgs = \App\MessagesCollector::create();

		// instantiate the view
		$view = new View_TaskHistory($this);

		$task = \Entity\Task::select($R['id']);

		// send data to the view
		$view->setOutputVar('task', $task);
		$view->setPageTitle(sprintf("%s %s %s", $view->getPageTitle(), $this->lang['taskHistory']['sectionTitleAdded'],
			\Engine\Smarty\Modifiers\DateTimeFormat::create(\Engine\DateTime::createFromTimestamp($task->addTime)->formatDatetimeIso(), 'dateWithHM')
		));

		// render the view
		return new \Engine\Mvc\Response\Html($view->render());
	}


	/**
	 * Change task status
	 * @return \Engine\Mvc\Response\Html
	 */
	public function actionChangeStatus($R)
	{
		$msgs = \App\MessagesCollector::create();

		// get form data for this operation
		if (!$R[$this->formSubmitButtonName]) {
			$task = \Entity\Task::select($R['id']);
			$formData['id'] = $task->getId();
			$formData['status'] = $task->status;
			$formData['statusDescription'] = $task->statusDescription;

			if ($task->status=='refused') {
				$formData['statusReasonRefused'] = $task->statusReason;
			} elseif ($task->status=='onHold') {
				$formData['statusReasonOnHold'] = $task->statusReason;
			} else {}

			if ($task->estimatedDuration>86400) {
				$formData['estimatedDurationUnit'] = "days";
				$formData['estimatedDurationValue']= round($task->estimatedDuration/86400);
			} elseif ($task->estimatedDuration>3600) {
				$formData['estimatedDurationUnit'] = "hours";
				$formData['estimatedDurationValue']= round($task->estimatedDuration/3600);
			} else {
				$formData['estimatedDurationUnit'] = "minutes";
				$formData['estimatedDurationValue']= round($task->estimatedDuration/60);
			}

			$formData['estimatedFinishTime'] = \Engine\DateTime::createFromTimestamp($task->estimatedFinishTime)->format(DATETIME_FORMAT);
			$formData['estimatedDuration'] = $task->estimatedDuration;

		} else {
			$formData = $R;
		}

		// execute the model (and collect the output)
		$closePopup = false;
		if ($R[$this->formSubmitButtonName]) {
			\DB::startTransaction();
			try {
				$task = \Entity\Task::changeStatus($R['id']);
				$task->status = $formData['status'];
				$task->statusDescription = $formData['statusDescription'];

				if ($formData['status']=='refused') {
					$task->statusReason = $formData['statusReasonRefused'];
				} elseif ($formData['status']=='onHold') {
					$task->statusReason = $formData['statusReasonOnHold'];
				} else {}

				if ($formData['estimatedDurationUnit']=='days') {
					$task->estimatedDuration = $formData['estimatedDurationValue']*86400;
				} elseif ($formData['estimatedDurationUnit']=='hours') {
					$task->estimatedDuration = $formData['estimatedDurationValue']*3600;
				} else {
					$task->estimatedDuration = $formData['estimatedDurationValue']*60;
				}

				$task->estimatedFinishTime = \Engine\DateTime::createFromIsoDatetime($formData['estimatedFinishTime']);

				$task->save();

				\DB::commitTransaction();

				// action was successful
				$task->assignMessages();
				$closePopup = true;
			} catch (\App\Entity\Exception $e) {
				\DB::rollbackTransaction();
				$msgs->appendMessages($e->getMessagesCollector());
			}
		}

		// instantiate the view
		$view = new View_ChangeStatus($this);

		// send data to the view
		$view->addInput('formData', $formData);
		if ($closePopup) {
			$view->setClosePopup(true);
		}
		$view->getMessagesCollector()->appendMessages($msgs);
		$view->addInput('formSubmitButtonName', $this->formSubmitButtonName);

		// render the view
		return new \Engine\Mvc\Response\Html($view->render());
	}


	/**
	 * The "downloadFile" action
	 * @return String - the output of "downloadFile" action.
	 */
	protected function actionDownloadFile($R)
	{
		$task = \Entity\Task::select($R['idTask']);
		try {
			$task = \Entity\Task::select($R['idTask']);
			$fileContent = $task->getFileContent($R['file']);
		}
		catch (\Exception $ex) {
			throw new \Exception("The file couldn't be downloaded.");
		}

		$response = new \Engine\Mvc\Response\FileDownload($fileContent);
		$response->setFilename($R['file']);
		return $response;
	}


}
