Proyectos de Subversion LeadersLinked - Backend

Rev

Rev 11722 | Rev 14627 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |

<?php
declare(strict_types = 1);
namespace LeadersLinked\Controller;

use Laminas\Db\Adapter\AdapterInterface;
use Laminas\Cache\Storage\Adapter\AbstractAdapter;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\Log\LoggerInterface;
use Laminas\View\Model\JsonModel;
use Laminas\View\Model\ViewModel;
use LeadersLinked\Library\Functions;
use LeadersLinked\Mapper\UserMapper;
use LeadersLinked\Mapper\ConnectionMapper;
use LeadersLinked\Mapper\ChatMessageMapper;
use LeadersLinked\Mapper\ChatGroupMapper;
use LeadersLinked\Mapper\ChatGroupMessageMapper;
use LeadersLinked\Mapper\ChatGroupUserMessageMapper;
use LeadersLinked\Mapper\ChatUserMapper;
use LeadersLinked\Model\ChatMessage;
use LeadersLinked\Model\ChatGroupMessage;
use LeadersLinked\Model\ChatGroupUserMessage;
use LeadersLinked\Model\Connection;
use LeadersLinked\Model\ChatGroup;
use LeadersLinked\Model\ChatUser;
use LeadersLinked\Form\CreateChatGroupForm;
use LeadersLinked\Mapper\ChatGroupUserMapper;
use LeadersLinked\Model\ChatGroupUser;


class ChatController extends AbstractActionController
{
    const SESSION_CHAT_OPEN_BOXES = 'chat_open_boxes';
    
    
    /**
     *
     * @var AdapterInterface
     */
    private $adapter;

    /**
     *
     * @var AbstractAdapter
     */
    private $cache;

    /**
     *
     * @var LoggerInterface
     */
    private $logger;

    /**
     *
     * @var array
     */
    private $config;

    /**
     *
     * @param AdapterInterface $adapter
     * @param AbstractAdapter $cache
     * @param LoggerInterface $logger
     * @param array $config
     */
    public function __construct($adapter, $cache, $logger, $config)
    {
        $this->adapter  = $adapter;
        $this->cache    = $cache;
        $this->logger   = $logger;
        $this->config   = $config;
        
 
        if(!isset($_SESSION[self::SESSION_CHAT_OPEN_BOXES])) {
            $_SESSION[self::SESSION_CHAT_OPEN_BOXES] = [];
        }

    }
    
