<?php

defined('BASEPATH') OR exit('No direct script access allowed');
require APPPATH . 'libraries/RestController.php';

use chriskacerguis\RestServer\RestController;

require APPPATH . 'libraries/Format.php';

class Auth extends RestController {

    function __construct() {
        parent::__construct();
        $this->load->helper('session');
        init_session();
    }

    public function logout_get() {
        unset_session();
        $this->response(['message' => 'Has Cerrado Sessión'], RestController::HTTP_OK);
    }

    public function acceso_post() {
        $this->_acceso_validation();
        $this->load->model('usuarios_model');
        $usuario = $this->usuarios_model->search_usuario_by_username_and_password($this->post('username'), $this->post('password'));
        if ($usuario !== NULL) {
            if ($usuario['status'] === '-1') {
                $_SESSION[$this->config->item('project_name') . $this->config->item('intentos_captcha')] = check_intentos_captcha() + 1;
                $this->response(array('message' => 'El usuario con el que intentas ingresar se encuentra inactivo, contacta a la administración para solucionar el problema.', 'intentos_captcha' => $_SESSION[$this->config->item('project_name') . $this->config->item('intentos_captcha')]), RestController::HTTP_BAD_REQUEST);
            } else {
                $this->_session_inicialize($usuario);
                $this->response(array("usuario" => $usuario), RestController::HTTP_OK);
            }
        } else {
            $_SESSION[$this->config->item('project_name') . $this->config->item('intentos_captcha')] = check_intentos_captcha() + 1;
            $this->response(array('message' => 'Usuario o Contraseña incorrecta', 'intentos_captcha' => $_SESSION[$this->config->item('project_name') . $this->config->item('intentos_captcha')]), RestController::HTTP_BAD_REQUEST);
        }
    }

    public function verificar_codigo_post() {
        $this->_codigo_validation();
        $this->load->model('usuarios_model');
        $this->_desencriptar_and_validar();
        $this->response(array(), RestController::HTTP_OK);
    }

    public function session_activa_get() {
        if (check_id()) {
            $this->response(['usuario_activo' => TRUE], RestController::HTTP_OK);
        }
        $this->response(['usuario_activo' => FALSE], RestController::HTTP_OK);
    }

    public function confirmar_acceso_post() {
        $this->_confirmar_acceso_validation();
        $this->load->model("usuarios_model");
        $usuario = $this->_desencriptar_and_validar();
        $data = $this->_fill_data_update();
        $this->db->trans_start();
        if (!$this->usuarios_model->update($usuario['id'], $data)) {
            $this->response(["message" => "Error al tratar de guardar el usuario, contacte a soporte técnico"], RestController::HTTP_INTERNAL_ERROR);
        }
        unset($usuario['password']);
        unset($usuario['status']);
        $this->db->trans_complete();
        $this->_envio_correo_password_actualizado($usuario['email']);
        $this->response(["message" => "Acceso completo", "usuario" => $usuario], RestController::HTTP_CREATED);
    }

    public function validate_and_send_correo_post() {
        $this->_form_username_validation();
        $this->load->model('usuarios_model');
        $usuario = $this->usuarios_model->get_usuario_by_username($this->post('username'));
        if ($usuario !== NULL) {
            //genera codigo para actualizar correo
            $data_update['email_code'] = date_timestamp_get(date_create());
            if (!$this->usuarios_model->update($usuario['id'], $data_update)) {
                $this->response(['message' => 'Error: No se envió el correo.'], RestController::HTTP_INTERNAL_ERROR);
            }
            //genera correo
            $this->load->helper('email');
            $key = $this->config->item('encrypt_url_key'); //key to encrypt and decrypts.
            $id_encripted = encrypt_url($usuario['id'] . '|' . $usuario['email'] . '|' . $data_update['email_code'], $key);
            if ($this->_envio_correo_cambiar_password($usuario['email'], $id_encripted)) {
                $this->response(['id_encripted' => $id_encripted], RestController::HTTP_OK);
            } else {
                $this->response(['message' => 'Error: No se envió el correo.'], RestController::HTTP_INTERNAL_ERROR);
            }
        } else {
            $this->response(["message" => "No existe un usuario con ese nombre."], RestController::HTTP_BAD_REQUEST);
        }
    }

    private function _fill_data_update() {
        $data['password'] = $this->post('password');
        $data['email_code'] = '';
        $data['updated_at'] = date("Y-m-d H:i:s");
        $data['status'] = 1;
        return $data;
    }

    private function _desencriptar_and_validar() {
        $codigo_encriptado = $this->post('codigo_encriptado');
        $this->load->helper('url');
        $this->load->helper('email');
        $key = $this->config->item('encrypt_url_key'); //key to encrypt and decrypts.
        $url_decoded = decrypt_url($codigo_encriptado, $key);
        $array_data = explode("|", $url_decoded);
        $usuario_array['id'] = $array_data[0];
        $usuario_array['email'] = $array_data[1];
        $usuario_array['code'] = $array_data[2];
        return $this->_validate_usuario_array($usuario_array);
    }

    private function _envio_correo_password_actualizado($destinatario) {
        $this->load->helper('email');
        $data['page_title'] = $this->config->item('page_title');
        $subject = 'Acceso como Usuario en la plataforma de ' . $data['page_title'] . '.';
        $data['url'] = $this->config->item('base_url');
        $message = $this->load->view('mail/password-actualizado', $data, TRUE);
        return send_mail($destinatario, $subject, $message);
    }

