<?php
// namespace administrator\components\com_jchat\controllers;
/**
 * @package JCHAT::LAMESSAGES::administrator::components::com_jchat
 * @subpackage controllers
 * @author Joomla! Extensions Store
 * @Copyright (C) 2015 - Joomla! Extensions Store
 * @license GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html  
 */
defined ( '_JEXEC' ) or die ( 'Restricted access' );

/**
 * Main controller leaved messages
 * @package JCHAT::LAMESSAGES::administrator::components::com_jchat
 * @subpackage controllers
 * @since 1.0
 */
class JChatControllerLamessages extends JChatController { 
	/**
	 * Setta il model state a partire dallo userstate di sessione
	 * @access protected
	 * @return void
	 */
	protected function setModelState($scope = 'default') {
		// User state specific
		$option= $this->option;
		
		// Get default model
		$defaultModel = $this->getModel();
		
		$filter_order = $this->getUserStateFromRequest( "$option.$scope.filter_order", 'filter_order', 'a.sentdate', 'cmd' );
		$filter_order_Dir = $this->getUserStateFromRequest ( "$option.$scope.filter_order_Dir", 'filter_order_Dir', 'desc', 'word' );
		$fromPeriod = $this->getUserStateFromRequest( "$option.$scope.fromperiod", 'fromperiod');
		$toPeriod = $this->getUserStateFromRequest( "$option.$scope.toperiod", 'toperiod');
		$worked = $this->getUserStateFromRequest( "$option.$scope.workedfilter", 'workedfilter');
		$closed = $this->getUserStateFromRequest( "$option.$scope.closedfilter", 'closedfilter');
		
		// Security safe for pagination
		if(isset($_REQUEST['start']) && !isset($_REQUEST['limitstart'])) {
			$_REQUEST['limitstart'] = $_REQUEST['start'];
		}
		parent::setModelState($scope);
		
		// Set model state  
		$defaultModel->setState('order', $filter_order);
		$defaultModel->setState('order_dir', $filter_order_Dir );
		$defaultModel->setState('fromPeriod', $fromPeriod);
		$defaultModel->setState('toPeriod', $toPeriod);
		$defaultModel->setState('workedfilter', $worked);
		$defaultModel->setState('closedfilter', $closed);
		
		return $defaultModel;
	}
	
	/**
	 * Default listEntities
	 * 
	 * @access public
	 * @param $cachable string
	 *       	 the view output will be cached
	 * @return void
	 */
	public function display($cachable = false, $urlparams = false) {
		// Set model state
		$defaultModel = $this->setModelState('lamessages');
		
		// Check if the user is logged in
		if (! $this->user->id) {
			$this->app->enqueueMessage ( JText::_ ( 'COM_JCHAT_MUST_BE_LOGGEDIN_TOMANAGE_TICKETS' ) );
			return;
		}
		
		// Check if the user has access to the chat app based on access level parameter
		if (! $this->allowDisplay()) {
			$this->app->enqueueMessage ( JText::_ ( 'COM_JCHAT_NOACCESS' ) );
			return;
		}
		
		// Check if the user has access to the chat app based on access level parameter
		if (! $this->hasGroupsPermissions('ticketsmanager', $defaultModel->getComponentParams())) {
			$this->app->enqueueMessage ( JText::_ ( 'COM_JCHAT_NOACCESS' ) );
			return;
		}
		 
		// Parent construction and view display
		parent::display($cachable);
	}
	
	/**
	 * Edit entity
	 *
	 * @access public
	 * @return void
	 */
	public function editEntity() {
		$this->app->input->set ( 'hidemainmenu', 1 );
		$cid = $this->app->input->get ( 'cid', array (
				0
		), 'array' );
		$idEntity = ( int ) $cid [0];
		$model = $this->getModel ();
		$model->setState ( 'option', $this->option );
	
		// Try to load record from model
		if (! $record = $model->loadEntity ( $idEntity )) {
			// Model set exceptions for something gone wrong, so enqueue exceptions and levels on application object then set redirect and exit
			$modelExceptions = $model->getErrors ();
			foreach ( $modelExceptions as $exception ) {
				$this->app->enqueueMessage ( $exception->getMessage (), $exception->getErrorLevel () );
			}
			$this->setRedirect ( JRoute::_("index.php?option=" . $this->option . "&view=" . $this->corename), JText::_('COM_JCHAT_ERROR_EDITING') );
			return false;
		}
	
		// Additional model state setting
		$model->setState ( 'option', $this->option );
	
		// Check out control on record
		if ($record->checked_out && $record->checked_out != $this->user->id) {
			$this->setRedirect ( JRoute::_("index.php?option=" . $this->option . "&view=" . $this->corename), JText::_ ( 'COM_JCHAT_CHECKEDOUT_RECORD' ), 'notice' );
			return false;
		}
	
		// Access check
		if ($record->id && ! $this->allowEdit ( $this->option )) {
			$this->setRedirect ( JRoute::_("index.php?option=" . $this->option . "&view=" . $this->corename), JText::_ ( 'COM_JCHAT_ERROR_ALERT_NOACCESS' ), 'notice' );
			return false;
		}
	
		if (! $record->id && ! $this->allowAdd ( $this->option )) {
			$this->setRedirect ( JRoute::_("index.php?option=" . $this->option . "&view=" . $this->corename), JText::_ ( 'COM_JCHAT_ERROR_ALERT_NOACCESS' ), 'notice' );
			return false;
		}
	
		// Check out del record
		if ($record->id) {
			$record->checkout ( $this->user->id );
		}
	
		// Get view and pushing model
		$view = $this->getView ();
		$view->setModel ( $model, true );
	
		// Call edit view
		$view->editEntity ( $record );
	}
	
