<?php
/**
 * ASISMA CRM - Usuarios Controller
 */
class UsuariosController extends Controller {

    public function index() {
        $db = Database::getInstance();

        $where = "u.activo IN (0,1)"; // Mostrar activos e inactivos
        $params = [];

        if (!SessionHelper::isAdmin()) {
            $where .= " AND u.franquiciado_id = :fid";
            $params['fid'] = SessionHelper::getFranquiciadoId();
        }

        $sql = "SELECT u.id, u.nombre, u.email, u.rol, u.telefono, u.ultimo_login, u.activo,
                       u.franquiciado_id, u.empresa_id,
                       ef.nombre_fantasia as empresa_nombre
                FROM usuarios u
                INNER JOIN empresas_franquiciados ef ON u.empresa_id = ef.id
                WHERE {$where}
                ORDER BY u.nombre ASC";

        $usuarios = $db->fetchAll($sql, $params);

        // Datos para el formulario de creación/edición
        $esFranquiciado = SessionHelper::getRol() === ROL_FRANQUICIADO;

        if ($esFranquiciado) {
            $fid = SessionHelper::getFranquiciadoId();
            $eid = SessionHelper::getEmpresaId();
            $franquiciados = $db->fetchAll(
                "SELECT f.id, ef.nombre_fantasia FROM franquiciados f
                 INNER JOIN empresas_franquiciados ef ON f.empresa_madre_id = ef.id
                 WHERE f.id = :fid",
                array('fid' => $fid)
            );
            $empresas = $db->fetchAll(
                "SELECT id, nombre_fantasia, razon_social FROM empresas_franquiciados WHERE id = :eid",
                array('eid' => $eid)
            );
            $rolesDisponibles = array(ROL_VENDEDOR => arr_roles()[ROL_VENDEDOR]);
        } else {
            $franquiciados = $db->fetchAll(
                "SELECT f.id, ef.nombre_fantasia FROM franquiciados f
                 INNER JOIN empresas_franquiciados ef ON f.empresa_madre_id = ef.id
                 WHERE f.estado = 'activo' ORDER BY ef.nombre_fantasia ASC"
            );
            $empresas = $db->fetchAll(
                "SELECT id, nombre_fantasia, razon_social FROM empresas_franquiciados WHERE activa = 1 ORDER BY nombre_fantasia ASC"
            );
            $rolesDisponibles = arr_roles();
        }

        $this->render('usuarios/index', array(
            'title'          => 'Gestion de Usuarios y Accesos',
            'usuarios'       => $usuarios,
            'franquiciados'  => $franquiciados,
            'empresas'       => $empresas,
            'modulos'        => arr_modulos_permisos(),
            'roles'          => $rolesDisponibles,
            'esFranquiciado' => $esFranquiciado
        ));
    }

    /**
     * Crear nuevo usuario (AJAX POST)
     */
    public function crear() {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->json(['success' => false, 'message' => 'Método no soportado.'], 405);
        }

        $nombre   = $this->input('nombre', '');
        $email    = $this->input('email', '');
        $password = isset($_POST['password']) ? $_POST['password'] : '';
        $telefono = $this->input('telefono', '');

        // Franquiciado solo puede crear vendedores de su propia franquicia
        if (!SessionHelper::isAdmin()) {
            $rol            = ROL_VENDEDOR;
            $franquiciadoId = SessionHelper::getFranquiciadoId();
            $empresaId      = SessionHelper::getEmpresaId();
        } else {
            $rol            = $this->input('rol', ROL_VENDEDOR);
            $franquiciadoId = (int)$this->input('franquiciado_id') ?: null;
            $empresaId      = (int)$this->input('empresa_id');
        }

        $permisos = isset($_POST['permisos']) ? $_POST['permisos'] : array();

        if (empty($nombre) || empty($email) || empty($password) || $empresaId <= 0) {
            $this->json(array('success' => false, 'message' => 'Nombre, email y contraseña son obligatorios.'));
        }

        $errorClave = ClaveHelper::validar($password);
        if ($errorClave !== null) {
            $this->json(array('success' => false, 'message' => $errorClave));
        }