    private function _envio_correo_cambiar_password($destinatario, $id_url) {
        $this->load->helper('email');
        $data['page_title'] = $this->config->item('page_title');
        $subject = 'Recuperación de acceso para la plataforma de ' . $data['page_title'] . '.';
        $data['base_url'] = $this->config->item('base_url');
        $data['url'] = $this->config->item('base_url') . '#!/confirmar-acceso?codigo=' . $id_url;
        $message = $this->load->view('mail/confirmar-acceso', $data, TRUE);
        return send_mail($destinatario, $subject, $message);
    }

    private function _validate_usuario_array($usuario_array) {
        $usuario = $this->usuarios_model->get_usuario_by_id($usuario_array['id']);
        if ($usuario === NULL) {
            $this->response(['message' => "Error: el identificador o el correo no corresponde al usuario, contacte a soporte."], RestController::HTTP_BAD_REQUEST);
        }
        if ($usuario['email'] !== $usuario_array['email']) {
            $this->response(['message' => "Error: código del correo invalido, contacte a soporte."], RestController::HTTP_BAD_REQUEST);
        }
        if ($usuario['status'] === '-1') {
            $this->response(['message' => "Error: el usuario no se encuentra activo, contacte a soporte."], RestController::HTTP_NOT_FOUND);
        }
        if ($usuario['email_code'] === '') {
            $this->response(['message' => "Error: el código ya fue utilizado, contacte a soporte."], RestController::HTTP_NOT_FOUND);
        }
        if ($usuario['email_code'] !== $usuario_array['code']) {
            $this->response(['message' => "Error: código invalido, contacte a soporte."], RestController::HTTP_BAD_REQUEST);
        }
        return $usuario;
    }

    //funcion que inicializa la session de php con los datos del usuario
    private function _session_inicialize($usuario) {
        $_SESSION[$this->config->item('project_name') . $this->config->item('intentos_captcha')] = 0;
        foreach ($usuario as $key => $value) {
            $_SESSION[$this->config->item('project_name')]['user'][$key] = $value;
        }
    }

    private function _acceso_validation() {
        $this->load->library('form_validation');
        $this->form_validation->set_rules('username', 'username', 'trim|required|max_length[250]');
        $this->form_validation->set_rules('password', 'Contrase&ntilde;a', 'trim|required');
        $this->form_validation->set_rules('intentos_captcha', 'Intentos captcha', 'trim|required|is_natural');
        if ($this->post("intentos_captcha") >= 3) {
            $this->form_validation->set_rules('captcha', 'Captcha', 'trim|required|callback_validation_captcha_is_equal');
        }
        if (!$this->form_validation->run()) {
            $this->response(array('message' => validation_errors(), 'intentos_captcha' => check_intentos_captcha()), RestController::HTTP_BAD_REQUEST);
        }
    }

    private function _form_username_validation() {
        $this->load->library('form_validation');
        $this->form_validation->set_rules('username', 'Username', 'trim|required|max_length[200]|callback_check_username_in_sistema');
        if (!$this->form_validation->run()) {
            $this->response(['message' => validation_errors()], RestController::HTTP_BAD_REQUEST);
        }
    }

    public function check_username_in_sistema() {
        $this->load->model("usuarios_model");
        $username = $this->post('username');
        $usuario = $this->usuarios_model->check_username_in_sistema($username);
        if ($usuario === NULL) {
            $this->form_validation->set_message('check_username_in_sistema', 'El nombre de usuario no se encuentra en el sistema.');
            return FALSE;
        } else {
            if ($usuario['status'] === '-1') {
                $this->form_validation->set_message('check_username_in_sistema', 'El usuario se encuentra INACTIVO.');
                return FALSE;
            }
        }

        return TRUE;
    }

    public function validation_captcha_is_equal() {
        $captcha = $this->post('captcha');
        if ($captcha !== $_SESSION[$this->config->item('project_name') . $this->config->item('captcha_name')]) {
            $this->form_validation->set_message('validation_captcha_is_equal', 'El captcha ingresado no coincide');
            $_SESSION[$this->config->item('project_name') . $this->config->item('intentos_captcha')] = check_intentos_captcha() + 1;
            return FALSE;
        }
        return TRUE;
    }

    private function _codigo_validation() {
        $this->load->library('form_validation');
        $this->form_validation->set_rules('codigo_encriptado', 'C&oacute;digo', 'trim|required');
        if (!$this->form_validation->run()) {
            $this->response(['message' => validation_errors()], RestController::HTTP_BAD_REQUEST);
        }
    }

    private function _confirmar_acceso_validation() {
        $this->load->library('form_validation');
        $this->form_validation->set_rules('codigo_encriptado', 'C&oacute;digo', 'trim|required');
        $this->form_validation->set_rules('password', 'Contrase&ntilde;a', 'trim|required|min_length[6]');
        $this->form_validation->set_rules('confirmpassword', 'Confirmar Contrase&ntilde;a', 'trim|required|min_length[6]|matches[password]');
        if (!$this->form_validation->run()) {
            $this->response(['message' => validation_errors()], RestController::HTTP_BAD_REQUEST);
        }
    }
}