	/**
	 * Manage entity apply/save after edit entity
	 *
	 * @access public
	 * @return boolean
	 */
	public function saveEntity() {
		$context = implode ( '.', array (
				$this->option,
				strtolower ( $this->getNames () ),
				'errordataload'
		) );
	
		// Load della model e bind store
		$model = $this->getModel ();
	
		if (! $result = $model->storeEntity ()) {
			// Model set exceptions for something gone wrong, so enqueue exceptions and levels on application object then set redirect and exit
			$modelException = $model->getError ( null, false );
			$this->app->enqueueMessage ( $modelException->getMessage (), $modelException->getErrorLevel () );
				
			// Store data for session recover
			$this->app->setUserState ( $context, $this->requestArray[$this->requestName] );
			$this->setRedirect ( JRoute::_("index.php?option=" . $this->option . "&task=" . $this->corename . ".editEntity&cid[]=" . $this->app->input->get ( 'id' )), JText::_ ( 'COM_JCHAT_ERROR_SAVING' ) );
			return false;
		}
	
		// Security safe if not model record id detected
		if (! $id = $result->id) {
			$id = $this->app->input->get ( 'id' );
		}
	
		// Redirects switcher
		switch($this->task) {
			case 'saveEntity':
				$redirects = array (
				'task' => 'display',
				'msgsufix' => '_SAVING'
						);
				break;
	
			case 'saveEntity2New':
				$redirects = array (
				'task' => 'editEntity',
				'msgsufix' => '_STORING'
						);
	
				break;
	
			default:
			case 'applyEntity':
				$redirects = array (
				'task' => 'editEntity&cid[]=' . $id,
				'msgsufix' => '_APPLY'
						);
				break;
		}
	
		$msg = 'COM_JCHAT_SUCCESS' . $redirects ['msgsufix'];
		$controllerTask = $redirects ['task'];
	
		$this->setRedirect ( JRoute::_("index.php?option=" . $this->option . "&task=" . $this->corename . "." . $controllerTask), JText::_ ( $msg ) );
	
		return true;
	}
	
	/**
	 * Delete a db table entity
	 *
	 * @access public
	 * @return void
	 */
	public function deleteEntity() {
		$cids = $this->app->input->get ( 'cid', array (), 'array' );
		// Access check
		if (! $this->allowDelete ( $this->option )) {
			$this->setRedirect ( "index.php?option=" . $this->option . "&task=" . $this->corename . ".display", JText::_ ( 'COM_JCHAT_ERROR_ALERT_NOACCESS' ), 'notice' );
			return false;
		}
		// Load della model e checkin before exit
		$model = $this->getModel ();
	
		if (! $model->deleteEntity ( $cids )) {
			// Model set exceptions for something gone wrong, so enqueue exceptions and levels on application object then set redirect and exit
			$modelException = $model->getError ( null, false );
			$this->app->enqueueMessage ( $modelException->getMessage (), $modelException->getErrorLevel () );
			$this->setRedirect ( JRoute::_("index.php?option=" . $this->option . "&view=" . $this->corename), JText::_ ( 'COM_JCHAT_ERROR_DELETE' ) );
			return false;
		}
	
		$this->setRedirect ( JRoute::_("index.php?option=" . $this->option . "&view=" . $this->corename), JText::_ ( 'COM_JCHAT_SUCCESS_DELETE' ) );
	}
	
	/**
	 * Manage cancel edit for entity and unlock record checked out
	 *
	 * @access public
	 * @return void
	 */
	public function cancelEntity() {
		$id = $this->app->input->get ( 'id' );
		// Load della model e checkin before exit
		$model = $this->getModel ();
	
		if (! $model->cancelEntity ( $id )) {
			// Model set exceptions for something gone wrong, so enqueue exceptions and levels on application object then set redirect and exit
			$modelException = $model->getError ( null, false );
			$this->app->enqueueMessage ( $modelException->getMessage (), $modelException->getErrorLevel () );
		}
	
		$this->setRedirect ( JRoute::_("index.php?option=" . $this->option . "&view=" . $this->corename), JText::_ ( 'COM_JCHAT_CANCELED_OPERATION' ) );
	}
	
