<?php

defined('BASEPATH') or exit('No direct script access allowed');



class User_messaging extends MY_Controller

{



    public function __construct()

    {

        parent::__construct();



        $no_logged_methods = array();



        if (empty($this->session->logged) && !in_array($this->router->fetch_method(), $no_logged_methods)) {

            $this->session->set_flashdata('show_login_form', true);

            redirect('engine/error?http_code=403');

        }



        $this->load->model(array('users_inbox_model' => 'inbox_model'));

    }



    public function index()

    {

        //$this->output->enable_profiler();



        $action = $this->input->get('action');

        switch ($action) {

            case 'read':

                $this->read_private_message();

                break;

            case 'write':

                $this->send_message();

                break;

            case 'limits':

                $this->get_limits();

                break;

            default:

                $this->get_inbox_home();

        }

    }



    private function get_inbox_home()

    {

        $pagination_config = $this->_get_pagination_config();



        $offset = $this->input->get('page', true);



        if (empty($offset))

        {

            $offset = 0;

        }



        $pagination_config['per_page']   = 25;

        $pagination_config['total_rows'] = $this->inbox_model->get_pm_count($this->session->id);



        $this->pagination->initialize($pagination_config);



        $auto_messages       = $this->inbox_model->get_auto_messages();



        // Get all inbox messages

        $classicMessages = $this->inbox_model->get_inbox_messages($pagination_config['per_page'], $offset);



        $session_status = $this->session->status_auto_messages;

        $session_status = json_decode($session_status, JSON_OBJECT_AS_ARRAY);





        foreach ($auto_messages as $k => $auto_message) 

        {

            $auto_message->string_type = 'auto_message';

            $key = 'message_'.$auto_message->id;



            if($session_status[$key] == 'deleted')

            {

                unset($auto_messages[$k]);

            }



            if($auto_message->type == 1)

            {

                $ascent = Ygg::get_ascent_timetamp($auto_message->periodicity);

                

                if($auto_message->instant_publish == 0 && date('z-Y', $ascent) == date('z-Y', time()) && $ascent > time()) 

                {

                    unset($auto_messages[$k]);

                }

                else if($auto_message->instant_publish == 0 && $auto_message->last_publish_date > $ascent)

                {

                    unset($auto_messages[$k]);

                }

                else if(time() > $ascent && $ascent > $auto_message->last_publish_date || date('z-Y', $ascent) == date('z-Y', time())) 

                {

                    $auto_message->last_publish_date = $ascent;

                }

            }



        }



       // print_r($auto_messages);

        $mergedArray     = array_merge($auto_messages, $classicMessages);



        usort($mergedArray, function($a, $b) {

            return strcmp($b->last_publish_date, $a->last_publish_date);

        });



        $messages = array_splice($mergedArray, 0, $pagination_config['per_page']);



        //print_r($messages);

        $data['messages'] = $messages;



        $data['total_messages'] = $pagination_config['total_rows'];

        $data['offset']         = $offset;

        $data['limit']          = count($data['messages']);



        $this->load->view('user/inbox/inbox_home', $data);

    }



    private function is_not_allowed_user($private_message_id)

    {

        $id = $this->db->select('id')->where('user_id', $this->session->id)->where('parent_message_id', $private_message_id)->where('state', 0)->get('messages_users')->row()->id;

        if (empty($id)) {

            return true;

        }

        return false;



    }



    public function update_messages_status($action='')