        if (!array_key_exists($rol, arr_roles())) {
            $this->json(array('success' => false, 'message' => 'Rol no valido.'));
        }

        $db = Database::getInstance();

        $existe = $db->fetchOne("SELECT id FROM usuarios WHERE email = :email", ['email' => $email]);
        if ($existe) {
            $this->json(['success' => false, 'message' => 'Ya existe un usuario registrado con ese email.']);
        }

        // Construir JSON de permisos
        $permisosJson = null;
        if ($rol !== ROL_ADMIN && !empty($permisos)) {
            $permisosMap = [];
            foreach (array_keys(arr_modulos_permisos()) as $mod) {
                $permisosMap[$mod] = in_array($mod, $permisos);
            }
            $permisosJson = json_encode($permisosMap);
        }

        try {
            $uid = $db->insert('usuarios', [
                'empresa_id'      => $empresaId,
                'franquiciado_id' => $franquiciadoId,
                'rol'             => $rol,
                'nombre'          => $nombre,
                'email'           => $email,
                'password_hash'   => password_hash($password, PASSWORD_BCRYPT),
                'telefono'        => $telefono,
                'permisos'        => $permisosJson,
                'activo'          => 1
            ]);

            AuditHelper::log('create_usuario', 'usuarios', $uid, null, ['email' => $email, 'rol' => $rol]);
            $this->json(['success' => true, 'message' => 'Usuario creado exitosamente.']);

        } catch (Exception $e) {
            error_log("Error al crear usuario: " . $e->getMessage());
            $this->json(['success' => false, 'message' => 'Error de base de datos al crear usuario.']);
        }
    }

    /**
     * Editar usuario existente (AJAX POST)
     */
    public function editar() {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->json(['success' => false, 'message' => 'Método no soportado.'], 405);
        }

        $id       = (int)$this->input('id');
        $nombre   = $this->input('nombre', '');
        $email    = $this->input('email', '');
        $telefono = $this->input('telefono', '');
        $permisos = isset($_POST['permisos']) ? $_POST['permisos'] : array();

        if (!SessionHelper::isAdmin()) {
            $rol            = ROL_VENDEDOR;
            $franquiciadoId = SessionHelper::getFranquiciadoId();
            $empresaId      = SessionHelper::getEmpresaId();
        } else {
            $rol            = $this->input('rol', ROL_VENDEDOR);
            $franquiciadoId = (int)$this->input('franquiciado_id') ?: null;
            $empresaId      = (int)$this->input('empresa_id');
        }

        if ($id <= 0 || empty($nombre) || empty($email)) {
            $this->json(array('success' => false, 'message' => 'Datos incompletos.'));
        }

        $db = Database::getInstance();

        $usuario = $db->fetchOne("SELECT * FROM usuarios WHERE id = :id", array('id' => $id));
        if (!$usuario) {
            $this->json(array('success' => false, 'message' => 'Usuario no encontrado.'));
        }

        // Franquiciado solo puede editar usuarios de su propia franquicia
        if (!SessionHelper::isAdmin() && $usuario['franquiciado_id'] != SessionHelper::getFranquiciadoId()) {
            $this->json(array('success' => false, 'message' => 'Sin permisos para editar este usuario.'), 403);
        }

        // Verificar email duplicado (excluyendo el usuario actual)
        $existe = $db->fetchOne("SELECT id FROM usuarios WHERE email = :email AND id != :id", ['email' => $email, 'id' => $id]);
        if ($existe) {
            $this->json(['success' => false, 'message' => 'El email ya está en uso por otro usuario.']);
        }

        // Construir JSON de permisos
        $permisosJson = $usuario['permisos'];
        if ($rol !== ROL_ADMIN) {
            $permisosMap = [];
            foreach (array_keys(arr_modulos_permisos()) as $mod) {
                $permisosMap[$mod] = in_array($mod, $permisos);
            }
            $permisosJson = json_encode($permisosMap);
        }

        try {
            $db->update('usuarios', [
                'nombre'          => $nombre,
                'email'           => $email,
                'rol'             => $rol,
                'telefono'        => $telefono,
                'empresa_id'      => $empresaId,
                'franquiciado_id' => $franquiciadoId,
                'permisos'        => $permisosJson
            ], "id = :id", ['id' => $id]);

            AuditHelper::log('edit_usuario', 'usuarios', $id, $usuario, ['email' => $email, 'rol' => $rol]);
            $this->json(['success' => true, 'message' => 'Usuario actualizado correctamente.']);

        } catch (Exception $e) {
            error_log("Error al editar usuario: " . $e->getMessage());
            $this->json(['success' => false, 'message' => 'Error de base de datos al actualizar usuario.']);
        }
    }

    /**
     * Activar / Desactivar usuario (AJAX POST)
     */
    public function toggleActivo() {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->json(['success' => false, 'message' => 'Método no soportado.'], 405);
        }

        $id = (int)$this->input('id');
        if ($id <= 0) {
            $this->json(['success' => false, 'message' => 'ID inválido.']);
        }

        // No se puede desactivar a sí mismo
        if ($id === SessionHelper::getUsuarioId()) {
            $this->json(['success' => false, 'message' => 'No puede desactivar su propio usuario.']);
        }

        $db = Database::getInstance();
        $usuario = $db->fetchOne("SELECT id, activo FROM usuarios WHERE id = :id", ['id' => $id]);
        if (!$usuario) {
            $this->json(['success' => false, 'message' => 'Usuario no encontrado.']);
        }

        $nuevoActivo = $usuario['activo'] ? 0 : 1;
        $db->update('usuarios', ['activo' => $nuevoActivo], "id = :id", ['id' => $id]);

        AuditHelper::log('toggle_usuario', 'usuarios', $id, ['activo' => $usuario['activo']], ['activo' => $nuevoActivo]);

        $this->json(['success' => true, 'activo' => $nuevoActivo, 'message' => $nuevoActivo ? 'Usuario activado.' : 'Usuario desactivado.']);
    }

    /**
     * Resetear contraseña de un usuario (AJAX POST)
     */
    public function resetPassword() {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->json(['success' => false, 'message' => 'Método no soportado.'], 405);
        }

        $id          = (int)$this->input('id');
        $newPassword = isset($_POST['new_password']) ? $_POST['new_password'] : '';

        if ($id <= 0) {
            $this->json(['success' => false, 'message' => 'ID de usuario inválido.']);
        }

        $errorClave = ClaveHelper::validar($newPassword);
        if ($errorClave !== null) {
            $this->json(['success' => false, 'message' => $errorClave]);
        }

        $db = Database::getInstance();
        $usuario = $db->fetchOne("SELECT id FROM usuarios WHERE id = :id", ['id' => $id]);
        if (!$usuario) {
            $this->json(['success' => false, 'message' => 'Usuario no encontrado.']);
        }

        $db->update('usuarios', ['password_hash' => password_hash($newPassword, PASSWORD_BCRYPT)], "id = :id", ['id' => $id]);

        AuditHelper::log('reset_password', 'usuarios', $id, null, ['accion' => 'contraseña_reseteada']);

        $this->json(['success' => true, 'message' => 'Contraseña actualizada correctamente.']);
    }

    /**
     * Obtener datos de usuario para el formulario de edición (AJAX GET)
     */
    public function getData() {
        $id = (int)$this->input('id');
        if ($id <= 0) {
            $this->json(['success' => false, 'message' => 'ID inválido.']);
        }

        $db = Database::getInstance();
        $u = $db->fetchOne(
            "SELECT id, nombre, email, rol, telefono, empresa_id, franquiciado_id, permisos FROM usuarios WHERE id = :id",
            ['id' => $id]
        );

        if (!$u) {
            $this->json(['success' => false, 'message' => 'No encontrado.']);
        }

        $u['permisos_decoded'] = !empty($u['permisos']) ? json_decode($u['permisos'], true) : [];
        $this->json(['success' => true, 'data' => $u]);
    }
}