	/**
	 * Avvia il processo di esportazione records
	 *
	 * @access public
	 * @return void
	 */
	public function exportMessages() {
		// Set model state
		$this->setModelState();
		// Mapping fields to load to column header
		$fieldsToLoadArray = array(	'a.name'=>JText::_('COM_JCHAT_LAMESSAGE_NAME'),
									'a.email'=>JText::_('COM_JCHAT_LAMESSAGE_EMAIL'),
									'a.message'=>JText::_('COM_JCHAT_MESSAGE'),  
									'a.sentdate'=>JText::_('COM_JCHAT_SENT'),
									'a.worked'=>JText::_('COM_JCHAT_WORKED_STATE'),
									'a.closed_ticket'=>JText::_('COM_JCHAT_CLOSED_TICKET'),
									'u.name AS username_logged'=>JText::_('COM_JCHAT_USERID'),
									'a.id AS msg_id'=>JText::_('ID'));
		$fieldsFunctionTransformation = array();
	
		$model = $this->getModel();
		$data = $model->exportMessages($fieldsToLoadArray, $fieldsFunctionTransformation);
	
		if(!$data) {
			$this->setRedirect(JRoute::_("index.php?option=" . $this->option . "&view=" . $this->corename), JText::_('NODATA_EXPORT'));
			return false;
		}
	
		// Get view
		$view = $this->getView();
		$view->sendCSVMessages($data, $fieldsFunctionTransformation);
	}
	
	/**
	 * Manage answered worked state for the ticket
	 * 
	 * @access public
	 */
	public function stateFlags() {
		// Access check
		if (! $this->allowEditState ( $this->option )) {
			$this->setRedirect ( JRoute::_("index.php?option=" . $this->option . "&view=" . $this->corename), JText::_ ( 'COM_JCHAT_ERROR_ALERT_NOACCESS' ), 'notice' );
			return false;
		}
		
		$cid = $this->app->input->get ( 'cid', array (
				0
		), 'array' );
		$idEntity = ( int ) $cid [0];
		
		$model = $this->getModel ();
		
		if (! $model->changeTicketState($idEntity, $this->task)) {
			// Model set exceptions for something gone wrong, so enqueue exceptions and levels on application object then set redirect and exit
			$modelException = $model->getError ( null, false );
			$this->app->enqueueMessage ( $modelException->getMessage (), $modelException->getErrorLevel () );
			$this->setRedirect ( JRoute::_("index.php?option=" . $this->option . "&view=" . $this->corename), JText::_ ( 'COM_JCHAT_ERROR_STATE_CHANGE' ) );
			return false;
		}
		
		$this->setRedirect ( JRoute::_("index.php?option=" . $this->option . "&view=" . $this->corename), JText::_ ( 'COM_JCHAT_LAMESSAGE_STATE_CHANGED' ) );
	}
	
	/**
	 * Risponde all'email del richiedente con il messaggio inserito dall'agente
	 * richiedendo la serializzazione delle risposte nell'apposito db field
	 *
	 * @access public
	 * @return void
	 */
	public function responseMessage() {
		$task = $this->app->input->get('task', 'responseMessage');
		$responseSubject = $this->app->input->getString('email_subject');
		$responseText = $this->app->input->getRaw('response', '');
		$idEntity = $this->app->input->getInt('id');
		
		// Response text vuota validazione lato server con return false
		if(!trim($responseSubject)) {
			$controllerTask = 'editEntity&cid[]=' . $idEntity; 
			$this->setRedirect ( JRoute::_("index.php?option=" . $this->option . "&task=" . $this->corename  . "." . $controllerTask), JText::_('COM_JCHAT_VALIDATION_ERROR'));
			return false;
		}
		 
		$model = $this->getModel();
		
		// Root controller -> dependency injection
		$mailer = JChatHelpersMailer::getInstance('Joomla');
		if (! $model->sendResponseStore($mailer, $idEntity, $responseSubject, $responseText)) {
			// Model set exceptions for something gone wrong, so enqueue exceptions and levels on application object then set redirect and exit
			$modelException = $model->getError ( null, false );
			$this->app->enqueueMessage ( $modelException->getMessage (), $modelException->getErrorLevel () );
				
			$this->setRedirect ( "index.php?option=" . $this->option . "&task=" . $this->corename . ".editEntity&cid=" . $this->app->input->get ( 'id' ), JText::_ ( 'COM_JCHAT_ERROR_SEND_MESSAGE' ) );
			return false;
		}
		
		$controllerTask = 'editEntity&cid=' . $idEntity; 
		$this->setRedirect ( JRoute::_("index.php?option=" . $this->option . "&task=" . $this->corename  . "." . $controllerTask), JText::_('COM_JCHAT_SUCCESS_SEND_MESSAGE'));
	}
	
	/**
	 * Class constructor
	 * @return Object&
	 */
	public function __construct($config = array()){
		// Mixin, add include path for admin side to avoid DRY on model
		$this->addModelPath ( JPATH_COMPONENT_ADMINISTRATOR . '/models', 'JChatModel' );
		
		parent::__construct($config);
	
		// Registering alias task
		$this->registerTask('applyEntity', 'saveEntity');
		$this->registerTask('workedFlagOff', 'stateFlags');
		$this->registerTask('workedFlagOn', 'stateFlags');
		$this->registerTask('closedFlagOff', 'stateFlags');
		$this->registerTask('closedFlagOn', 'stateFlags');
	}
}