Proyectos de Subversion LeadersLinked - Backend

Rev

Rev 17002 | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |

<?php

declare(strict_types=1);

namespace LeadersLinked\Controller;

use LeadersLinked\Model\User;
use LeadersLinked\Library\Zoom;
use Laminas\Log\LoggerInterface;
use LeadersLinked\Model\Network;
use Laminas\View\Model\JsonModel;
use Laminas\View\Model\ViewModel;
use LeadersLinked\Model\ChatUser;
use LeadersLinked\Model\ChatGroup;
use LeadersLinked\Model\Connection;
use LeadersLinked\Library\Functions;
use LeadersLinked\Mapper\UserMapper;
use LeadersLinked\Model\ChatMessage;
use LeadersLinked\Model\ZoomMeeting;
use LeadersLinked\Model\ChatGroupUser;
use Laminas\Db\Adapter\AdapterInterface;
use LeadersLinked\Form\Chat\ZoomAddForm;
use LeadersLinked\Mapper\ChatUserMapper;
use LeadersLinked\Model\ZoomMeetingUser;
use LeadersLinked\Mapper\ChatGroupMapper;
use LeadersLinked\Model\ChatGroupMessage;
use LeadersLinked\Mapper\ConnectionMapper;
use LeadersLinked\Mapper\ChatMessageMapper;
use LeadersLinked\Mapper\ZoomMeetingMapper;
use LeadersLinked\Mapper\ChatGroupUserMapper;
use LeadersLinked\Model\ChatGroupUserMessage;
use LeadersLinked\Mapper\ZoomMeetingUserMapper;
use LeadersLinked\Mapper\ChatGroupMessageMapper;

use Laminas\Mvc\Controller\AbstractActionController;
use LeadersLinked\Mapper\ChatGroupUserMessageMapper;


class ChatController extends AbstractActionController
{
    /**
     *
     * @var \Laminas\Db\Adapter\AdapterInterface
     */
    private $adapter;
    
    /**
     *
     * @var \LeadersLinked\Cache\CacheInterface
     */
    private $cache;
    
    
    /**
     *
     * @var \Laminas\Log\LoggerInterface
     */
    private $logger;
    
    /**
     *
     * @var array
     */
    private $config;
    
    
    /**
     *
     * @var \Laminas\Mvc\I18n\Translator
     */
    private $translator;
    
    
    /**
     *
     * @param \Laminas\Db\Adapter\AdapterInterface $adapter
     * @param \LeadersLinked\Cache\CacheInterface $cache
     * @param \Laminas\Log\LoggerInterface LoggerInterface $logger
     * @param array $config
     * @param \Laminas\Mvc\I18n\Translator $translator
     */
    public function __construct($adapter, $cache, $logger, $config, $translator)
    {
        $this->adapter      = $adapter;
        $this->cache        = $cache;
        $this->logger       = $logger;
        $this->config       = $config;
        $this->translator   = $translator;
    }

    /**
     *
     * 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);
                $status = $user->online ? 'Online' : 'Offline';
                $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 marcar como cerrado el chat',
     *       'url_open'                                 => 'url para marcar como abierto 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 marcar como cerrado el chat',
     *        'url_open'                => 'url para marcar como abierto 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();

            $currentNetworkPlugin = $this->plugin('currentNetworkPlugin');
            $currentNetwork = $currentNetworkPlugin->getNetwork();

            $userMapper = UserMapper::getInstance($this->adapter);
            $now = $userMapper->getDatebaseNow();
            
            
            $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);
                    $chatUser = $chatGroupUserMapper->fetchOneByGroupIdAndUserId($chatGroup->id, $currentUser->id);


                    $is_open = $chatUser->open == ChatUser::OPEN_YES;
                    $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_open'                              => $this->url()->fromRoute('chat/open', ['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_open'                              => $this->url()->fromRoute('chat/open', ['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_open'                      => $this->url()->fromRoute('chat/open', ['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);



            if ($currentNetwork->relationship_user_mode == Network::RELATIONSHIP_USER_MODE_USER_2_USER) {
                $connectionMapper = ConnectionMapper::getInstance($this->adapter);
                $userConnectionIds = $connectionMapper->fetchAllConnectionsByUserReturnIds($currentUser->id);
            } else {
                $userConnectionIds = [];
            }


            $userIds = [];
            $records = $chatUserMapper->fetchAllByUserId($currentUser->id);
            foreach ($records as $record) {
                if ($currentNetwork->relationship_user_mode == Network::RELATIONSHIP_USER_MODE_USER_2_USER) {

                    if ($record->user_id1 == $currentUser->id) {
                        $connection_user_id = $record->user_id2;
                    } else {
                        $connection_user_id = $record->user_id1;
                    }

                    if (in_array($connection_user_id, $userConnectionIds)) {
                        array_push($userIds, $connection_user_id);
                    }
                } else {


                    if ($record->user_id1 == $currentUser->id) {
                        array_push($userIds, $record->user_id2);
                    } else {
                        array_push($userIds, $record->user_id1);
                    }
                }
            }

            /*
             if($currentNetwork->relationship_user_mode == Network::RELATIONSHIP_USER_MODE_USER_2_USER)  {
             
             $connectionMapper = ConnectionMapper::getInstance($this->adapter);
             $userIds = $connectionMapper->fetchAllConnectionsByUserReturnIds($currentUser->id);
             
             } else {
             
             $records = $chatUserMapper->fetchAllByUserId($currentUser->id);
             foreach($records as $record)
             {
             if($record->user_id1 == $currentUser->id) {
             array_push($userIds, $record->user_id2);
             } else {
             array_push($userIds, $record->user_id1);
             }
             }
             
             }
             */