    /**
     *
     * Ruta usada para mostrar el chat en pantalla completa usada en los moviles
     * 
     */
    public function indexAction()
    {
        $currentUserPlugin = $this->plugin('currentUserPlugin');
        $currentUser = $currentUserPlugin->getUser();
        
        $connectionMapper = ConnectionMapper:: getInstance($this->adapter);
        $connectionIds = $connectionMapper->fetchAllConnectionsByUserReturnIds( $currentUser->id );
        
        $contacts = [];
        if($connectionIds) {
            $userMapper = UserMapper::getInstance($this->adapter);
            $users = $userMapper->fetchAllByIds($connectionIds);
            
            foreach($users as $user)
            {
                $username = trim($user->first_name . ' ' . $user->last_name);
                
                
                if($this->isInactiveConnection($user->last_heart_beat_at ? $user->last_heart_beat_at : '')) {
                    $userMapper->updateChatOfflineStatus($user->id);
                    $status = 'Offline';
                } else {
                    $status = "Online";
                }
                
                $user_image = $this->url()->fromRoute('storage', ['type' => 'user', 'code' => $user->uuid, 'filename' => $user->image]);
                
                array_push($contacts, ['id' => $user->uuid, 'status'=> $status,'name'=> $username, 'image' => $user_image]);
                
            }
        }
        
        $groups = [];
        $chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);
        $chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);
        
        $results = $chatGroupUserMapper->fetchAllByUserId($currentUser->id);
        if(is_array($results)) {
            foreach ($results as $r) 
            {
                
                $chatOwner = $chatGroupUserMapper->fetchOwnerByGroupId($r->group_id);
                $userOwner = $userMapper->fetchOne( $chatOwner->user_id );
                $chatGroup = $chatGroupMapper->fetchOne($r->group_id);
                
                array_push($groups, ['id' => $chatGroup->uuid, 'name' => $chatGroup->name, 'owner_id' => $userOwner->uuid ]);
                
                
                
            }
        }
        
        /*
        $this->layout()->setTemplate('layout/layout-chat.phtml');
        $this->layout()->setVariables([
            'is_chat' => true
        ]);*/
        $this->layout()->setTemplate('layout/layout-backend');
        $viewModel = new ViewModel();
        $viewModel->setTemplate('leaders-linked/chat/chat.phtml');
        $viewModel->setVariables([
            'contacts' => $contacts, 
            'groups' => $groups, 
            'user_id' => $currentUser->id,
            'is_chat' => true
        ]);
        return $viewModel ;
       
        
    }
    
    /**
     * Recuperamos los contactos y grupos 
     * tiene que enviarse un petición GET a la siguiente url: /chat/heart-beat
     * retorna un json en caso de ser  positivo
     * [
     *  'success' : true,
     *  'data' : [
     *     [
     *       'url_leave'                                => 'url para abandonar el grupo en caso de no ser el propietario',
     *       'url_delete'                               => 'url para borrar el grupo si es el propietario',
     *       'url_add_user_to_group'                    => 'url para agregar un usuario al grupo si es el propietario',
     *       'url_get_contacts_availables_for_group'    => 'url para obtener los usuarios disponibles para agregarlos al grupo',
     *       'url_get_contact_group_list'               => 'url para obtener los usuarios del grupo si es el propietario',
     *       'url_clear'                                => 'url para limpiar los mensajes del grupo',
     *       'url_close'                                => 'url para cerrar el chat',
     *       'url_send'                                 => 'url para enviar un mensaje',
     *       'url_upload'                               => 'url para subir un archivo, imagen o video',
     *       'url_get_all_messages'                     => 'url para para obtener los mensajes',
     *       'url_mark_seen'                            => 'url para marcar los mensajes como vistos'
     *       'url_mark_received'                        => 'url para marcar los mensajes como recibios'
     *       'id'                                       => 'id del grupo encriptado',
     *       'name'                                     => 'nombre del grupo',
     *       'type'                                     => 'group', //fixed
     *       'is_open'                                  => 'true/false',
     *       'unsee_messages'                           => 'true/false',
     *       'unread_messages'                          => 'true/false'
     *      ],
     *      [
     *        'url_clear'               => 'url para limpiar los mensajes del grupo',
     *        'url_close'               => 'url para cerrar el chat',
     *        'url_send'                => 'url para enviar un mensaje',
     *        'url_upload'              => 'url para subir un archivo, imagen o video',
     *        'url_get_all_messages'    => 'url para para obtener los mensajes',
     *        'url_mark_seen'                            => 'url para marcar los mensajes como vistos'
     *        'url_mark_received'                        => 'url para marcar los mensajes como recibios'
     *        'id'                      => 'id del usuario encriptado',
     *        'name'                    => 'nombre del usuario',
     *        'image'                   => 'imagen del usuario',
     *        'type'                    => 'user' //fixed,
     *        'profile'                 => 'url del profile',
     *        'online'                  => 'true/false',
     *        'is_open'                 => 'true/false',
     *        'unsee_messages'          => 'true/false'
     *        'unread_messages'         => 'true/false'
     *     ]
     * ]
     * En caso de ser negativo puede haber 2 formatos
     * [
     *  'success' : false,
     *  'data' : mensaje de error
     * ]
     * o
     * [
     *  'success' : false,
     *  'data' : [
     *      'fieldname' : [
     *          'mensaje de error'
     *      ]
     *  ]
     * ]
     * @return \Laminas\View\Model\JsonModel
     */
    public function heartBeatAction()
    {
       
        $request    = $this->getRequest();
        if($request->isGet()) {
          
          
            $currentUserPlugin = $this->plugin('currentUserPlugin');
            $currentUser = $currentUserPlugin->getUser();

            $userMapper = UserMapper::getInstance($this->adapter);
            $userMapper->updateChatOnlineStatus($currentUser->id);

            $chats      = [];
            
            $chatGroupMapper            = ChatGroupMapper::getInstance($this->adapter);
            $chatGroupUserMapper        = ChatGroupUserMapper::getInstance($this->adapter);
            $chatGroupUserMessageMapper = ChatGroupUserMessageMapper::getInstance($this->adapter);
           
            
            $results = $chatGroupUserMapper->fetchAllByUserId($currentUser->id);
            
            if (is_array($results)) {
                foreach ($results as $r) 
                {
                    
                    $chatGroup = $chatGroupMapper->fetchOne($r->group_id); 
                    $chatUserOwner = $chatGroupUserMapper->fetchOwnerByGroupId($chatGroup->id);
                    
                    
                    $is_open = in_array($chatGroup->uuid, $_SESSION[self::SESSION_CHAT_OPEN_BOXES]);
                    $not_seen_messages     = $chatGroupUserMessageMapper->existNotSeenMessages($chatGroup->id, $currentUser->id);
                    $not_received_messages = $chatGroupUserMessageMapper->existNotReceivedMessages($chatGroup->id, $currentUser->id);
                    if($chatGroup->high_performance_team_group_id!=NULL){
                        $chat = [
                            'url_leave'                             => '',
                            'url_delete'                            => '',
                            'url_add_user_to_group'                 => '',
                            'url_get_contact_group_list'            => '',
                            'url_get_contacts_availables_for_group' => '',
                            'url_clear'                             => $this->url()->fromRoute('chat/clear', ['id' => $chatGroup->uuid]),
                            'url_close'                             => $this->url()->fromRoute('chat/close', ['id' => $chatGroup->uuid]),
                            'url_send'                              => $this->url()->fromRoute('chat/send', ['id' => $chatGroup->uuid]),
                            'url_upload'                            => $this->url()->fromRoute('chat/upload', ['id' => $chatGroup->uuid]),
                            'url_get_all_messages'                  => $this->url()->fromRoute('chat/get-all-messages', ['id' => $chatGroup->uuid]),
                            'url_mark_seen'                         => $this->url()->fromRoute('chat/mark-seen', ['id' => $chatGroup->uuid]),
                            'url_mark_received'                     => $this->url()->fromRoute('chat/mark-received', ['id' => $chatGroup->uuid]),
                            'id'                                    => $chatGroup->uuid,
                            'name'                                  => $chatGroup->name,
                            'type'                                  => 'group',
                            'is_open'                               => $is_open ? 1 : 0,
                            'not_seen_messages'                     => $not_seen_messages,
                            'not_received_messages'                 => $not_received_messages,
                            
                        ];
                    }else{
                        if($chatUserOwner->user_id == $currentUser->id ) {
                        
                            $chat = [
                                'url_leave'                             => '',
                                'url_delete'                            => $this->url()->fromRoute('chat/delete-group', ['group_id' => $chatGroup->uuid]),
                                'url_add_user_to_group'                 => $this->url()->fromRoute('chat/add-user-to-group', ['group_id' => $chatGroup->uuid]),
                                'url_get_contact_group_list'            => $this->url()->fromRoute('chat/get-contact-group-list', ['group_id' => $chatGroup->uuid]),
                                'url_get_contacts_availables_for_group' => $this->url()->fromRoute('chat/get-contacts-availables-for-group', ['group_id' => $chatGroup->uuid]),
                                'url_clear'                             => $this->url()->fromRoute('chat/clear', ['id' => $chatGroup->uuid]),
                                'url_close'                             => $this->url()->fromRoute('chat/close', ['id' => $chatGroup->uuid]),
                                'url_send'                              => $this->url()->fromRoute('chat/send', ['id' => $chatGroup->uuid]),
                                'url_upload'                            => $this->url()->fromRoute('chat/upload', ['id' => $chatGroup->uuid]),
                                'url_get_all_messages'                  => $this->url()->fromRoute('chat/get-all-messages', ['id' => $chatGroup->uuid]),
                                'url_mark_seen'                         => $this->url()->fromRoute('chat/mark-seen', ['id' => $chatGroup->uuid]),
                                'url_mark_received'                     => $this->url()->fromRoute('chat/mark-received', ['id' => $chatGroup->uuid]),
                                'id'                                    => $chatGroup->uuid,
                                'name'                                  => $chatGroup->name,
                                'type'                                  => 'group',
                                'is_open'                               => $is_open ? 1 : 0,
                                'not_seen_messages'                     => $not_seen_messages,
                                'not_received_messages'                 => $not_received_messages,
                                
                            ];
                        } else {
                     
                            $chat = [
                                'url_delete'                    => '',
                                'url_add_user_to_group'         => '',
                                'url_get_contact_group_list'    => $this->url()->fromRoute('chat/get-contact-group-list', ['group_id' => $chatGroup->uuid]),
                                'url_leave'                     => $this->url()->fromRoute('chat/leave-group', ['group_id' => $chatGroup->uuid]),
                                'url_clear'                     => $this->url()->fromRoute('chat/clear', ['id' => $chatGroup->uuid]),
                                'url_close'                     => $this->url()->fromRoute('chat/close', ['id' => $chatGroup->uuid]),
                                'url_send'                      => $this->url()->fromRoute('chat/send', ['id' => $chatGroup->uuid]),
                                'url_upload'                    => $this->url()->fromRoute('chat/upload', ['id' => $chatGroup->uuid]),
                                'url_get_all_messages'          => $this->url()->fromRoute('chat/get-all-messages', ['id' => $chatGroup->uuid]),
                                'url_mark_seen'                 => $this->url()->fromRoute('chat/mark-seen', ['id' => $chatGroup->uuid]),
                                'url_mark_received'             => $this->url()->fromRoute('chat/mark-received', ['id' => $chatGroup->uuid]),
                                'id'                            => $chatGroup->uuid,
                                'name'                          => $chatGroup->name,
                                'type'                          => 'group',
                                'is_open'                       => $is_open ? 1 : 0,
                                'not_seen_messages'             => $not_seen_messages,
                                'not_received_messages'         => $not_received_messages,
                            ];
                        }
                    }
                   

                   array_push($chats, $chat);
                }
            }
            
            $chatUserMapper = ChatUserMapper::getInstance($this->adapter);
            $chatMessageMapper = ChatMessageMapper::getInstance($this->adapter);
            
            $connectionMapper = ConnectionMapper::getInstance($this->adapter);
            $connectionIds = $connectionMapper->fetchAllConnectionsByUserReturnIds($currentUser->id);

            
           
            if ($connectionIds) {
                 
                $userMapper = UserMapper::getInstance($this->adapter);
                $users = $userMapper->fetchAllByIds($connectionIds);
                
                foreach ($users as $user) 
                {
                    
                   
                    if ($this->isInactiveConnection($user->last_heart_beat_at ? $user->last_heart_beat_at : '')) {
                        $userMapper->updateChatOfflineStatus($user->id);
                        $online = false;
                    } else {
                        $online = true;
                    }
                    
                    
                    $chatUser = $chatUserMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);
                    
                    
                    if($chatUser) {
                        $is_open = in_array($chatUser->uuid, $_SESSION[self::SESSION_CHAT_OPEN_BOXES]);
                        $not_received_messages = $chatMessageMapper->existNotReceivedMessagesByChatIdAndToId($chatUser->id, $currentUser->id);
                        $not_seen_messages = $chatMessageMapper->existNotSeenMessagesByChatIdAndToId($chatUser->id, $currentUser->id);
                    } else {
                        $is_open = false;
                        $not_seen_messages = false;
                        $not_received_messages = false;
                    }
                   
                    
                    $chat = [
                        'url_clear'                 => $this->url()->fromRoute('chat/clear', ['id' => $user->uuid]),
                        'url_close'                 => $this->url()->fromRoute('chat/close', ['id' => $user->uuid]),
                        'url_send'                  => $this->url()->fromRoute('chat/send', ['id' => $user->uuid]),
                        'url_upload'                => $this->url()->fromRoute('chat/upload', ['id' => $user->uuid]),
                        'url_mark_seen'             => $this->url()->fromRoute('chat/mark-seen', ['id' => $user->uuid]),
                        'url_mark_received'         => $this->url()->fromRoute('chat/mark-received', ['id' => $user->uuid]),
                        'url_get_all_messages'      => $this->url()->fromRoute('chat/get-all-messages', ['id' => $user->uuid]),
                        'id'                        => $user->uuid,
                        'name'                      => trim($user->first_name . ' ' . $user->last_name),
                        'image'                     => $this->url()->fromRoute('storage', ['code' => $user->uuid, 'type' => 'user', 'filename' => $user->image]),
                        /*'profile'                   => $this->url()->fromRoute('profile/view', ['id' =>$user->uuid]),*/
                        'type'                      => 'user',
                        'online'                    => $online ? 1 : 0,
                        'is_open'                   => $is_open ? 1 : 0,
                        'not_seen_messages'         => $not_seen_messages,
                        'not_received_messages'     => $not_received_messages,
                    ];
                 
                    array_push($chats, $chat);
                }
            }
          
            $userMapper->updateLastHeartBeat($currentUser->id);

            $response = [
                'success' => true,
                'data' => $chats
            ];
            
        } else {
            $response = [
                'success' => false,
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
            ];
        }
        
        return new JsonModel($response);
    }
    
  

    /**
     * Esta función crea un grupo y asigna al usuario actual como el owner del mismo, 
     * tiene que enviarse un petición POST a la siguiente url: /chat/create-group 
     * con el siguiente parámetro
     * name = un string con un máximo de 50 carácteres
     * retorna un json en caso de ser  positivo
     * [
     *  'success' : true, 
     *  'data' : ID del grupo encriptado
     * ]
     * En caso de ser negativo puede haber 2 formatos
     * [
     *  'success' : false, 
     *  'data' : mensaje de error
     * ]
     * o 
     * [
     *  'success' : false, 
     *  'data' : [
     *      'fieldname' : [
     *          'mensaje de error'
     *      ]
     *  ]
     * ]
     * @return \Laminas\View\Model\JsonModel
     */
    public function createGroupAction()
    {
        $request    = $this->getRequest();
        if($request->isPost()) {
            $form = new  CreateChatGroupForm();
            $form->setData($request->getPost()->toArray());
            
            if($form->isValid()) {
                $dataPost = (array) $form->getData();
                $name = $dataPost['name'];
                
            
                $currentUserPlugin = $this->plugin('currentUserPlugin');
                $currentUser = $currentUserPlugin->getUser();
       
                $chatGroup = new ChatGroup();
                $chatGroup->name = $name;


                $chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);
                $result = $chatGroupMapper->insert($chatGroup);
                if ($result) {
                    $chatGroup = $chatGroupMapper->fetchOne($chatGroup->id);
                    
                    
                    
                    $chatGroupUser = new ChatGroupUser();
                    $chatGroupUser->group_id = $chatGroup->id;
                    $chatGroupUser->user_id = $currentUser->id;
                    $chatGroupUser->owner = ChatGroupUser::OWNER_YES;
                    
                    $chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);
                    $result = $chatGroupUserMapper->insert($chatGroupUser);
                    
                    if($result)  {
                        $fullpath_chat = $this->config['leaderslinked.fullpath.chat'];
                        $dirpath = $fullpath_chat . $chatGroup->uuid;
                        if (! file_exists($dirpath)) {
                            mkdir($dirpath, 0777, true);
                            chmod($dirpath, 0777);
                        }
            
                        $response = [
                            'success' => true,
                            'data' => $chatGroup->uuid,
                        ];
                    } else {
                        $response = [
                            'success' => false,
                            'data' => $chatGroupUserMapper->getError(),
                        ];
                    }
                    
                } else {
                    $response = [
                        'success' => false,
                        'data' => $chatGroupMapper->getError(),
                    ];
                }
            } else {
                $messages = [];
                $form_messages = (array) $form->getMessages();
                foreach($form_messages  as $fieldname => $field_messages)
                {
                    
                    $messages[$fieldname] = array_values($field_messages);
                }
                
                return new JsonModel([
                    'success'   => false,
                    'data'   => $messages
                ]);
            }
        } else {
            $response = [
                'success' => false,
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
            ];
        }

        return new JsonModel($response);
    }

    /**
     * Esta función crea un grupo y asigna al usuario al mismo, solo el owner puede hacerlo
     * Es una petición POST el url que contiene el ID encriptado del chat (/chat/add-user-to-group/:group_id) 
     * Parámetros del route
     * :group_id = id del grupo encriptado
     * Parámetro post
     * uid = id encriptado del usuario
     * retorna un json en caso de ser  positivo
     * [
     *  'success' : true,
     *  'data' : [
     *     [
     *       'url_remove_from_group' => 'url para remover el usuario del grupo',
     *       'id'                    => 'id del usuario encriptado',
     *       'name'                  => 'nombre del usuario',
     *       'image'                 => 'imagen del usuario',
     *       'type'                  => 'user' //fixed,
     *       'online'                => $online,
     *     ]
     * ]
     * En caso de ser negativo puede haber 2 formatos
     * [
     *  'success' : false,
     *  'data' : mensaje de error
     * ]
     * o
     * [
     *  'success' : false,
     *  'data' : [
     *      'fieldname' : [
     *          'mensaje de error'
     *      ]
     *  ]
     * ]
     * @return \Laminas\View\Model\JsonModel
     */
    public function addUserToGroupAction()
    {
        $request    = $this->getRequest();
        if($request->isPost()) {
            $currentUserPlugin = $this->plugin('currentUserPlugin');
            $currentUser = $currentUserPlugin->getUser();
    
            $group_id   = $this->params()->fromRoute('group_id');
            $user_id    = $this->params()->fromPost('uid');
            
            if(empty($group_id) || empty($user_id)) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_PARAMETERS_ARE_INVALID'
                ]);
            }
    
            $chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);
            $chatGroup = $chatGroupMapper->fetchOneByUuid($group_id);
            if(!$chatGroup) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_CHAT_GROUP_NOT_FOUND'
                ]);
            }
            if($chatGroup->high_performance_team_group_id!=NULL){
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_YOU_DO_NOT_HAVE_ACCESS'
                ]);
            }
            $chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);
            $chatGroupOwner = $chatGroupUserMapper->fetchOwnerByGroupId($chatGroup->id);
                
            if($chatGroupOwner->user_id != $currentUser->id) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_CHAT_GROUP_YOU_ARE_NOT_OWNER'
                ]);
            }
           
            $userMapper = UserMapper::getInstance($this->adapter);
            $user = $userMapper->fetchOneByUuid($user_id);
                    
            if(!$user) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_USER_NOT_FOUND'
                ]);
            }
            
            if($chatGroupOwner->user_id == $user->id) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_CHAT_I_CAN_NOT_ADD_HIMSELF'
                ]);
            }
                        
            
            $connectionMapper = ConnectionMapper::getInstance($this->adapter);
            $connection = $connectionMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);
            if(!$connection) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_THIS_USER_IS_NOT_A_CONNECTION'
                ]);
            }
                            
            $chatGroupUser = $chatGroupUserMapper->fetchOneByGroupIdAndUserId($chatGroup->id, $user->id);
            if($chatGroupUser) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_THIS_USER_ALREADY_EXISTS_IN_THIS_GROUP'
                ]);
            }
                                

            $chatGroupUser = new ChatGroupUser();
            $chatGroupUser->group_id    = $chatGroup->id;
            $chatGroupUser->user_id     = $user->id;
            $chatGroupUser->owner       = ChatGroupUser::OWNER_NO;
            
            $result = $chatGroupUserMapper->insert($chatGroupUser);
            if(!$result) {
                return new JsonModel([
                    'success' => false,
                    'data' => $chatGroupUserMapper->getError()
                ]);
            }
            
            if ($this->isInactiveConnection($user->last_heart_beat_at ? $user->last_heart_beat_at : '')) {
                $userMapper->updateChatOfflineStatus($user->id);
                $online = false;
            } else {
                $online = true;
            }
                                    
                                    
            return new JsonModel([
                'success' => true,
                'data' => [
                    'url_remove_from_group' => $this->url()->fromRoute('chat/remove-user-from-group', ['group_id' => $chatGroup->uuid, 'user_id' => $user->uuid]),
                    'id'        => $user->uuid,
                    'name'      => trim($user->first_name . ' ' . $user->last_name),
                    'image'     => $this->url()->fromRoute('storage', ['code' => $user->uuid, 'type' => 'user', 'filename' => $user->image]),
                    'type'      => 'user',
                    'online'    => $online,
                ]
            ]);    


        } else {
            return new JsonModel([
                'success' => false,
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
            ]);
        }

    }

    /**
     * Esta función remueve el usuario del grupo
     * Es una petición POST el url que contiene el ID encriptado del chat (/chat/remove-user-from-group/:group_id/:user_id) 
     * y la cuál se recibe en la función heartBeat.
     * Parámetros del route
     * group_id= id encriptado del grupo
     * user_id = id encriptado del usuario
     * retorna un json en caso de ser  positivo
     * [
     *  'success' : true,
     * ]
     * En caso de ser negativo puede haber 2 formatos
     * [
     *  'success' : false,
     *  'data' : mensaje de error
     * ]
     * @return \Laminas\View\Model\JsonModel
     */
    public function removeUserFromGroupAction()
    {
        $request    = $this->getRequest();
        if($request->isPost()) {
        
            $currentUserPlugin = $this->plugin('currentUserPlugin');
            $currentUser = $currentUserPlugin->getUser();
    
            $user_id = $this->params()->fromRoute('user_id');
            $group_id = $this->params()->fromRoute('group_id');
            
            if(empty($group_id) || empty($user_id)) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_PARAMETERS_ARE_INVALID'
                ]);
            }
            
            $chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);
            $chatGroup = $chatGroupMapper->fetchOneByUuid($group_id);
            if(!$chatGroup) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_CHAT_GROUP_NOT_FOUND'
                ]);
            }
            if($chatGroup->high_performance_team_group_id!=NULL){
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_YOU_DO_NOT_HAVE_ACCESS'
                ]);
            }
            $chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);
            $chatGroupOwner = $chatGroupUserMapper->fetchOwnerByGroupId($chatGroup->id);
            
            if($chatGroupOwner->user_id != $currentUser->id) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_CHAT_GROUP_YOU_ARE_NOT_OWNER'
                ]);
            }
            
            $userMapper = UserMapper::getInstance($this->adapter);
            $user = $userMapper->fetchOneByUuid($user_id);
            
            if(!$user) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_USER_NOT_FOUND'
                ]);
            }
            
            if($chatGroupOwner->user_id == $user->id) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_CHAT_I_CAN_NOT_REMOVE_MYSELF'
                ]);
            }
            
            
 

            $chatGroupUser = $chatGroupUserMapper->fetchOneByGroupIdAndUserId($chatGroup->id, $user->id);
            if(!$chatGroupUser) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_CHAT_GROUP_YOU_NOT_MEMBER'
                ]);
            }
            

            $response = $chatGroupUserMapper->deleteByGroupIdAndUserId($chatGroup->id, $user->id);
            if($response) {
                return new JsonModel([
                    'success' => true
                ]);
            } else {
                return new JsonModel([
                    'success' => false,
                    'data' => $chatGroupMapper->getError()
                ]);
            }
        
        } else {
            return new JsonModel([
                'success' => false,
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
            ]);
        }
    }

    
    /**
     * Abandonar un grupo
     * Es una petición POST el url que contiene el ID encriptado del chat (/chat/leave-group/:group_id) y la cuál se recibe en la función heartBeat.
     * Parámetros del route
     * :group_id = id del grupo encriptado
     * En caso de una respuesta positiva
     * [
     *      'success' => true,
     * ]
     * En caso de un respuesta negativa
     * [
     *      'success' => false,
     *      'data' => (string) 'mensaje_de_error'
     * ]
     * @return \Laminas\View\Model\JsonModel
     */
    public function leaveGroupAction()
    {
        $request    = $this->getRequest();
        if($request->isPost()) {
            $currentUserPlugin = $this->plugin('currentUserPlugin');
            $currentUser = $currentUserPlugin->getUser();
            
            $result = false;
            $group_id = $this->params()->fromRoute('group_id');
            
            
            if(empty($group_id)) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_PARAMETERS_ARE_INVALID'
                ]);
            }
            
            
            $chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);
            $chatGroup = $chatGroupMapper->fetchOneByUuid($group_id);
            if(!$chatGroup) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_GROUP_NOT_FOUND'
                ]);
            }
            if($chatGroup->high_performance_team_group_id!=NULL){
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_YOU_DO_NOT_HAVE_ACCESS'
                ]);
            }
            $chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);
            $chatGroupUser = $chatGroupUserMapper->fetchOneByGroupIdAndUserId($chatGroup->id, $currentUser->id);
            if(!$chatGroupUser) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_CHAT_GROUP_YOU_NOT_MEMBER'
                ]);
            }
            
            if($chatGroupUser->owner == ChatGroupUser::OWNER_YES) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_CHAT_GROUP_YOU_ARE_OWNER'
                ]);
            }
            
            
            $result = $chatGroupUserMapper->deleteByGroupIdAndUserId($chatGroupUser->group_id, $chatGroupUser->user_id);
            if($result) {
                return new JsonModel([
                    'success' => true
                ]);
            } else {
                return new JsonModel([
                    'success' => false,
                    'data' => $chatGroupMapper->getError()
                ]);
            }

    
           
        } else {
            return new JsonModel([
                'success' => false,
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
            ]);
        }

    }
    
    /**
     * 
     * @param ChatGroup $chatGroup
     * @param int $page
     * @return array
     */
    private function getAllMessagesForChatGroup($chatGroup, $page = 0)
    {
        $currentUserPlugin = $this->plugin('currentUserPlugin');
        $currentUser = $currentUserPlugin->getUser();
        
        $chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);
        $chatGroupUser = $chatGroupUserMapper->fetchOneByGroupIdAndUserId($chatGroup->id, $currentUser->id);
        
        if(!$chatGroupUser) {
            return [
                'success' => false,
                'data' => 'ERROR_CHAT_GROUP_YOU_NOT_MEMBER'
            ];
        }
        
        if(!in_array(trim($chatGroup->uuid), $_SESSION[self::SESSION_CHAT_OPEN_BOXES])) {
            $_SESSION[self::SESSION_CHAT_OPEN_BOXES][] = $chatGroup->uuid;
        }
        
        $chatGroupMessageMapper = ChatGroupMessageMapper::getInstance($this->adapter);
        $paginator = $chatGroupMessageMapper->getPaginatorByGroupId($chatGroup->id, $page);
        
        $pages = $paginator->count();
        $page  = $paginator->getCurrentPageNumber();
        
        $items = [];
        $users = [];
        $userMapper = UserMapper::getInstance($this->adapter);
        
        foreach ($paginator as $m) 
        {

            if (isset($users[$m->sender_id])) {
                $userdata_from = $users[$m->sender_id];
            } else {
                $userdata_from = $userMapper->fetchOne($m->sender_id);
                $users[ $m->sender_id ] = $userdata_from;
            }
            
            $pic_from = $this->url()->fromRoute('storage', [
                'code' => $userdata_from->uuid,
                'type' => 'user',
                'filename' => $userdata_from->image
            ]);
            $u =  $userdata_from->id == $currentUser->id ? 1 : 2;
            if($m->type == ChatGroupMessage::TYPE_TEXT) {
                $content = $this->sanitize($m->content);
            } else {
                $content = $this->url()->fromRoute('storage', ['code' => $chatGroup->uuid, 'type' => 'chat', 'filename' => $m->content]);
            }
            
            $msgtime = $this->timeAgo($m->added_on);
            array_push($items, [
                'user_name' => trim($userdata_from->first_name . ' ' .$userdata_from->last_name) ,
                'user_id' => $userdata_from->uuid,
                'user_image' => $pic_from,
                'u' => $u,
                'mtype' => $m->type,
                'm' => $content,
                'time' => $msgtime,
                'id' => $m->uuid
            ]);
        }
        
        return [
            'success' => true,
            'data' => [
                'page' => $page,
                'pages' => $pages,
                'items' => $items
            ]
        ];
        
        
    }
    
    /**
     *
     * @param ChatUser $chatUser
     * @param int $page
     * @return array
     */
    private function getAllMessagesForChatUser($chatUser, $page = 0)
    {
        $currentUserPlugin = $this->plugin('currentUserPlugin');
        $currentUser = $currentUserPlugin->getUser();
        
        if(!in_array(trim($chatUser->uuid), $_SESSION[self::SESSION_CHAT_OPEN_BOXES])) {
            $_SESSION[self::SESSION_CHAT_OPEN_BOXES][] = $chatUser->uuid;
        }
        
        $chatMessageMapper = ChatMessageMapper::getInstance($this->adapter);
        $paginator = $chatMessageMapper->getAllMessagesPaginatorByChatId($chatUser->id, $page);
        $pages = $paginator->count();
        $page = $paginator->getCurrentPageNumber();
        
        $items = [];
        $users = [];
        $userMapper = UserMapper::getInstance($this->adapter);
        
        $messages = $paginator->getCurrentItems();
        foreach ($messages as $m) {
            $from_id = (int) $m->from_id;
            $to_id = (int) $m->to_id;
            
            if (isset($users[$from_id])) {
                $userdata_from = $users[$from_id];
            } else {
                $userdata_from = $userMapper->fetchOne($from_id);
                $users[$from_id] = $userdata_from;
            }
            
            $pic_from = $this->url()->fromRoute('storage', [
                'code' => $userdata_from->uuid,
                'type' => 'user',
                'filename' => $userdata_from->image
            ]);
            
            if (isset($users[$to_id])) {
                $userdata_to = $users[$to_id];
            } else {
                $userdata_to = $userMapper->fetchOne($to_id);
                $users[ $to_id ] = $userdata_to;
            }
            
            $u = $m->from_id == $currentUser->id ? 1 : 2;
            
            
            if($m->type == ChatMessage::TYPE_TEXT) {
                $content = $this->sanitize($m->content);
            } else {
                $content = $this->url()->fromRoute('storage', ['code' => $chatUser->uuid, 'type' => 'chat', 'filename' => $m->content]);
            }
            
            $msgtime = $this->timeAgo($m->added_on);
            array_push($items, [
                'user_name' => ($userdata_from->first_name . ' ' . $userdata_from->last_name),
                'user_id' => $userdata_from->uuid,
                'user_image' => $pic_from,
                'u' => $u,
                'mtype' => $m->type,
                'm' => $content,
                'time' => $msgtime,
                'id' => $m->uuid,
            ]);
        }
        
        
        if ($this->isInactiveConnection($currentUser->last_heart_beat_at ? $currentUser->last_heart_beat_at : '')) {
            $userMapper->updateChatOfflineStatus($currentUser->id);
            $online = false;
        } else {
            $online = true;
        }
        
        
        return [
            'success' => true,
            'data' => [
                'page' => $page,
                'pages' => $pages,
                'items' => $items,
                'online' => $online
            ]
        ];
    }

    /**
     * Recupera los mensajes de un chat individual o grupal
     * Es una petición GET el url que contiene el ID encriptado del chat (/chat/get-all-messages/:id) y la cuál se recibe en la función heartBeat.
     * En caso de una respuesta positiva
     * [
     *      'success' => true,
     *      'data' => [
     *          'page' => 'entero número de página actúal',
     *          'pages' => 'entero número total de páginaS',
     *              'items' => [
     *              'user_name' => 'nombre del usuario que envia',
     *              'user_id_encript' => 'id encriptado del usuario que envia',
     *              'user_image' => 'ruta de la imagén del usuario que envia',
     *              'u' => '1 = si el usuario que envia es el usuario actual , 2 si no lo es',
     *              'mtype' => 'text | file',
     *              'm' => 'texto del mensaje o url del archivo',
     *              'time' => 'cadena que da el tiempo del mensaje ejemplo 1seg',
     *          ],
     *          'online' => 'true/false'
     *      ]
     * ]
     * En caso de un respuesta negativa
     * [
     *      'success' => false,
     *      'data' => (string) 'mensaje_de_error'
     * ]
     * @return \Laminas\View\Model\JsonModel
     */
    public function getAllMessagesAction()
    {
        
        $request    = $this->getRequest();
        if($request->isGet()) {
            $currentUserPlugin = $this->plugin('currentUserPlugin');
            $currentUser = $currentUserPlugin->getUser();
            
        
            $id     = $this->params()->fromRoute('id');
            $page   = filter_var($this->params()->fromQuery('page', 0), FILTER_SANITIZE_NUMBER_INT);
            
            if(!$id) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_PARAMETERS_ARE_INVALID'
                ]);
            }
        
            /**** Mensajes de un chat grupal ****/
            $chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);
            $chatGroup = $chatGroupMapper->fetchOneByUuid($id);
            if ($chatGroup) {
                $response = $this->getAllMessagesForChatGroup($chatGroup, $page);
                return new JsonModel($response);
            } else {
                
                $userMapper = UserMapper::getInstance($this->adapter);
                $user = $userMapper->fetchOneByUuid($id);
                if(!$user) {
                    return new JsonModel([
                        'success' => false,
                        'data' => 'ERROR_USER_NOT_FOUND'
                    ]);
                }
                
                
                
                
                

                $connectionMapper = ConnectionMapper::getInstance($this->adapter);
                $connection = $connectionMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);
                if(!$connection || $connection->status != Connection::STATUS_ACCEPTED) {
                    
                    return new JsonModel([
                        'success' => false,
                        'data' => 'ERROR_THIS_USER_IS_NOT_A_CONNECTION'
                    ]);
                    
                }
                $chatUserMapper = ChatUserMapper::getInstance($this->adapter);
                $chatUser = $chatUserMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);
                if(!$chatUser) {
                    $chatUser = new ChatUser();
                    $chatUser->user_id1 = $currentUser->id;
                    $chatUser->user_id2 = $user->id;
                            
                    $response = $chatUserMapper->insert($chatUser);
                    
                    
                    if(!$response) {
                        return new JsonModel([
                            'success' => false,
                            'data' => $chatUserMapper->getError()
                        ]);
                    }
                    
                    $chatUser = $chatUserMapper->fetchOne($chatUser->id);
                    $fullpath_chat = $this->config['leaderslinked.fullpath.chat'];
                    $dirpath = $fullpath_chat . $chatUser->uuid;
                    if (! file_exists($dirpath)) {
                        mkdir($dirpath, 0777, true);
                        chmod($dirpath, 0777);
                    }
                            
                }
                
    
                
                $response = $this->getAllMessagesForChatUser($chatUser, $page);
                return new JsonModel($response);
                
            }
        
        } else {
            return new JsonModel([
                'success' => false,
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
            ]);
        }

    }

    /**
     * Envia un mensaje a un chat individual o grupal
     * Es una petición POST el url que contiene el ID encriptado del chat (/chat/send/:id) y la cuál se recibe en la función heartBeat.
     * Parámetros del route
     * :id = id del chat encriptado
     * Como parámentro solo se espera un campo
     * message: string
     * En caso de una respuesta positiva
     * [
     *      'success' => true,
     *      'user_name' => 'nombre del usuario que envia',
     *      'user_id_encripted' => 'id encriptado del usuario que envia',
     *      'user_image' => 'ruta de la imagén del usuario que envia',
     *      'u' => '1 = si el usuario que envia es el usuario actual , 2 si no lo es',
     *      'mtype' => 'text | file',
     *      'm' => 'texto del mensaje o url del archivo',
     *      'time' => 'cadena que da el tiempo del mensaje ejemplo 1seg',
      * ]
     * En caso de un respuesta negativa
     * [
     *      'success' => false,
     *      'data' => (string) 'mensaje_de_error'
     * ]
     * @return \Laminas\View\Model\JsonModel
     */
    public function sendAction()
    {
        
        $request    = $this->getRequest();
        if($request->isPost()) {
            $id         = $this->params()->fromRoute('id');
            $message    = trim(filter_var($this->params()->fromPost('message', ''), FILTER_SANITIZE_STRING));
            
            if(!$id || empty($message)) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_PARAMETERS_ARE_INVALID'
                ]);
            } 
            
            $currentUserPlugin = $this->plugin('currentUserPlugin');
            $currentUser = $currentUserPlugin->getUser();
            
            $userMapper = UserMapper::getInstance($this->adapter);
            $sender_result = $userMapper->fetchOne($currentUser->id);
            $sender_name = trim($sender_result->first_name . ' ' . $sender_result->last_name);
            $sender_pic = $this->url()->fromRoute('storage', [
                'code' => $sender_result->uuid,
                'type' => 'user',
                'filename' => $sender_result->image
            ]);
                
            $chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);
            $chatGroup = $chatGroupMapper->fetchOneByUuid($id);
            if($chatGroup) {
                
                $chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);
                $chatGroupUser = $chatGroupUserMapper->fetchOneByGroupIdAndUserId($chatGroup->id, $currentUser->id);
                
                if(!$chatGroupUser) {
                    return new JsonModel([
                        'success' => false,
                        'data' => 'ERROR_CHAT_GROUP_YOU_NOT_MEMBER'
                    ]);
                }
                
                $chatGroupMessage = new ChatGroupMessage();
                $chatGroupMessage->sender_id = $currentUser->id;
                $chatGroupMessage->group_id = $chatGroup->id;
                $chatGroupMessage->content = $message;
                $chatGroupMessage->type = ChatGroupMessage::TYPE_TEXT;
                
                $chatGroupMessageMapper = ChatGroupMessageMapper::getInstance($this->adapter);
                $result = $chatGroupMessageMapper->insert($chatGroupMessage);
                if(!$result) {
                    return new JsonModel([
                        'success' => false,
                        'data' => $chatGroupMessageMapper->getError()
                    ]);
                }
                $chatGroupMessage = $chatGroupMessageMapper->fetchOne($chatGroupMessage->id);

                    
                $chatGroupUserMessage = new ChatGroupUserMessage();
                $chatGroupUserMessage->group_id = $chatGroupMessage->group_id;
                $chatGroupUserMessage->message_id = $chatGroupMessage->id;
                $chatGroupUserMessage->receiver_id = $currentUser->id;
                $chatGroupUserMessage->recd = ChatGroupUserMessage::RECD_YES;
                $chatGroupUserMessage->seen = ChatGroupUserMessage::SEEN_NO;
                    
                $chatGroupUserMessageMapper = ChatGroupUserMessageMapper::getInstance($this->adapter);
                $result = $chatGroupUserMessageMapper->insert($chatGroupUserMessage);
                if(!$result) {
                    return new JsonModel([
                        'success' => false,
                        'data' => $chatGroupUserMessageMapper->getError()
                    ]);
                }
                
      
                $results = $chatGroupUserMapper->fetchAllByGroupId($chatGroup->id);
                foreach ($results as $r) 
                {
                    if ($r->user_id != $currentUser->id) {
                        $chatGroupUserMessage               = new ChatGroupUserMessage();
                        $chatGroupUserMessage->group_id     = $chatGroupMessage->group_id;
                        $chatGroupUserMessage->message_id   = $chatGroupMessage->id;
                        $chatGroupUserMessage->receiver_id  = $r->user_id;
                        $chatGroupUserMessage->recd         = ChatGroupUserMessage::RECD_NO;
                        $chatGroupUserMessage->seen         = ChatGroupUserMessage::SEEN_NO;
                            
                        $result = $chatGroupUserMessageMapper->insert($chatGroupUserMessage);
                        if(!$result) {
                            return new JsonModel([
                                'success' => false,
                                'data' => $chatGroupUserMessageMapper->getError()
                            ]);
                        }
                    }
                }
                    
                $msgtime = $this->timeAgo(date('Y-m-d H:i:s'));
                return new JsonModel([
                    'success' => true,
                    'data' => [
                        'user_name'         => $sender_name,
                        'user_id_encripted' => $sender_result->uuid,
                        'user_image'        => $sender_pic,
                        'u'                 => 1,
                        'mtype'             => 'text',
                        'm'                 => $message,
                        'time'              => $msgtime,
                        'id'                => $chatGroupMessage->uuid,
                    ]
                ]);

                
                
            } else {
                $userMapper = UserMapper::getInstance($this->adapter);
                $user = $userMapper->fetchOneByUuid($id);
                if(!$user) {
                    return new JsonModel([
                        'success' => false,
                        'data' => 'ERROR_USER_NOT_FOUND'
                    ]);
                }
                
                
                $connectionMapper = ConnectionMapper::getInstance($this->adapter);
                $connection = $connectionMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);
                if(!$connection || $connection->status != Connection::STATUS_ACCEPTED) {
                    
                    return new JsonModel([
                        'success' => false,
                        'data' => 'ERROR_THIS_USER_IS_NOT_A_CONNECTION'
                    ]);
                    
                }
                $chatUserMapper = ChatUserMapper::getInstance($this->adapter);
                $chatUser = $chatUserMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);
                if(!$chatUser) {
                    $chatUser = new ChatUser();
                    $chatUser->user_id1 = $currentUser->id;
                    $chatUser->user_id2 = $user->id;
                    
                    $response = $chatUserMapper->insert($chatUser);
                    if(!$response) {
                        return new JsonModel([
                            'success' => false,
                            'data' => $chatUserMapper->getError()
                        ]);
                    }
                    
                    $chatUser = $chatUserMapper->fetchOne($chatUser->id);
                    $fullpath_chat = $this->config['leaderslinked.fullpath.chat'];
                    $dirpath = $fullpath_chat . $chatUser->uuid;
                    if (! file_exists($dirpath)) {
                        mkdir($dirpath, 0777, true);
                        chmod($dirpath, 0777);
                    }
                    
                }
                
      
    
                $chatMessage = new ChatMessage();
                $chatMessage->chat_id   = $chatUser->id;
                $chatMessage->from_id   = $currentUser->id;
                $chatMessage->to_id     = $user->id;
                $chatMessage->content   = $message;
                $chatMessage->type      = ChatMessage::TYPE_TEXT;
                $chatMessage->recd      = ChatMessage::RECD_NO;
                $chatMessage->seen      = ChatMessage::SEEN_NO;
                        
                $chatMessageMapper = ChatMessageMapper::getInstance($this->adapter);
                $result = $chatMessageMapper->insert($chatMessage);
                if(!$result) {
                    return new JsonModel([
                        'success' => false,
                        'data' => $chatMessageMapper->getError()
                    ]);
                }
                
                $chatMessage = $chatMessageMapper->fetchOne($chatMessage->id);
 
                $msgtime = $this->timeAgo(date('Y-m-d H:i:s'));
                return new JsonModel([
                    'success' => true,
                    'data' => [
                        'user_name'     => $sender_name,
                        'user_id'       => $sender_result->uuid,
                        'user_image'    => $sender_pic,
                        'u'             => 1,
                        'mtype'         => ChatMessage::TYPE_TEXT,
                        'm'             => $message,
                        'time'          => $msgtime,
                        'id'            => $chatMessage->uuid,
                    ]
                 ]); 

                
            }
            return new JsonModel($response);
        
        } else {
            return new JsonModel([
                'success' => false,
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
            ]);
        }

    }
    
    /**
     * Esta función recuperar los contactos disponibles para agregarlos a un grupo
     * Es una petición GET el url que contiene el ID encriptado del chat (/chat/get-contacts-availables-for-group/:group_id) y la cuál se recibe en la función heartBeat.
     * con el siguiente parámetro
     * uid = id encriptado del usuario
     * retorna un json en caso de ser  positivo
     * [
     *  'success' : true,
     *  'data' : [
     *     [
     *       'id'                    => 'id del usuario encriptado',
     *       'name'                  => 'nombre del usuario',
     *       'image'                 => 'imagen del usuario',
     *       'type'                  => 'user' //fixed,
     *       'online'                => $online,
     *     ]
     * ]
     * En caso de ser negativo puede haber 2 formatos
     * [
     *  'success' : false,
     *  'data' : mensaje de error
     * ]
     * @return \Laminas\View\Model\JsonModel
     */
    public function contactAvailableGroupListAction()
    {
        $request    = $this->getRequest();
        if($request->isGet()) {
            $currentUserPlugin = $this->plugin('currentUserPlugin');
            $currentUser = $currentUserPlugin->getUser();
            
            $id = $this->params()->fromRoute('group_id');
            if(!$id) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_PARAMETERS_ARE_INVALID'
                ]);
            } 
            
            $userMapper = UserMapper::getInstance($this->adapter);
            $chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);
            $chatGroup = $chatGroupMapper->fetchOneByUuid($id);
            
            if(!$chatGroup) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_GROUP_NOT_FOUND'
                ]);
            }
                
            $chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);
            $chatGroupOwner = $chatGroupUserMapper->fetchOwnerByGroupId($chatGroup->id);
            
            if($chatGroupOwner->user_id != $currentUser->id) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_CHAT_GROUP_YOU_ARE_NOT_OWNER'
                ]);
            }
            
            
                
            $contact_ids = [];
            $contacts = $chatGroupUserMapper->fetchAllByGroupId($chatGroup->id);
            foreach($contacts as $contact) 
            {
                array_push($contact_ids, $contact->user_id);
            }
                
            $connectionMapper = ConnectionMapper::getInstance($this->adapter);
            $connection_ids = $connectionMapper->fetchAllConnectionsByUserReturnIds($currentUser->id);
            $connection_ids = array_filter($connection_ids, function($var) use ( $contact_ids) {
                return !in_array($var, $contact_ids); 
            });
                
                
            $items = [];
            foreach ($connection_ids as $connection_id)
            {
                $user = $userMapper->fetchOne($connection_id);
                if (! $user) {
                    continue;
                }
                    
                $name   = trim($user->first_name . ' ' . $user->last_name);
                $image  = $this->url()->fromRoute('storage', [
                    'code' => $user->uuid,
                    'type' => 'user',
                    'filename' => $user->image
                ]);

                    
                if ($this->isInactiveConnection($user->last_heart_beat_at ? $user->last_heart_beat_at : '')) {
                    $userMapper->updateChatOfflineStatus($user->id);
                    $online = false;
                } else {
                    $online = true;
                }
                

                array_push($items, [
                    'id'        => $user->uuid,
                    'name'      => $name,
                    'image'     => $image,
                    'online'    => $online,
                ]);
            } 
            
            
            return new JsonModel([
                'success' => true,
                'data' => $items,
            ]);
            
        } else {
            return new JsonModel([
                'success' => false,
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
            ]);
        }

    }

    /**
     * Esta función recuperar los contactos de un grupo
     * Es una petición GET el url que contiene el ID encriptado del chat (/chat/get-contact-group-list/:group_id) y la cuál se recibe en la función heartBeat.
     * con el siguiente parámetro
     * uid = id encriptado del usuario
     * retorna un json en caso de ser  positivo
     * [
     *  'success' : true,
     *  'data' : [
     *     [
     *       'url_remove_from_group' => 'url para remover el usuario del grupo',
     *       'id'                    => 'id del usuario encriptado',
     *       'name'                  => 'nombre del usuario',
     *       'image'                 => 'imagen del usuario',
     *       'type'                  => 'user' //fixed,
     *       'online'                => $online,
     *     ]
     * ]
     * En caso de ser negativo puede haber 2 formatos
     * [
     *  'success' : false,
     *  'data' : mensaje de error
     * ]
     * o
     * [
     *  'success' : false,
     *  'data' : [
     *      'fieldname' : [
     *          'mensaje de error'
     *      ]
     *  ]
     * ]
     * @return \Laminas\View\Model\JsonModel
     */

    public function contactGroupListAction()
    {
        
        $request    = $this->getRequest();
        if($request->isGet()) {
            $currentUserPlugin = $this->plugin('currentUserPlugin');
            $currentUser = $currentUserPlugin->getUser();
    
            $id = $this->params()->fromRoute('group_id');
            if(!$id) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_PARAMETERS_ARE_INVALID'
                ]);
            } 
            
            $userMapper = UserMapper::getInstance($this->adapter);
            $chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);
            $chatGroup = $chatGroupMapper->fetchOneByUuid($id);
            
            if(!$chatGroup) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_GROUP_NOT_FOUND'
                ]);
            }
            
            $chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);
            
            $chatGroupUser = $chatGroupUserMapper->fetchOneByGroupIdAndUserId($chatGroup->id, $currentUser->id);
            
            if(!$chatGroupUser) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_CHAT_GROUP_USER_NOT_FOUND'
                ]);
            }

            $items = [];
            $chatGroupUsers = $chatGroupUserMapper->fetchAllByGroupId($chatGroup->id);
            foreach ($chatGroupUsers as $chatGroupUser) 
            {
                $user = $userMapper->fetchOne((int) $chatGroupUser->user_id);
                if (! $user) {
                    continue;
                }
                    
                $name   = trim($user->first_name . ' ' . $user->last_name);
                $image  = $this->url()->fromRoute('storage', [
                    'code' => $user->uuid,
                    'type' => 'user',
                    'filename' => $user->image
                ]);
                    
     
                if($chatGroupUser->owner == ChatGroupUser::OWNER_YES) {
                    $url_remove_from_group = '';
                    
                } else {
                    $url_remove_from_group = $this->url()->fromRoute('chat/remove-user-from-group', ['group_id' => $chatGroup->uuid, 'user_id' => $user->uuid ]);
                }
                    

                if ($this->isInactiveConnection($user->last_heart_beat_at ? $user->last_heart_beat_at : '')) {
                    $userMapper->updateChatOfflineStatus($user->id);
                    $online = false;
                } else {
                    $online = true;
                }
                    
                array_push($items, [
                    'url_remove_from_group' => $url_remove_from_group,
                    'id'                    => $user->uuid,
                    'name'                  => $name,
                    'image'                 => $image,
                    'online'                => $online,
                ]);
                    
            }
                
            return new JsonModel([
                'success' => true, 
                'data' => $items,
            ]);
        
        } else {
            return new JsonModel([
                'success' => false,
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
            ]);
        }
    }
    
    /**
     * Elimina un grupo de chat, solo el owner puede realizarla
     * Es una petición POST el url que contiene el ID encriptado del chat (/chat/delete-group/:group_id) y la cuál se recibe en la función heartBeat.
     * Parámetros del route
     * :group_id = id del grupo encriptado
     * En caso de una respuesta positiva
     * [
     *      'success' => true,
     *      'data'=> (int) registros_borrados
     * ]
     * En caso de un respuesta negativa
     * [
     *      'success' => false,
     *      'data' => (string) 'mensaje_de_error'
     * ]
     * @return \Laminas\View\Model\JsonModel
     */
    public function deleteGroupAction()
    {
        
        $request    = $this->getRequest();
        if($request->isPost()) {

            $currentUserPlugin = $this->plugin('currentUserPlugin');
            $currentUser = $currentUserPlugin->getUser();
    
            $id = trim(filter_var($this->params()->fromRoute('group_id'), FILTER_SANITIZE_STRING));
            if(!$id) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_PARAMETERS_ARE_INVALID'
                ]);
            } 
            
    

            $chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);
            $chatGroup = $chatGroupMapper->fetchOneByUuid($id);
            
            if(!$chatGroup) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_GROUP_NOT_FOUND'
                ]);
            }
            
            $chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);
            $chatGroupOwner = $chatGroupUserMapper->fetchOwnerByGroupId($chatGroup->id);
            
            if($chatGroupOwner->user_id != $currentUser->id) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_CHAT_GROUP_YOU_ARE_NOT_OWNER'
                ]);
            }


            $chatGroupUserMessageMapper = ChatGroupUserMessageMapper::getInstance($this->adapter);
            $result = $chatGroupUserMessageMapper->deleteAllByGroupId($chatGroup->id);
            if(!$result) {
                return new JsonModel([
                    'success' => false,
                    'data' => $chatGroupUserMessageMapper->getError()
                ]);
            }
            
            $chatGroupMessageMapper = ChatGroupMessageMapper::getInstance($this->adapter);
            $result = $chatGroupMessageMapper->deleteAllByGroupId($chatGroup->id);
            if(!$result) {
                return new JsonModel([
                    'success' => false,
                    'data' => $chatGroupMessageMapper->getError()
                ]);
            }
            
            $chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);
            $result = $chatGroupUserMapper->deleteAllByGroupId($chatGroup->id);
            if(!$result) {
                return new JsonModel([
                    'success' => false,
                    'data' => $chatGroupUserMapper->getError()
                ]);
            }
            
            $chatGroupMapper->deleteByGroupId($chatGroup->id);
            if(!$result) {
                return new JsonModel([
                    'success' => false,
                    'data' => $chatGroupMapper->getError()
                ]);
            }
           
                    
            $fullpath_chat = $this->config['leaderslinked.fullpath.chat'];
            $dirpath = $fullpath_chat . $chatGroup->uuid;
                        
            Functions::rmDirRecursive($dirpath);
                        
            return new JsonModel([
                'success' => true
            ]);


        } else {
            return new JsonModel([
                'success' => false,
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
            ]);
            
        }
    }

    /**
     * Cerrar el chat, consiste en borrar de la variable de sessión para que el mismo no se presente la siguiente vez abierto , 
     * al menos que tenga mensajes sin leer 
     * Es una petición POST el url que contiene el ID encriptado del chat (/chat/close/:id)  y la cuál se recibe en la función heartBeat.
     * Parámetros del route
     * :id = id del chat encriptado
     * En caso de una respuesta positiva 
     * [
     *  'success' => true
     * ]
     * En caso de un respuesta negativa
     * [
     *  'success' => false,
     *  'data'  => mensaje_de_error
     * ]
     * @return \Laminas\View\Model\JsonModel
     */
    public function closeAction()
    {
        $request    = $this->getRequest();
        if($request->isPost()) {
            $currentUserPlugin = $this->plugin('currentUserPlugin');
            $currentUser = $currentUserPlugin->getUser();
            
            $id = filter_var($this->params()->fromRoute('id'), FILTER_SANITIZE_STRING);
            
            if (!$id) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_PARAMETERS_ARE_INVALID'
                ]);
            }
            
            $uuid = '';
            
            $chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);
            $chatGroup = $chatGroupMapper->fetchOneByUuid($id);
            if ($chatGroup) {
                $uuid = $chatGroup->uuid;
            } else {
                
                $userMapper = UserMapper::getInstance($this->adapter);
                $user = $userMapper->fetchOneByUuid($id);
                if(!$user) {
                    return new JsonModel([
                        'success' => false,
                        'data' => 'ERROR_USER_NOT_FOUND'
                    ]);
                }
                
                
                $chatUserMapper = ChatUserMapper::getInstance($this->adapter);
                $chatUser = $chatUserMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);
                if($chatUser) {
                    $uuid = $chatUser->uuid;
                }
            }
            
            if($uuid) {
                $_SESSION[self::SESSION_CHAT_OPEN_BOXES] = array_filter($_SESSION[self::SESSION_CHAT_OPEN_BOXES], function($var) use($uuid)  {
                    return $uuid != $var;
                });
            }
              
            return new JsonModel([
                'success' => true
            ]);
        } else {
            return new JsonModel([
                'success' => false,
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
            ]);
        }
    }

    /**
     * Clear como su nombre lo indica es borrar los mensajes entre el usuario actual y otro usuario con quien sostiene el chat
     * Es una petición POST el url que contiene el ID encriptado del chat (/chat/clear/:id) y la cuál se recibe en la función heartBeat.
     * Parámetros del route
     * :id = id del usuario encriptado
     * En caso de una respuesta positiva 
     * [    
     *      'success' => true, 
     *      'data'=> (int) registros_borrados
     * ]  
     * En caso de un respuesta negativa
     * [
     *      'success' => false, 
     *      'data' => (string) 'mensaje_de_error'
     * ]
     * @return \Laminas\View\Model\JsonModel
     */
    public function clearAction()
    {
        $request    = $this->getRequest();
        if($request->isPost()) {
            $currentUserPlugin = $this->plugin('currentUserPlugin');
            $currentUser = $currentUserPlugin->getUser();
            
            $id = filter_var($this->params()->fromRoute('id'), FILTER_SANITIZE_STRING);
            
            if (!$id) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_PARAMETERS_ARE_INVALID'
                ]);
            }
            
            $uuid = '';
            
            $chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);
            $chatGroup = $chatGroupMapper->fetchOneByUuid($id);
            if ($chatGroup) {
                $uuid = $chatGroup->uuid;
            } else {
                
                $userMapper = UserMapper::getInstance($this->adapter);
                $user = $userMapper->fetchOneByUuid($id);
                if(!$user) {
                    return new JsonModel([
                        'success' => false,
                        'data' => 'ERROR_USER_NOT_FOUND'
                    ]);
                }
                
                
                $chatUserMapper = ChatUserMapper::getInstance($this->adapter);
                $chatUser = $chatUserMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);
                if($chatUser) {
                    $uuid = $chatUser->uuid;
                }
            }
            
            if($uuid) {
                $_SESSION[self::SESSION_CHAT_OPEN_BOXES] = array_filter($_SESSION[self::SESSION_CHAT_OPEN_BOXES], function($var) use($uuid)  {
                    return $uuid != $var;
                });
            }
            
            return new JsonModel([
                'success' => true
            ]);
        } else {
            return new JsonModel([
                'success' => false,
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
            ]);
        }
    }
    
    public function uploadAction()
    {
        $request    = $this->getRequest();
        if($request->isPost()) {
            $currentUserPlugin = $this->plugin('currentUserPlugin');
            $currentUser = $currentUserPlugin->getUser();
            
            $id = filter_var($this->params()->fromRoute('id'), FILTER_SANITIZE_STRING);
            if (!$id) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_PARAMETERS_ARE_INVALID'
                ]);
            }
            
            $files = $this->getRequest()->getFiles()->toArray();
            if(!isset($files['file']) || !empty($files['file']['error'])) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_FILE_NOT_UPLOAD'
                ]);
            }
            
            $tmp_filename   = $files['file']['tmp_name'];
            if(!$this->validMimeType($tmp_filename)) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_FILE_UPLODED_IS_NOT_VALID'
                ]);
            }

            
            $extensions     = explode('.', $files['file']['name']);
            $extension      = strtolower(trim($extensions[count($extensions) - 1]));
            $filename       = uniqid() . '.' . $extension;
           

            $mime_type = mime_content_type($tmp_filename);
            if($mime_type == 'image/jpg' || $mime_type == 'image/jpeg' || $mime_type == 'image/png') {
                $file_type = 'image';
            } else if($mime_type == 'video/webm' || $mime_type == 'video/mpeg' || $mime_type == 'video/mpg' || $mime_type == 'video/mp4') {
                $file_type = 'video';
            } else if($mime_type == 'application/pdf') {
                $file_type = 'document';
            }
            
                
            $userMapper = UserMapper::getInstance($this->adapter);
            $sender_result = $userMapper->fetchOne($currentUser->id);
            $sender_from = trim($sender_result->first_name . ' ' . $sender_result->last_name);
            $sender_pic = $this->url()->fromRoute('storage', [
                'code' => $sender_result->uuid,
                'type' => 'user',
                'filename' => $sender_result->image
            ]);
            
            $chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);
            $chatGroup = $chatGroupMapper->fetchOneByUuid($id);
            if($chatGroup) {
                
                $chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);
                $chatGroupUser = $chatGroupUserMapper->fetchOneByGroupIdAndUserId($chatGroup->id, $currentUser->id);
                
                if(!$chatGroupUser) {
                    return new JsonModel([
                        'success' => false,
                        'data' => 'ERROR_CHAT_GROUP_YOU_NOT_MEMBER'
                    ]);
                }

        
                $fullpath_chat = $this->config['leaderslinked.fullpath.chat'];
                $dirpath = $fullpath_chat . $chatGroup->uuid;
                if (! file_exists($dirpath)) {
                    mkdir($dirpath, 0777, true);
                    chmod($dirpath, 0777);
                }
                    
                $full_filename = $dirpath . DIRECTORY_SEPARATOR . $filename;
                if(!move_uploaded_file($tmp_filename, $full_filename)) {
                    return new JsonModel([
                        'success' => false,
                        'data' => 'ERROR_FILE_UPLOADED_NOT_MOVE'
                    ]);
                }
                
                $chatGroupMessage = new ChatGroupMessage();
                $chatGroupMessage->sender_id    = $currentUser->id;
                $chatGroupMessage->group_id     = $chatGroup->id;
                $chatGroupMessage->content      = $filename;
                $chatGroupMessage->type         = $file_type;
                
                $chatGroupMessageMapper = ChatGroupMessageMapper::getInstance($this->adapter);
                $result = $chatGroupMessageMapper->insert($chatGroupMessage);
                if(!$result) {
                    return new JsonModel([
                        'success' => false,
                        'data' => $chatGroupMessageMapper->getError()
                    ]);
                }
                
                $chatGroupMessage = $chatGroupMessageMapper->fetchOne($chatGroupMessage->id);
                
                        
                $chatGroupUserMessage = new ChatGroupUserMessage();
                $chatGroupUserMessage->group_id = $chatGroupMessage->group_id;
                $chatGroupUserMessage->message_id = $chatGroupMessage->id;
                $chatGroupUserMessage->receiver_id = $currentUser->id;
                $chatGroupUserMessage->recd = ChatGroupUserMessage::RECD_YES;
                $chatGroupUserMessage->seen = ChatGroupUserMessage::SEEN_YES;
                
                            
                $chatGroupUserMessageMapper = ChatGroupUserMessageMapper::getInstance($this->adapter);
                $result = $chatGroupUserMessageMapper->insert($chatGroupUserMessage);
                if(!$result) {
                    return new JsonModel([
                        'success' => false,
                        'data' => $chatGroupUserMessageMapper->getError()
                    ]);
                }
                
          
                
                $chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);
                            
                $results = $chatGroupUserMapper->fetchAllByGroupId($chatGroup->id);
                foreach ($results as $r) 
                {
                    if ($r->user_id != $currentUser->id) {
                        $chatGroupUserMessage = new ChatGroupUserMessage();
                        $chatGroupUserMessage->group_id = $chatGroupMessage->group_id;
                        $chatGroupUserMessage->message_id = $chatGroupMessage->id;
                        $chatGroupUserMessage->receiver_id= $r->user_id;
                        $chatGroupUserMessage->recd = ChatGroupUserMessage::RECD_NO;
                        $chatGroupUserMessage->seen = ChatGroupUserMessage::SEEN_NO;
                                    
                        $result = $chatGroupUserMessageMapper->insert($chatGroupUserMessage);
                        if(!$result) {
                            return new JsonModel([
                                'success' => false,
                                'data' => $chatGroupUserMessageMapper->getError()
                            ]);
                        }
                        
             
                    }
                }
                            
                $msgtime = $this->timeAgo(date('Y-m-d H:i:s'));
                return new JsonModel([
                    'success' => true,
                    'data' => [
                        'user_name'     => $sender_from,
                        'user_id'       => $currentUser->uuid,
                        'user_image'    => $sender_pic,
                        'u'             => 1,
                        'mtype'         => $file_type,
                        'm'             => $this->url()->fromRoute('storage', ['code' => $chatGroup->uuid, 'type' => 'chat', 'filename' => $filename]),
                        'time'          => $msgtime,
                        'id'            => $chatGroupMessage->uuid
                    ]
                ]);

                
            } else {
                
                $user = $userMapper->fetchOneByUuid($id);
                if(!$user) {
                    return new JsonModel([
                        'success' => false,
                        'data' => 'ERROR_USER_NOT_FOUND'
                    ]);
                }
                
                $chatUserMapper = ChatUserMapper::getInstance($this->adapter);
                $chatUser = $chatUserMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);
                if(!$chatUser) {
                    return new JsonModel([
                        'success' => false,
                        'data' => 'ERROR_CHAT_NOT_FOUND'
                    ]);
                }
                        
                $fullpath_chat = $this->config['leaderslinked.fullpath.chat'];
                $dirpath = $fullpath_chat . $chatUser->uuid;
                        
                if (! file_exists($dirpath)) {
                    mkdir($dirpath, 0777, true);
                    chmod($dirpath, 0777);
                }
                        
                $full_filename = $dirpath . DIRECTORY_SEPARATOR . $filename;
                if(!move_uploaded_file($tmp_filename, $full_filename)) {
                    return new JsonModel([
                        'success' => false,
                        'data' => 'ERROR_FILE_UPLOADED_NOT_MOVE'
                    ]);
                }

                $chatMessage = new ChatMessage();
                $chatMessage->chat_id = $chatUser->id;
                $chatMessage->from_id = $currentUser->id;
                $chatMessage->to_id = $user->id;
                $chatMessage->content = $filename;
                $chatMessage->type = $file_type;
                $chatMessage->recd = ChatMessage::RECD_NO;
                $chatMessage->seen = ChatMessage::SEEN_NO;
                            
                            
                $chatMessageMapper = ChatMessageMapper::getInstance($this->adapter);
                $result = $chatMessageMapper->insert($chatMessage);
                if(!$result) {
                    return new JsonModel([
                        'success' => false,
                        'data' =>  $chatMessageMapper->getError()
                    ]);
                }
                
                $chatMessage = $chatMessageMapper->fetchOne($chatMessage->id);
                
                
                $msgtime = $this->timeAgo(date('Y-m-d H:i:s'));
                return new JsonModel([
                    'success' => true,
                    'data' => [
                        'user_name' => $sender_from,
                        'user_id' => $currentUser->uuid,
                        'user_image' => $sender_pic,
                        'u' => 1,
                        'mtype' => $file_type,
                        'm' => $this->url()->fromRoute('storage', ['code' => $currentUser->uuid, 'type' => 'chat', 'filename' => $filename]),
                        'time' => $msgtime,
                        'id' => $chatMessage->uuid
                    ]
                ]);

            }
        } else {
            return new JsonModel([
                'success' => false,
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
            ]);
        }
    }

    public function markSeenAction()
    {
        $request = $this->getRequest();
        if($request->isPost()) { 
            $currentUserPlugin = $this->plugin('currentUserPlugin');
            $currentUser = $currentUserPlugin->getUser();
            
            $id = $this->params()->fromRoute('id');
            if (!$id) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_PARAMETERS_ARE_INVALID'
                ]);
            }
            
            $chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);
            $chatGroup =  $chatGroupMapper->fetchOneByUuid($id);
            
            if($chatGroup) {
                
                $charGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);
                $chatGroupUser = $charGroupUserMapper->fetchOneByGroupIdAndUserId($chatGroup->id, $currentUser->id);
                
                if(!$chatGroupUser) {
                    return new JsonModel([
                        'success' => false,
                        'data' =>  'ERROR_CHAT_GROUP_YOU_NOT_MEMBER'
                    ]);
                }
                
                $charGroupUserMessage = ChatGroupUserMessageMapper::getInstance($this->adapter);
                $result = $charGroupUserMessage->markAsSeenByGroupIdAndUserId($chatGroup->id, $currentUser->id);
                if($result) {
                    return new JsonModel([
                        'success' => true,
                    ]);
                } else {
                    return new JsonModel([
                        'success' => false,
                        'data' =>  $charGroupUserMessage->getError()
                    ]);
                }
                
                
            } else {
                $userMapper = UserMapper::getInstance($this->adapter);
                $user = $userMapper->fetchOneByUuid($id);
                
                if(!$user) {
                    return new JsonModel([
                        'success' => false,
                        'data' => 'ERROR_USER_NOT_FOUND'
                    ]);
                }
                
                $chatUserMapper = ChatUserMapper::getInstance($this->adapter);
                $chatUser = $chatUserMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);
                if(!$chatUser) {
                    return new JsonModel([
                        'success' => false,
                        'data' => 'ERROR_CHAT_NOT_FOUND'
                    ]);
                }
                
                $chatMessageMapper = ChatMessageMapper::getInstance($this->adapter);
                $result = $chatMessageMapper->markAsSeenByChatIdAndToId($chatUser->id, $currentUser->id);
                if($result) {
                    return new JsonModel([
                        'success' => true,
                    ]);
                } else {
                    return new JsonModel([
                        'success' => false,
                        'data' =>  $charGroupUserMessage->getError()
                    ]);
                }
                
            }

            
        } else {
            $response = [
                'success' => false,
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
            ];
        }

        return new JsonModel($response);
    }
    
    
    public function markReceivedAction()
    {
        $request = $this->getRequest();
        if($request->isPost()) {
            $currentUserPlugin = $this->plugin('currentUserPlugin');
            $currentUser = $currentUserPlugin->getUser();
            
            $id = $this->params()->fromRoute('id');
            if (!$id) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_PARAMETERS_ARE_INVALID'
                ]);
            }
            
            $chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);
            $chatGroup =  $chatGroupMapper->fetchOneByUuid($id);
            
            if($chatGroup) {
                
                $charGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);
                $chatGroupUser = $charGroupUserMapper->fetchOneByGroupIdAndUserId($chatGroup->id, $currentUser->id);
                
                if(!$chatGroupUser) {
                    return new JsonModel([
                        'success' => false,
                        'data' =>  'ERROR_CHAT_GROUP_YOU_NOT_MEMBER'
                    ]);
                }
                
                $charGroupUserMessage = ChatGroupUserMessageMapper::getInstance($this->adapter);
                $result = $charGroupUserMessage->markAsReceivedByGroupIdAndUserId($chatGroup->id, $currentUser->id);
                if($result) {
                    return new JsonModel([
                        'success' => true,
                    ]);
                } else {
                    return new JsonModel([
                        'success' => false,
                        'data' =>  $charGroupUserMessage->getError()
                    ]);
                }
                
                
            } else {
                $userMapper = UserMapper::getInstance($this->adapter);
                $user = $userMapper->fetchOneByUuid($id);
                
                if(!$user) {
                    return new JsonModel([
                        'success' => false,
                        'data' => 'ERROR_USER_NOT_FOUND'
                    ]);
                }
                
                $chatUserMapper = ChatUserMapper::getInstance($this->adapter);
                $chatUser = $chatUserMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);
                if(!$chatUser) {
                    return new JsonModel([
                        'success' => false,
                        'data' => 'ERROR_CHAT_NOT_FOUND'
                    ]);
                }
                
                $chatMessageMapper = ChatMessageMapper::getInstance($this->adapter);
                $result = $chatMessageMapper->markAsReceivedByChatIdAndToId($chatUser->id, $currentUser->id);
                if($result) {
                    return new JsonModel([
                        'success' => true,
                    ]);
                } else {
                    return new JsonModel([
                        'success' => false,
                        'data' =>  $charGroupUserMessage->getError()
                    ]);
                }
                
            }
            
            
        } else {
            $response = [
                'success' => false,
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
            ];
        }
        
        return new JsonModel($response);
    }


   
    /**
     * 
     * @param string $file
     * @return boolean
     */
    private function validMimeType($file)
    {
        /*
         * image/jpeg jpeg jpg jpe
         * image/gif gif
         * image/png png
         * video/mp4
         * audio/mpeg mpga mp2 mp2a mp3 m2a m3a
         * video/x-flv flv
         * application/msword doc dot
         * application/vnd.openxmlformats-officedocument.wordprocessingml.document docx
         * application/vnd.ms-excel xls xlm xla xlc xlt xlw
         * application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx
         * application/vnd.ms-powerpoint ppt pps pot
         * application/vnd.openxmlformats-officedocument.presentationml.presentation pptx
         * application/pdf pdf
         */
        $mime = mime_content_type($file);
        $valid = false;
        $types = [
            'image/jpeg',
            'image/gif',
            'image/png',
            'video/mp4',
            'audio/mpeg',
            'video/x-flv',
            'application/msword',
            'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
            'application/vnd.ms-excel',
            'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            'application/vnd.ms-powerpoint',
            'application/vnd.openxmlformats-officedocument.presentationml.presentation',
            'application/pdf'
        ];
        foreach ($types as $t) {
            if (strpos($mime, $t) !== false) {
                $valid = true;
                break;
            }
        }
        return $valid;
    }

    /**
     * 
     * @param string $text
     * @return string
     */
    private function sanitize($text)
    {
        $text = htmlspecialchars($text, ENT_QUOTES);
        $text = str_replace("\n\r", "\n", $text);
        $text = str_replace("\r\n", "\n", $text);
        $text = str_replace("\n", "<br>", $text);
        return $text;
    }

    /**
     * 
     * @param string $timestamp
     * @return string
     */
    private function timeAgo($timestamp)
    {
        $datetime1 = new \DateTime("now");
        $datetime2 = date_create($timestamp);
        $diff = date_diff($datetime1, $datetime2);
        $timemsg = '';
        if ($diff->y > 0) {
            $timemsg = $diff->y . ' anio' . ($diff->y > 1 ? "s" : '');
        } else if ($diff->m > 0) {
            $timemsg = $diff->m . ' mes' . ($diff->m > 1 ? "s" : '');
        } else if ($diff->d > 0) {
            $timemsg = $diff->d . ' dia' . ($diff->d > 1 ? "s" : '');
        } else if ($diff->h > 0) {
            $timemsg = $diff->h . ' hora' . ($diff->h > 1 ? "s" : '');
        } else if ($diff->i > 0) {
            $timemsg = $diff->i . ' minuto' . ($diff->i > 1 ? "s" : '');
        } else if ($diff->s > 0) {
            $timemsg = $diff->s . ' segundo' . ($diff->s > 1 ? "s" : '');
        }
        if (!$timemsg) {
            $timemsg = "Ahora";
        } else {
            $timemsg = $timemsg . '';
        }
        return $timemsg;
    }

    /**
     * 
     * @param string $timestamp
     * @return boolean
     */
    private function isInactiveConnection($timestamp)
    {
        if (empty($timestamp)) {
            return true;
        }

        $now = date('Y-m-d H:i:s');
        $datetime1 = date_create($now);
        $datetime2 = date_create($timestamp);
        $diff = date_diff($datetime1, $datetime2);

        if ($diff->y > 0 || $diff->m > 0 || $diff->d > 0 || $diff->h > 0 || $diff->i > 0) {
            return true;
        }

        return ($diff->s) > 15 ? true : false;
    }
    
    public function csrfAction()
    {
        $request = $this->getRequest();
        if($request->isGet()) {
            
            $token = md5(uniqid('CSFR-' . mt_rand(), true));
            $_SESSION['token'] = $token;
            
            
            return new JsonModel([
                'success' => true,
                'data' => $token
            ]);
        
        
        } else {
            return new JsonModel([
                'success' => false,
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
            ]);
        }
        
        
    }
}