<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Auth extends CI_Controller {

    public function __construct() {
        parent::__construct();
        $this->load->model('auth_model');
        $this->load->library('session');
        $this->load->helper(array('url', 'form', 'security'));
        $this->load->library('form_validation');
    }

    /**
     * Página de login
     */
    public function index() {
        // Si ya está logueado, redirigir al dashboard
        if ($this->session->userdata('logged_in')) {
            redirect('cotizaciones');
        }
        
        $this->load->view('auth/login');
    }

    /**
     * Procesar login
     */
    public function login() {
        // Validar CSRF token
        if (!$this->security->get_csrf_hash()) {
            $this->session->set_flashdata('error', 'Token de seguridad inválido');
            redirect('auth');
        }

        $this->form_validation->set_rules('username', 'Usuario', 'required|trim');
        $this->form_validation->set_rules('password', 'Contraseña', 'required');

        if ($this->form_validation->run() == FALSE) {
            $this->session->set_flashdata('error', 'Complete todos los campos');
            redirect('auth');
        }

        $username = $this->security->xss_clean($this->input->post('username'));
        $password = $this->input->post('password');

        // Protección contra timing attacks
        usleep(rand(100000, 300000)); // 0.1 - 0.3 segundos

        $resultado = $this->auth_model->verificar_login($username, $password);

        if ($resultado['success']) {
            $usuario = $resultado['usuario'];

            // Regenerar session ID para prevenir session fixation
            $this->session->sess_regenerate(TRUE);

            // Crear sesión
            $session_data = array(
                'user_id' => $usuario->id,
                'username' => $usuario->username,
                'email' => $usuario->email,
                'nombre_completo' => $usuario->nombre_completo,
                'logged_in' => TRUE,
                'login_time' => time()
            );

            $this->session->set_userdata($session_data);
            $this->auth_model->crear_sesion($usuario->id);

            // Redirigir al dashboard
            redirect('cotizaciones');
        } else {
            $this->session->set_flashdata('error', $resultado['message']);
            redirect('auth');
        }
    }

    /**
     * Cerrar sesión
     */
    public function logout() {
        if ($this->session->userdata('logged_in')) {
            $usuario_id = $this->session->userdata('user_id');
            $username = $this->session->userdata('username');

            // Registrar logout
            $this->auth_model->registrar_log($usuario_id, $username, 'logout', 'Cierre de sesión');
            
            // Eliminar sesión de BD
            $this->auth_model->eliminar_sesion($usuario_id);
        }

        // Destruir sesión
        $this->session->sess_destroy();

        // Redirigir al login
        redirect('auth');
    }

    /**
     * Página de recuperación de contraseña
     */
    public function recuperar() {
        $this->load->view('auth/recuperar');
    }

    /**
     * Enviar email de recuperación
     */
    public function enviar_recuperacion() {
        $this->form_validation->set_rules('email', 'Email', 'required|valid_email');

        if ($this->form_validation->run() == FALSE) {
            $this->session->set_flashdata('error', 'Email inválido');
            redirect('auth/recuperar');
        }

        $email = $this->security->xss_clean($this->input->post('email'));
        $resultado = $this->auth_model->generar_token_recuperacion($email);

        if ($resultado) {
            // Aquí puedes integrar el envío de email
            // Por ahora, mostrar el token (en producción, enviarlo por email)
            $link = base_url('auth/restablecer/' . $resultado['token']);
            
            $this->session->set_flashdata('success', 'Se ha enviado un enlace de recuperación a tu email');
            // TODO: Enviar email con $link
            
            redirect('auth');
        } else {
            // Por seguridad, no revelar si el email existe o no
            $this->session->set_flashdata('success', 'Si el email existe, recibirás un enlace de recuperación');
            redirect('auth');
        }
    }

    /**
     * Página para restablecer contraseña
     */
    public function restablecer($token = null) {
        if (!$token) {
            redirect('auth');
        }

        $usuario = $this->auth_model->validar_token_recuperacion($token);

        if (!$usuario) {
            $this->session->set_flashdata('error', 'Token inválido o expirado');
            redirect('auth');
        }

        $data['token'] = $token;
        $this->load->view('auth/restablecer', $data);
    }

    /**
     * Procesar restablecimiento de contraseña
     */
    public function procesar_restablecer() {
        $this->form_validation->set_rules('token', 'Token', 'required');
        $this->form_validation->set_rules('password', 'Contraseña', 'required|min_length[8]');
        $this->form_validation->set_rules('password_confirm', 'Confirmar Contraseña', 'required|matches[password]');

        if ($this->form_validation->run() == FALSE) {
            $this->session->set_flashdata('error', validation_errors());
            redirect('auth/restablecer/' . $this->input->post('token'));
        }

        $token = $this->input->post('token');
        $usuario = $this->auth_model->validar_token_recuperacion($token);

        if (!$usuario) {
            $this->session->set_flashdata('error', 'Token inválido o expirado');
            redirect('auth');
        }

        $password = $this->input->post('password');
        
        // Validar complejidad de contraseña
        if (!$this->validar_complejidad_password($password)) {
            $this->session->set_flashdata('error', 'La contraseña debe contener al menos una mayúscula, una minúscula, un número y un carácter especial');
            redirect('auth/restablecer/' . $token);
        }

        $this->auth_model->cambiar_password($usuario->id, $password);
        $this->auth_model->registrar_log($usuario->id, $usuario->username, 'password_changed', 'Contraseña cambiada');

        $this->session->set_flashdata('success', 'Contraseña actualizada exitosamente');
        redirect('auth');
    }

    /**
     * Validar complejidad de contraseña
     */
    private function validar_complejidad_password($password) {
        // Al menos 8 caracteres, una mayúscula, una minúscula, un número y un carácter especial
        $uppercase = preg_match('@[A-Z]@', $password);
        $lowercase = preg_match('@[a-z]@', $password);
        $number = preg_match('@[0-9]@', $password);
        $specialChars = preg_match('@[^\w]@', $password);

        return $uppercase && $lowercase && $number && $specialChars && strlen($password) >= 8;
    }

    /**
     * Verificar si hay sesión activa (para AJAX)
     */
    public function verificar_sesion() {
        if (!$this->session->userdata('logged_in')) {
            echo json_encode(array('valid' => false));
            return;
        }

        $usuario_id = $this->session->userdata('user_id');
        $valid = $this->auth_model->validar_sesion($usuario_id);

        if (!$valid) {
            $this->session->sess_destroy();
            echo json_encode(array('valid' => false));
        } else {
            echo json_encode(array('valid' => true));
        }
    }
}