            if ($userIds) {

                $userMapper = UserMapper::getInstance($this->adapter);
                $users = $userMapper->fetchAllByIds($userIds);

                foreach ($users as $user) {
                    $chatUser = $chatUserMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);
                    if ($chatUser) {
                        $count_not_received_messages = $chatMessageMapper->countNotReceivedMessagesByChatIdAndToId($chatUser->id, $currentUser->id);
                        $count_not_seen_messages = $chatMessageMapper->countNotSeenMessagesByChatIdAndToId($chatUser->id, $currentUser->id);
                        $lastMessage = $chatMessageMapper->fetchLastMessage($chatUser->id, $currentUser->id);

                        if ($lastMessage) {
                            $lastMessage = Functions::timeAgo($lastMessage->added_on, $now);
                        } else {
                            $lastMessage = '';
                        }

                        if ($currentUser->id == $chatUser->user_id1) {
                            $is_open = $chatUser->user_open1 == ChatUser::OPEN_YES;
                        } else {
                            $is_open = $chatUser->user_open2 == ChatUser::OPEN_YES;
                        }


                        $not_received_messages = $count_not_received_messages > 0;
                        $not_seen_messages = $count_not_seen_messages > 0;
                    } else {
                        $is_open = false;
                        $count_not_received_messages = 0;
                        $count_not_seen_messages =  0;
                        $not_seen_messages = false;
                        $not_received_messages = false;
                        $lastMessage = '';
                    }


                    $chat = [
                        'url_clear'                 => $this->url()->fromRoute('chat/clear', ['id' => $user->uuid]),
                        'url_close'                 => $this->url()->fromRoute('chat/close', ['id' => $user->uuid]),
                        'url_open'                  => $this->url()->fromRoute('chat/open', ['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]),
                        'url_zoom'                  => $this->url()->fromRoute('chat/zoom', ['id' => $user->uuid, 'type' => 'chat']),
                        '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'                    => $user->online ? 1 : 0,
                        'is_open'                   => $is_open ? 1 : 0,
                        'not_seen_messages'         => $not_seen_messages,
                        'not_received_messages'     => $not_received_messages,
                        'count_not_seen_messages'       => $count_not_seen_messages,
                        'count_not_received_messages'   => $count_not_received_messages,
                        'last_message'                  => $lastMessage

                    ];

                    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()
                ]);
            }




            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'    => $user->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'
            ];
        }

        $chatGroupMessageMapper = ChatGroupMessageMapper::getInstance($this->adapter);
        $paginator = $chatGroupMessageMapper->getPaginatorByGroupId($chatGroup->id, $page);

        $pages = $paginator->count();
        $page  = $paginator->getCurrentPageNumber();

        $items = [];
        $users = [];
        $userMapper = UserMapper::getInstance($this->adapter);
        $now = $userMapper->getDatebaseNow();

        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, $now);
            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();


        $chatMessageMapper = ChatMessageMapper::getInstance($this->adapter);
        $paginator = $chatMessageMapper->getAllMessagesPaginatorByChatId($chatUser->id, $page);
        $pages = $paginator->count();
        $page = $paginator->getCurrentPageNumber();

        $items = [];
        $users = [];
        $userMapper = UserMapper::getInstance($this->adapter);
        $now = $userMapper->getDatebaseNow();


        $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, $now);
            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,
            ]);
        }




        return [
            'success' => true,
            'data' => [
                'page' => $page,
                'pages' => $pages,
                'items' => $items,
                'online' => 1
            ]
        ];
    }

    /**
     * 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    = Functions::sanitizeFilterString($this->params()->fromPost('message', ''));

            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);
            $now = $userMapper->getDatebaseNow();
            
            $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()
                            ]);
                        }
                    }
                }

                $userMapper->updateLastActivity($currentUser->id);

                $msgtime = $this->timeAgo($now, $now);
                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($chatMessage->added_on, $now);
                $userMapper->updateLastActivity($currentUser->id);

                if ($currentUser->id == $chatUser->user_id1) {
                    $chatUserMapper->markIsOpen2($chatUser->id);
                } else {
                    $chatUserMapper->markIsOpen1($chatUser->id);
                }

                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
                ]);




                array_push($items, [
                    'id'        => $user->uuid,
                    'name'      => $name,
                    'image'     => $image,
                    'online'    => $user->online,
                ]);
            }

            $userMapper->updateLastActivity($currentUser->id);

            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]);
                }




                array_push($items, [
                    'url_remove_from_group' => $url_remove_from_group,
                    'id'                    => $user->uuid,
                    'name'                  => $name,
                    'image'                 => $image,
                    'online'                => $user->online,
                ]);
            }

            $userMapper->updateLastActivity($currentUser->id);

            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 = Functions::sanitizeFilterString($this->params()->fromRoute('group_id'));
            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);

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

            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 = Functions::sanitizeFilterString($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) {
                $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'
                    ]);
                }

                $chatGroupUserMapper->markIsClose($chatGroup->id, $currentUser->id);
            } 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) {
                    if ($currentUser->id == $chatUser->user_id1) {
                        $chatUserMapper->markIsClose1($chatUser->id);
                    } else {
                        $chatUserMapper->markIsClose2($chatUser->id);
                    }
                }
            }

            $userMapper->updateLastActivity($currentUser->id);



            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 = Functions::sanitizeFilterString($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) {
                $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'
                    ]);
                }

                $chatGroupUserMapper->markIsClose($chatGroup->id, $currentUser->id);
            } 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) {
                    if ($currentUser->id == $chatUser->user_id1) {
                        $chatUserMapper->markIsClose1($currentUser->id);
                    } else {
                        $chatUserMapper->markIsClose2($currentUser->id);
                    }
                }
            }

            $userMapper->updateLastActivity($currentUser->id);


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

    /**
     * Marca como abierto el caht
     * Es una petición POST el url que contiene el ID encriptado del chat (/chat/open/: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 openAction()
    {
        $request    = $this->getRequest();
        if ($request->isPost()) {
            $currentUserPlugin = $this->plugin('currentUserPlugin');
            $currentUser = $currentUserPlugin->getUser();

            $id = Functions::sanitizeFilterString($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) {
                $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'
                    ]);
                }

                $chatGroupUserMapper->markIsOpen($chatGroup->id, $currentUser->id);
            } 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) {
                    if ($currentUser->id == $chatUser->user_id1) {
                        $chatUserMapper->markIsOpen1($chatUser->id);
                    } else {
                        $chatUserMapper->markIsOpen2($chatUser->id);
                    }
                }
            }


            $userMapper->updateLastActivity($currentUser->id);

            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 = Functions::sanitizeFilterString($this->params()->fromRoute('id'));
            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()
                            ]);
                        }
                    }
                }

                $userMapper->updateLastActivity($currentUser->id);
                $now = $userMapper->getDatebaseNow();

                $msgtime = $this->timeAgo($now, $now);
                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()
                    ]);
                }


                $userMapper->updateLastActivity($currentUser->id);
                $now = $userMapper->getDatebaseNow();
                
                
                $chatMessage = $chatMessageMapper->fetchOne($chatMessage->id);

                $msgtime = $this->timeAgo($chatMessage->added_on, $now);
                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
     * @param string $now
     * @return string
     */
    private function timeAgo($timestamp, $now = '')
    {

        if ($now) {
            $datetime1 = \DateTime::createFromFormat('Y-m-d H:i:s', $now);
        } else {
            $now = date('Y-m-d H:i:s');
            $datetime1 = date_create($now);
        }
        $datetime2 = date_create($timestamp);

        $diff = date_diff($datetime1, $datetime2);
        $timemsg = '';
        if ($diff->y > 0) {
            $timemsg = $diff->y . ' año' . ($diff->y > 1 ? "s" : '');
        } else if ($diff->m > 0) {
            $timemsg = $diff->m . ' mes' . ($diff->m > 1 ? "es" : '');
        } 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 zoomAction()
    {
        $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'
                ]);
            }

            $chatUserMapper = ChatUserMapper::getInstance($this->adapter);
            $chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);
            $chatUser = null;
            $chatGroup = $chatGroupMapper->fetchOneByUuid($id);

            if ($chatGroup) {
                $chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);
                $chatGroupUser = $chatGroupUserMapper->fetchOneByGroupIdAndUserId($chatGroup->id, $currentUser->id);

                if (!$chatGroupUser) {
                    $data = [
                        'success' => false,
                        'data' =>  'ERROR_ZOOM_CHAT_UNAUTHORIZE'
                    ];
                    return new JsonModel($data);
                }
            } 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);
                    }
                }
            }

            if (!$chatUser && !$chatGroup) {
                $data = [
                    'success' => false,
                    'data' => 'ERROR_ZOOM_CHAT_NOT_FOUND'
                ];
                return new JsonModel($data);
            }

            $dataPost = $request->getPost()->toArray();
            $form = new ZoomAddForm();
            //Anderson
            $form->setData($dataPost);

            if ($form->isValid()) {
                $dataPost = (array) $form->getData();
                $dtStart = \DateTime::createFromFormat('Y-m-d H:i:s', $dataPost['date'] . ' ' . $dataPost['time']);
                if (!$dtStart) {
                    return new JsonModel([
                        'success' => false,
                        'data' => 'ERROR_PARAMETERS_ARE_INVALID'
                    ]);
                }

                $dtEnd = \DateTime::createFromFormat('Y-m-d H:i:s', $dataPost['date'] . ' ' . $dataPost['time']);
                $dtEnd->add(new \DateInterval('PT' . $dataPost['duration'] . 'M'));
                $start_time = $dtStart->format('Y-m-d\TH:i:s');
                $zoom = new Zoom($this->adapter, $this->config, $this->cache);
                $response =  $zoom->getOAuthAccessToken();

                if ($response['success']) {
                    $access_token = $response['data'];
                    $result = $zoom->addMeeting($access_token, $dataPost['title'], $dataPost['description'], $dataPost['type'], $start_time, $dataPost['duration'], $dataPost['timezone'], $dataPost['password']);
                } else {
                    return new JsonModel([
                        'success' => false,
                        'data' => 'ERROR_ZOOM_CREATING_NEW_MEETING'
                    ]);
                }

                if ($result['success']) {
                    $zoomMeetingMapper = ZoomMeetingMapper::getInstance($this->adapter);
                    $zoomMeeting = $zoomMeetingMapper->fetchOne($result['data']['id']);

                    if (!$zoomMeeting) {
                        $zoomMeeting = new ZoomMeeting();
                        $zoomMeeting->id = $result['data']['id'];
                        $zoomMeeting->topic = $dataPost['title'];
                        $zoomMeeting->agenda = $dataPost['description'];
                        $zoomMeeting->duration = $dataPost['duration'];
                        $zoomMeeting->join_url = $result['data']['join_url'];
                        $zoomMeeting->start_time = $dtStart->format('Y-m-d H:i:s');
                        $zoomMeeting->end_time = $dtEnd->format('Y-m-d H:i:s');
                        $zoomMeeting->timezone = $dataPost['timezone'];
                        $zoomMeeting->type = $dataPost['type'];
                        $zoomMeeting->uuid = $result['data']['uuid'];
                        $zoomMeeting->password = $dataPost['password'];

                        if (!$zoomMeetingMapper->insert($zoomMeeting)) {
                            return new JsonModel([
                                'success' => false,
                                'data' => $zoomMeetingMapper->getError()
                            ]);
                        }
                    }

                    $chatMessageContent = "LABEL_ZOOM_MEETING \r\n" .
                        " LABEL_ZOOM_MEETING_START_DATE : " . $dtStart->format('Y-m-d') . "\r\n" .
                        " LABEL_ZOOM_MEETING_START_TIME : " . $dtStart->format('H:i a') . "\r\n" .
                        " LABEL_ZOOM_MEETING_TIMEZONE : " . $zoomMeeting->timezone . "\r\n" .
                        " LABEL_ZOOM_MEETING_TITLE :  " . $zoomMeeting->topic  . "\r\n" .
                        " LABEL_ZOOM_MEETING_URL : " . $zoomMeeting->join_url . "\r\n" .
                        " LABEL_ZOOM_MEETING_PASSWORD : " . $zoomMeeting->password . "\r\n";
                    $zoomMeetingUserMapper = ZoomMeetingUserMapper::getInstance($this->adapter);
                    $zoomMeetingUser = $zoomMeetingUserMapper->fetchOneByZoomMeetingIdAndUserId($zoomMeeting->id, $currentUser->id);

                    if (!$zoomMeetingUser) {
                        $zoomMeetingUser = new ZoomMeetingUser();
                        $zoomMeetingUser->zoom_meeting_id = $zoomMeeting->id;
                        $zoomMeetingUser->user_id = $currentUser->id;
                        $zoomMeetingUser->type = ZoomMeetingUser::TYPE_CREATOR;
                        $zoomMeetingUserMapper->insert($zoomMeetingUser);
                    }

                    if ($chatUser) {
                        if ($chatUser->user_id1 == $currentUser->id) {
                            $zoomMeetingUser = $zoomMeetingUserMapper->fetchOneByZoomMeetingIdAndUserId($zoomMeeting->id, $chatUser->user_id2);

                            if (!$zoomMeetingUser) {
                                $zoomMeetingUser = new ZoomMeetingUser();
                                $zoomMeetingUser->zoom_meeting_id = $zoomMeeting->id;
                                $zoomMeetingUser->user_id = $chatUser->user_id2;
                                $zoomMeetingUser->type = ZoomMeetingUser::TYPE_CREATOR;
                                $zoomMeetingUserMapper->insert($zoomMeetingUser);
                            }
                        } else {
                            $zoomMeetingUser = $zoomMeetingUserMapper->fetchOneByZoomMeetingIdAndUserId($zoomMeeting->id, $chatUser->user_id1);

                            if (!$zoomMeetingUser) {
                                $zoomMeetingUser = new ZoomMeetingUser();
                                $zoomMeetingUser->zoom_meeting_id = $zoomMeeting->id;
                                $zoomMeetingUser->user_id = $chatUser->user_id1;
                                $zoomMeetingUser->type = ZoomMeetingUser::TYPE_CREATOR;
                                $zoomMeetingUserMapper->insert($zoomMeetingUser);
                            }
                        }

                        $chatMessage = new ChatMessage();
                        $chatMessage->recd = ChatMessage::RECD_NO;
                        $chatMessage->seen = ChatMessage::SEEN_NO;
                        $chatMessage->type = ChatMessage::TYPE_TEXT;
                        $chatMessage->content = $chatMessageContent;
                        $chatMessage->from_id = $currentUser->id;
                        $chatMessage->to_id = $chatUser->user_id1 == $currentUser->id ? $chatUser->user_id2 : $chatUser->user_id1;
                        $chatMessage->chat_id = $chatUser->id;
                        $chatMessageMapper = ChatMessageMapper::getInstance($this->adapter);
                        $chatMessageMapper->insert($chatMessage);
                        $chatUserMapper->markIsOpen1($chatUser->id);
                        $chatUserMapper->markIsOpen2($chatUser->id);
                    } else if ($chatGroup) {

                        $chatGroupMessage = new ChatGroupMessage();
                        $chatGroupMessage->group_id = $chatGroup->id;
                        $chatGroupMessage->content = $chatMessageContent;
                        $chatGroupMessage->sender_id = $currentUser->id;
                        $chatGroupMessage->type = ChatGroupMessage::TYPE_TEXT;
                        $chatGroupMessageMapper = ChatGroupMessageMapper::getInstance($this->adapter);

                        if ($chatGroupMessageMapper->insert($chatGroupMessage)) {
                            $chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);
                            $groupUsers =   $chatGroupUserMapper->fetchAllByGroupId($chatGroup->id);
                            $chatGroupUserMessageMapper = ChatGroupUserMessageMapper::getInstance($this->adapter);
                            foreach ($groupUsers as $groupUser) {
                                if ($groupUser->user_id != $currentUser->id) {
                                    $zoomMeetingUser = $zoomMeetingUserMapper->fetchOneByZoomMeetingIdAndUserId($zoomMeeting->id, $groupUser->user_id);

                                    if (!$zoomMeetingUser) {
                                        $zoomMeetingUser = new ZoomMeetingUser();
                                        $zoomMeetingUser->zoom_meeting_id = $zoomMeeting->id;
                                        $zoomMeetingUser->user_id = $groupUser->user_id;
                                        $zoomMeetingUser->type = ZoomMeetingUser::TYPE_CREATOR;
                                        $zoomMeetingUserMapper->insert($zoomMeetingUser);
                                    }
                                }

                                $chatGroupUserMessage = new ChatGroupUserMessage();
                                $chatGroupUserMessage->group_id = $chatGroup->id;
                                $chatGroupUserMessage->message_id = $chatGroupMessage->id;
                                $chatGroupUserMessage->receiver_id = $groupUser->user_id;
                                $chatGroupUserMessage->recd = ChatGroupUserMessage::RECD_NO;
                                $chatGroupUserMessage->seen = ChatGroupUserMessage::SEEN_NO;
                                $chatGroupUserMessageMapper->insert($chatGroupUserMessage);
                                $chatGroupUserMapper->markIsOpen($groupUser->group_id, $groupUser->user_id);
                            }
                        }
                    }

                    return new JsonModel([
                        'success' => true,
                        'data' => 'LABEL_ZOOM_NEW_MEETING_SUCCESSFULLY'
                    ]);
                } else {
                    return new JsonModel([
                        'success' => false,
                        'data' => 'ERROR_ZOOM_CREATING_NEW_MEETING'
                    ]);
                }
            } 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
                ]);

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

        return new JsonModel($response);
    }


    public function usersAction()
    {
        $currentUserPlugin = $this->plugin('currentUserPlugin');
        $currentUser = $currentUserPlugin->getUser();
        $currentNetworkPlugin = $this->plugin('currentNetworkPlugin');
        $currentNetwork = $currentNetworkPlugin->getNetwork();
        $request = $this->getRequest();

        if ($request->isGet()) {
            $items = [];
            $chatUserMapper = ChatUserMapper::getInstance($this->adapter);
            $search = Functions::sanitizeFilterString($this->params()->fromQuery('search', ''));

            if (strlen($search) >= 3) {
                $user_ids = [];
                $userMapper = UserMapper::getInstance($this->adapter);

                if ($currentNetwork->relationship_user_mode == Network::RELATIONSHIP_USER_MODE_USER_2_USER) {

                    $connectionMapper = ConnectionMapper::getInstance($this->adapter);
                    $user_ids = $connectionMapper->fetchAllConnectionsByUserReturnIds($currentUser->id);
                } else {
                    if ($currentNetwork->default == Network::DEFAULT_YES) {
                        $user_ids = $userMapper->fetchAllIdsByDefaultNetworkId($currentNetwork->id, $currentUser->id);
                    } else {
                        $user_ids = $userMapper->fetchAllIdsByNonDefaultNetworkId($currentNetwork->id, $currentUser->id);
                    }
                }

                $items = [];
                $records = $userMapper->fetchAllByIdsAndSearch($user_ids, $search, $currentUser->id);

                foreach ($records as $record) {
                    $chatUser = $chatUserMapper->fetchOneByUserId1AndUserId2($currentUser->id, $record->id);
                    if ($chatUser) {
                        $link_send = $this->url()->fromRoute('chat/send', ['id' => $record->uuid]);
                    } else {
                        $link_send = '';
                    }

                    $link_open_or_create = $this->url()->fromRoute('chat/open-or-create', ['id' => $record->uuid]);
                    array_push($items, [
                        'name'  => trim($record->first_name .  '  ' . $record->last_name) . ' (' . $record->email . ')',
                        'image' => $this->url()->fromRoute('storage', ['code' => $record->uuid, 'type' => 'user', 'filename' => $record->image]),
                        'link_send' => $link_send,
                        'link_open_or_create' => $link_open_or_create,
                    ]);
                }
            }

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

        return new JsonModel($response);
    }

    public function openOrCreateAction()
    {
        $request    = $this->getRequest();
        if ($request->isPost()) {
            $currentUserPlugin = $this->plugin('currentUserPlugin');
            $currentUser = $currentUserPlugin->getUser();

            $currentNetworkPlugin = $this->plugin('currentNetworkPlugin');
            $currentNetwork = $currentNetworkPlugin->getNetwork();


            $id = Functions::sanitizeFilterString($this->params()->fromRoute('id'));

            if (!$id) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_PARAMETERS_ARE_INVALID'
                ]);
            }

            $userMapper = UserMapper::getInstance($this->adapter);
            $user = $userMapper->fetchOneByUuid($id);

            if (!$user) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_USER_NOT_FOUND'
                ]);
            }

            if ($user->email_verified == User::EMAIL_VERIFIED_NO || $user->status != User::STATUS_ACTIVE) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_USER_IS_INACTIVE'
                ]);
            }

            if ($user->network_id != $currentUser->network_id) {
                return new JsonModel([
                    'success' => false,
                    'data' => 'ERROR_USER_IS_INACTIVE'
                ]);
            }

            if ($currentNetwork->relationship_user_mode == Network::RELATIONSHIP_USER_MODE_USER_2_USER) {

                $connectionMapper = ConnectionMapper::getInstance($this->adapter);
                $connection = $connectionMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);

                if (!$connection) {
                    return new JsonModel([
                        'success' => false,
                        'data' =>  'ERROR_CONNECTION_NOT_ACTIVE'
                    ]);
                }
            }

            $chatUserMapper = ChatUserMapper::getInstance($this->adapter);
            $chatUser = $chatUserMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);
            if ($chatUser) {
                if ($currentUser->id == $chatUser->user_id1) {
                    $chatUserMapper->markIsOpen1($chatUser->id);
                } else {
                    $chatUserMapper->markIsOpen2($chatUser->id);
                }
            } else {
                $chatUser = new ChatUser();
                $chatUser->user_id1 = $currentUser->id;
                $chatUser->user_id2 = $user->id;
                $chatUser->user_open1 = ChatUser::OPEN_YES;
                $chatUser->user_open2 = ChatUser::OPEN_NO;


                if (!$chatUserMapper->insert($chatUser)) {
                    return new JsonModel([
                        'success' => false,
                        'data' =>  $chatUserMapper->getError()
                    ]);
                }
            }

            $now = $userMapper->getDatebaseNow();

            $chatMessageMapper = ChatMessageMapper::getInstance($this->adapter);
            $count_not_received_messages = $chatMessageMapper->countNotReceivedMessagesByChatIdAndToId($chatUser->id, $currentUser->id);
            $count_not_seen_messages = $chatMessageMapper->countNotSeenMessagesByChatIdAndToId($chatUser->id, $currentUser->id);
            $lastMessage = $chatMessageMapper->fetchLastMessage($chatUser->id, $currentUser->id);

            if ($lastMessage) {
                $lastMessage = Functions::timeAgo($lastMessage->added_on, $now);
            } else {
                $lastMessage = '';
            }

            if ($currentUser->id == $chatUser->user_id1) {
                $is_open = $chatUser->user_open1 == ChatUser::OPEN_YES;
            } else {
                $is_open = $chatUser->user_open2 == ChatUser::OPEN_YES;
            }


            $not_received_messages = $count_not_received_messages > 0;
            $not_seen_messages = $count_not_seen_messages > 0;

            $data = [
                'url_clear'                 => $this->url()->fromRoute('chat/clear', ['id' => $user->uuid]),
                'url_close'                 => $this->url()->fromRoute('chat/close', ['id' => $user->uuid]),
                'url_open'                  => $this->url()->fromRoute('chat/open', ['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]),
                'url_zoom'                  => $this->url()->fromRoute('chat/zoom', ['id' => $user->uuid, 'type' => 'chat']),
                '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'                    => $user->online ? 1 : 0,
                'is_open'                   => $is_open ? 1 : 0,
                'not_seen_messages'         => $not_seen_messages,
                'not_received_messages'     => $not_received_messages,
                'count_not_seen_messages'       => $count_not_seen_messages,
                'count_not_received_messages'   => $count_not_received_messages,
                'last_message'                  => $lastMessage
            ];



            $userMapper->updateLastActivity($currentUser->id);

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