    {

 

        $actions = ['deleted' => null, 'unreaded'  => ['txt' => 'marquer comme non-lu'] , 'readed' => ['txt' => 'marquer comme lu']];



        if ($this->input->method() == 'post' && array_key_exists($action, $actions)) 

        {

            $messages_data = $this->input->post('data');

            $messages_data = json_decode($messages_data, JSON_OBJECT_AS_ARRAY);



            $days = [null, 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'];

            

            $func = 'set_status_'.$action;



            if($action == 'deleted')

            {

                $regular_messages_id = array();

                $session_status = $this->session->status_auto_messages;

                $session_status = json_decode($session_status, JSON_OBJECT_AS_ARRAY);



                foreach($messages_data as $message)

                {

                    if($message['mtype'] == 'auto')

                    {

                        $result = $this->inbox_model->get_auto_message($message['mid'], 'messages_auto.id, messages_auto.type, messages_auto.periodicity, messages_auto.publish_date, messages_auto.publish_date');



                        # Message périodique

                        if($result->type == 1)

                        {

                            $ascent = Ygg::get_ascent_timetamp($result->periodicity);

                        }



                        $key = 'message_'.$result->id;



                        if(array_key_exists($key, $session_status) && $session_status[$key] == 'deleted')

                        {

                            $this->show_error('Certains des messages selectionnés ont déjà été supprimés');   

                        }

                        else if(array_key_exists($key, $session_status) && $session_status[$key] > $result->publish_date)

                        {

                            if($result->type == 1 && time() > $ascent && $session_status[$key] < $ascent)

                            {  

                              $this->show_error('Vous ne pouvez supprimer un message automatique qu\\'après l\\'avoir lu.');   

                            }

                            else

                            {

                                $session_status[$key] = 'deleted';

                            }

                        }

                        else 

                        {

                            $this->show_error('Vous ne pouvez supprimer un message automatique qu\\'après l\\'avoir lu.');   

                        }

                    }

                    else {

                        $regular_messages_id[] = $message['mid'];

                    }

                }



                $this->inbox_model->update_status_auto_message($session_status);

                $this->inbox_model->$func($regular_messages_id);



                $data = array(

                    'action' => 'success',

                    'data' => $session_status

                );

                $this->show_json($data);

            }

            else 

            {

                if(in_array('auto', array_column($messages_data, 'mtype')))

                {

                   $this->show_error('Impossible de '.$actions[$action]['txt'].' un message automatique.');   

                }

                else 

                {

                    $messages_id = array_column($messages_data, 'mid');



                    $this->inbox_model->$func($messages_id);



                    $this->show_json('success');

                }

            }

        }

    }



    public function get_ajax_replies()

    {

        $private_message = intval($this->input->post('pm', true));

        $offset          = intval($this->input->post('offset', true));



        if ($this->is_not_allowed_user($private_message)) {

            $this->send_message_error('Accès refusé vous n\\'avez pas l\\'autorisation');

        }



        $message_replies = $this->inbox_model->get_replies($private_message, 15, $offset);

        $out             = '';

        foreach ($message_replies as $reply) {

            $data['reply'] = $reply;

            $out .= $this->load->view('ajax_templates/private_message/reply', $data, true);

        }



        $this->output->set_content_type('application/json')->set_output(json_encode(array('html' => $out, 'length' => count($message_replies))));

    }



    public function edit_reply()

    {

        //    $this->output->enable_profiler();

        $reply_id = intval($this->input->post('id', true));



        if ($this->inbox_model->is_owner_reply($reply_id) && isset($reply_id)) {



            $this->form_validation->set_rules('reply_body', 'contenu du message', 'required|min_length[10]|max_length[4000]|xss_clean');



            if ($this->form_validation->run()) {

                $reply = $this->input->post('reply_body');

                $reply = purify($reply);

                $reply = htmlentities($reply);

                // Je suis un porc et j'assume !

                $this->db->where('id', $reply_id)->set('message_body', $reply)->update('messages_replies');

            }



            sizeof($this->form_validation->error_array()) > 0 ? $this->show_error(array_values($this->form_validation->error_array())[0]) : '';



        }



    }



    public function read_message_auto($message_auto_id = '')

    {

        $message = $this->inbox_model->get_auto_message($message_auto_id);

        $status_messages = $this->session->status_auto_messages;

        $status_messages = json_decode($status_messages, JSON_OBJECT_AS_ARRAY);

        

        if(count($status_messages) == 0 || !is_array($status_messages))

        {

            $status_messages = array();

        }



        $message_id = 'message_'.$message_auto_id;

        

        if($message->type == 1)

        {

            $ascent = Ygg::get_ascent_timetamp($message->periodicity);

        }



        if(!array_key_exists($message_id, $status_messages) || $status_messages[$message_id] < $message->publish_date 

            || ($message->type == 1 && time() > $ascent && $status_messages[$message_id] < $ascent))

        {

            $this->inbox_model->viewed_auto_message($message_auto_id);

            $this->inbox_model->increment_views_message_auto($message_auto_id);

        }



        $status_messages['message_'.$message_auto_id] = time();

        $this->inbox_model->update_status_auto_messages($status_messages);



        $data['auto_message'] = $message;

        $this->load->view('user/inbox/inbox_read_message_auto', $data);

    }



    public function get_message()

    {

        $message_id = $this->input->get('id');



        if (!filter_var($message_id, FILTER_VALIDATE_INT)) {

            $this->show_error('Paramètre message_id invalide');

        }



        $message = $this->inbox_model->get_reply_message($message_id);



        if (empty($message->id)) {

            $this->show_error('Message inexistant');

        }



        if ($message->publisher_id != $this->session->id) {

            $this->show_error('Impossible de charger un message qui ne vous appartient pas');

        }



        $this->load->helper('minify');



        $html = minify_html(html_entity_decode($message->message_body));

        $this->output->set_content_type('application/json')->set_output(json_encode(array('html' => $html)));

    }



    public function delete_action()

    {

        $del_type = $this->input->get('type');

        $tid      = intval($this->input->get('target_id'));



        if (isset($del_type) && isset($tid)) {

            // We want to "delete" an entire private message

            if ($del_type == 'private_message') {



                // We want to "delete" a reply

            } else if ($del_type == 'reply') {

                $this->inbox_model->is_owner_reply($tid) ? $this->inbox_model->delete_reply($tid) : '';

                // $this->action_success();

            }



        }

    }



    public function read_private_message()

    {

        // Send form action

        if ($_SERVER['REQUEST_METHOD'] == 'POST') {

            //   $this->form_validation->set_rules('message_object', 'objet du message', 'required');

            $this->form_validation->set_rules('reply_body', 'contenu du message', 'required|min_length[10]|max_length[4000]|xss_clean');

            $this->form_validation->set_rules('private_message_id', 'private_message_id', 'required|integer');



            if ($this->form_validation->run()) {



                $reply_body         = htmlentities(purify($this->input->post('reply_body')));

                $private_message_id = $this->input->post('private_message_id');



                if ($this->is_not_allowed_user($private_message_id)) {

                    $this->send_message_error('Accès refusé vous n\\'avez pas l\\'autorisation');

                }



                $reply_id = $this->inbox_model->new_reply($private_message_id, $reply_body);



                $this->load->helper('minify');



                $data['reply_body']         = $reply_body;

                $data['reply_id']           = $reply_id;

                $data['private_message_id'] = $private_message_id;

                // Buil ajax response

                $html = minify_html($this->load->view('ajax_templates/private_message/my_reply', $data, true));



                $this->output->set_content_type('application/json')->set_output(json_encode(array('html' => $html)));

            }



            // Handles form_validation errors in Json

            sizeof($this->form_validation->error_array()) > 0 ? $this->show_error(array_values($this->form_validation->error_array())[0]) : '';



        } else {

            $private_message_id = $this->input->get('id');



            $data['private_message'] = $this->inbox_model->get_private_message($private_message_id);



            if ($this->is_not_allowed_user($private_message_id)) {

                $this->send_message_error('Acces refusé vous n\\'avez pas l\\'autorisation');

            } else {

                $data['private_replies_message'] = $this->inbox_model->get_replies($private_message_id);

                $data['count_replies']           = $this->inbox_model->get_count_replies($private_message_id);



                $this->inbox_model->mark_as_read($private_message_id);

            }



            $this->load->view('user/inbox/inbox_read_message', $data);

        }

    }



    public function report_message()

    {

        if ($_SERVER['REQUEST_METHOD'] == 'POST') {

            //  $this->output->enable_profiler();

            $message_id    = intval($this->input->post('message_id'));

            $del_message   = $this->input->post('del_message');

            $ignore_sender = $this->input->post('ignore_sender');

            $reason        = $this->input->post('reason');



            $private_message_data = $this->inbox_model->getMessageDataFromReply('publisher_id, parent_message_id', $message_id);

            $publisher_id         = $private_message_data->publisher_id;

            $private_message_id   = $private_message_data->parent_message_id;



            if (isset($_POST['ignore_sender'])) {

                $ignoredList = $this->db->select('ignored')->where('id', $this->session->id)->get('users')->row()->ignored;

                $ignoredList = json_decode($ignoredList, JSON_OBJECT_AS_ARRAY);



                if (!array_key_exists($publisher_id, $ignoredList)) {

                    $isUserExists = $this->db->select('id')->where('id', $publisher_id)->get('users')->num_rows() > 0;



                    if ($isUserExists) {



                        // On ajoute l'utilisateur à la liste avec la date d'ajout

                        if (!is_array($ignoredList)) {

                            $ignoredList                = array();

                            $ignoredList[$publisher_id] = now();

                        } else {

                            $ignoredList[$publisher_id] = now();

                        }



                        $ignoredList = json_encode($ignoredList);

                        $this->db->where('id', $this->session->id)->set('ignored', $ignoredList)->update('users');

                    }



                }



                if (isset($_POST['del_message'])) {

                    $this->inbox_model->remove_private_messages(array($private_message_id));

                }



                if (isset($reason) && strlen($reason)) {

                    $this->show_error('le motif du signalement excède 250 caractères');

                }



            }

        }

    }



    public function send_message()

    {

        $recipient_id = $this->input->get('recipient_id');



        $data['single_recipient'] = false;



        if (isset($recipient_id) && filter_var($recipient_id, FILTER_VALIDATE_INT)) {

            // If users try to send a PM to itself

            if ($recipient_id == $this->session->id) {

                $this->action_send_message('Impossible de s\\'envoyer un message à soit même');

            } else {

                $recipient_nickname = $this->inbox_model->get_recipient_nickname($recipient_id);

                // If ID user doesn't exists

                if (empty($recipient_nickname)) {

                    $this->action_send_message('Cet identifiant utilisateur n\\'existe pas');

                } else {

                    $data['single_recipient_id']       = $recipient_id;

                    $data['single_recipient_nickname'] = $recipient_nickname;

                    $data['single_recipient']          = true;

                }

            }

        }

        // Send form action

        if ($_SERVER['REQUEST_METHOD'] == 'POST') {

            $this->action_send_message($data['single_recipient']);

        } else {

            $this->load->view('user/inbox/inbox_new_message', $data);

        }

    }



    private function action_send_message($single_recipient = false)

    {

        $this->form_validation->set_rules('recipients[]', 'destinataires', 'integer|required');



        // Set validation rules

        $this->form_validation->set_rules('message_object', 'objet du message', 'required|xss_clean');

        $this->form_validation->set_rules('message_body', 'contenu du message', 'required');



        if ($this->form_validation->run()) {

            // Get values

            $recipients     = array_map('intval', $this->input->post('recipients'));

            $message_object = strip_tags($this->input->post('message_object'));

            $message_body   = htmlentities(purify($this->input->post('message_body')));



            if (count($recipients) > 5) {

                $this->show_error('Impossible d\\'envoyer un MP à plus de 5 destinataires');

            }



            if (in_array($this->session->id, $recipients)) {

                $this->show_error('Impossible de s\\'inclure dans la liste des destinataires');

            }



            $recipients_list = $this->inbox_model->get_recipients_list($recipients);

            // Add the current session user to recipients list

            $recipient_self->id           = $this->session->id;

            $recipient_self->nickname     = $this->session->nickname;

            $recipient_self->is_expeditor = true;

            $recipients_list[]            = $recipient_self;



            $recipients_list_id = array();



            $seconds = array(

                '24hours' => 3600,

                '4days'   => 345600,

                '1week'   => 604800,

                '2weeks'  => 1209600,

                '1month'  => 2629746,

                '3months' => 7889238,

            );



            foreach ($recipients_list as $recipient) {

                if ($recipient->id != $this->session->id) {

                    $recipient_settings = json_decode($recipient->settings, JSON_OBJECT_AS_ARRAY);

                    $ignoredList        = json_decode($recipient->ignored, JSON_OBJECT_AS_ARRAY);



                    if (array_key_exists($this->session->id, $ignoredList)) {

                        $this->show_error('Impossible de communiquer avec l\\'utilisateur <strong>' . $recipient->nickname . '</strong>');

                    } else if (isset($recipient_settings['pm']['condition_sender_age']) && $recipient_settings['pm']['condition_sender_age'] != 'nocondition') {

                        $sender_age = $recipient_settings['pm']['condition_sender_age'];



                        $timestamp_pm = now() - $seconds[$sender_age];



                        if ($this->session->join_date >= $timestamp_pm) {

                            $this->show_error('L\\'ancienneté de votre compte ne vous permet pas de communiquer avec l\\'utilisateur <strong>' . $recipient->nickname . '</strong>');

                        }

                    } else if ($recipient_settings['pm']['enable'] != 1) {

                        $this->show_error('<strong>' . $recipient->id . '</strong> a désactivé sa boite de réception et ne souhaite pas recevoir de nouveaux messages');

                    }



                    $recipients_list_id[] = $recipient->id;

                }

            }



            // Verify if recipients are valids

            if (count(array_diff($recipients, $recipients_list_id)) != 0) {



                $this->show_error('La liste des destinataires est invalide');

            }



            // Create private message

            $private_message_id = $this->inbox_model->new_private_message($message_object, $recipients_list);



            // Add reply

            $this->inbox_model->new_reply($private_message_id, $message_body);



            $this->session->set_flashdata('pm_sent', true);



            $this->output->set_content_type('application/json')->set_output(json_encode(array('message_id' => $private_message_id)));

        }



        // Handles form_validation errors in Json

        sizeof($this->form_validation->error_array()) > 0 ? $this->show_error(array_values($this->form_validation->error_array())[0]) : '';

    }



    public function search_users()

    {

        $queryP = $this->input->get('q', true);



        $list = array();



        if (!empty($queryP) && strlen($queryP) >= 3) {

            $query = 'SELECT * FROM users WHERE MATCH(\\'@nick ' . $this->_escape($queryP . '*') . '| ' . $this->_escape($queryP) . ' \\') limit 10';

            // Open Sphinx connection

            $conn = new mysqli($this->config->item('sphinx_server'), null, null, null, $this->config->item('sphinx_server_port'));



            if ($conn->connect_error) {

                throw new Exception('Erreur avec Sphinx : ' . $conn->connect_error, $conn->connect_error);

            }



            $query_search = $conn->query($query);

            $results      = array();

            // Retrieve the Ids

            while ($row = $query_search->fetch_assoc()) {

                $results[] = $row['id'];

            }



            $query_search->free_result();

            $ids = join('\\',\\'', $results);

            // Mysql query to get the nicknames

            // id, avatar, rank, uploaded, downloaded, last_activity_date, nickname, country

            $sql = "SELECT id, avatar, rank, uploaded, downloaded, last_activity_date, nickname, country FROM users WHERE id IN ('$ids') ORDER BY FIELD (users.id,'$ids')";



            $results = $this->db->query($sql)->result();



            foreach ($results as $result) {

                $list[] = ['id' => $result->id, 'text' => $result->nickname];

            }

        }



        $this->output->set_content_type('application/json')->set_output(json_encode($list));

    }



    public function can_receive()

    {

        $user_id = intval($this->input->get('user_id', true));



        if (isset($user_id)) {

            if ($this->session->id == $user_id) {

            	 $this->output->set_content_type('application/json');

                $this->output->set_output(json_encode(array('response' => 'negative', 'msg' => 'Impossible de s\\'inclure dans la liste des destinataires')));

            } else {

                $recipient_data = $this->db->select('nickname, settings, ignored')->where('id', $user_id)->get('users')->row();

                $nickname       = $recipient_data->nickname;



                $recipient_settings = json_decode($recipient_data->settings, JSON_OBJECT_AS_ARRAY);

                $ignoredList        = json_decode($recipient_data->ignored, JSON_OBJECT_AS_ARRAY);



                if (array_key_exists($this->session->id, $ignoredList)) {

                    $this->output->set_content_type('application/json')->set_output(json_encode(array('response' => 'negative', 'msg' => 'Impossible de communiquer avec l\\'utilisateur <strong>' . $nickname . '</strong>')));

                } else {

                    if ($recipient_settings['pm']['enable'] != 1) {

                        $this->output->set_content_type('application/json')->set_output(json_encode(array('response' => 'negative', 'msg' => '<strong>' . $nickname . '</strong> a désactivé sa boite de réception et ne souhaite pas recevoir de nouveaux messages')));

                    } else if (isset($recipient_settings['pm']['condition_sender_age']) && $recipient_settings['pm']['condition_sender_age'] != 'nocondition') {

                        $sender_age = $recipient_settings['pm']['condition_sender_age'];



                        $seconds = array

                            (

                            '24hours' => 3600,

                            '4days'   => 345600,

                            '1week'   => 604800,

                            '2weeks'  => 1209600,

                            '1month'  => 2629746,

                            '3months' => 7889238,

                        );



                        $timestamp_pm = now() - $seconds[$sender_age];



                        if ($this->session->join_date >= $timestamp_pm) {

                            $this->output->set_content_type('application/json');

                            $this->output->set_output(json_encode(array('response' => 'negative', 'msg' => 'L\\'ancienneté de votre compte ne vous permet pas de communiquer avec l\\'utilisateur <strong>' . $recipient->nickname . '</strong>')));

                        }

                    }

                }

            }

        }

    }



    private function send_message_error($error)

    {

        $this->session->set_flashdata('send_message_error', $error);

        // It redirects on error

        redirect(site_url('user_messaging'));

    }



}

