<?php
/**
 * Acciones del Módulo de Usuarios (JSON)
 */

// Respuestas JSON por defecto
header('Content-Type: application/json');

// Iniciar sesión si no está iniciada
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

// Definir BASE_PATH si no está definido
if (!defined('BASE_PATH')) {
    define('BASE_PATH', dirname(dirname(__DIR__))); // .../simple_crm
}

// Incluir configuración y conexión de base de datos
require_once BASE_PATH . '/database/config.php';
require_once BASE_PATH . '/database/connection.php';

// Helper de autenticación si no existe
if (!function_exists('isLoggedIn')) {
    function isLoggedIn() {
        return isset($_SESSION['user_id']) && !empty($_SESSION['user_id']);
    }
}

if (!isLoggedIn()) {
    http_response_code(401);
    echo json_encode(['success' => false, 'message' => 'No autorizado']);
    exit;
}

$db = getDB()->getConnection();
$action = $_GET['action'] ?? '';

function userHasPermission($perm) {
    if (!isset($_SESSION['user_id'])) return false;
    $uid = (int)$_SESSION['user_id'];
    global $db;
    $stmt = $db->prepare("SELECT 1 FROM permissions p INNER JOIN role_permissions rp ON p.id = rp.permission_id INNER JOIN user_roles ur ON rp.role_id = ur.role_id WHERE ur.user_id = ? AND CONCAT(p.module, '.', p.action) = ? LIMIT 1");
    $stmt->execute([$uid, $perm]);
    return (bool)$stmt->fetchColumn();
}

function requirePermission($perm) {
    if (!userHasPermission($perm)) {
        http_response_code(403);
        echo json_encode(['success' => false, 'error' => 'Permiso denegado: ' . $perm]);
        exit;
    }
}

function isVoisoConfigured(PDO $db): bool {
    try {
        $stmt = $db->prepare("SELECT setting_key, setting_value FROM integration_settings WHERE integration_name='voiso' AND setting_key IN ('api_base_url','api_token')");
        $stmt->execute();
        $vals = [];
        while ($r = $stmt->fetch(PDO::FETCH_ASSOC)) { $vals[$r['setting_key']] = trim((string)$r['setting_value']); }
        return !empty($vals['api_base_url']) && !empty($vals['api_token']);
    } catch (Exception $e) { return false; }
}

function columnExists(PDO $db, string $table, string $column): bool {
    try {
        $stmt = $db->prepare("SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ? LIMIT 1");
        $stmt->execute([$table, $column]);
        return (bool)$stmt->fetchColumn();
    } catch (Exception $e) {
        return false;
    }
}

switch ($action) {
    case 'create':
        requirePermission('users.create');
        createUser();
        break;
    case 'update':
        requirePermission('users.edit');
        updateUser();
        break;
    case 'delete':
        requirePermission('users.delete');
        deleteUser();
        break;
    case 'get_details':
        requirePermission('users.view');
        getUserDetails();
        break;
    default:
        http_response_code(400);
        echo json_encode(['error' => 'Acción no válida']);
        break;
}

/**
 * Crear usuario
 */
function createUser() {
    global $db;

    try {
        $username    = trim($_POST['username'] ?? '');
        $email       = trim($_POST['email'] ?? '');
        $first_name  = trim($_POST['first_name'] ?? '');
        $last_name   = trim($_POST['last_name'] ?? '');
        $password    = $_POST['password'] ?? '';
        $voiso_ext   = trim($_POST['voiso_extension'] ?? '');
        $status      = $_POST['status'] ?? 'active';
        $roles       = isset($_POST['roles']) ? (array)$_POST['roles'] : [];
        $desk_id     = isset($_POST['desk_id']) ? (int)$_POST['desk_id'] : 0;

        if ($username === '' || $email === '' || $password === '' || $first_name === '' || $last_name === '') {
            throw new Exception('Campos requeridos: usuario, email, contraseña, nombre, apellido');
        }

        // Validar duplicados
        $stmt = $db->prepare("SELECT id FROM users WHERE username = ? OR email = ? LIMIT 1");
        $stmt->execute([$username, $email]);
        if ($stmt->fetch(PDO::FETCH_ASSOC)) {
            throw new Exception('Usuario o email ya existen');
        }

        $password_hash = password_hash($password, PASSWORD_DEFAULT);

        // Insertar usuario
        $stmt = $db->prepare("INSERT INTO users (username, email, password_hash, first_name, last_name, status, created_at) VALUES (?, ?, ?, ?, ?, ?, NOW())");
        $stmt->execute([$username, $email, $password_hash, $first_name, $last_name, $status]);
        $user_id = (int)$db->lastInsertId();

        // Asignar extensión Voiso si está configurado el sistema y el valor se proporcionó
        if ($voiso_ext !== '' && isVoisoConfigured($db) && columnExists($db, 'users', 'voiso_extension')) {
            try {
                $db->prepare("UPDATE users SET voiso_extension = ? WHERE id = ?")->execute([$voiso_ext, $user_id]);
            } catch (Exception $e) { /* ignorar errores menores */ }
        }

        // Asignar roles
        if (!empty($roles)) {
            $assign = $db->prepare("INSERT INTO user_roles (user_id, role_id, assigned_at) VALUES (?, ?, NOW())");
            foreach ($roles as $role_id) {
                $assign->execute([$user_id, (int)$role_id]);
            }
        }

        // Asignar desk (opcional, uno)
        if ($desk_id > 0) {
            // Validar que el desk existe y está activo
            $dchk = $db->prepare("SELECT id FROM desks WHERE id = ? AND status = 'active' LIMIT 1");
            $dchk->execute([$desk_id]);
            if ($dchk->fetch(PDO::FETCH_ASSOC)) {
                $du = $db->prepare("INSERT INTO desk_users (desk_id, user_id, assigned_at) VALUES (?, ?, NOW())");
                $du->execute([$desk_id, $user_id]);
            }
        }

        echo json_encode([
            'success' => true,
            'message' => 'Usuario creado exitosamente',
            'user_id' => $user_id
        ]);
    } catch (Exception $e) {
        http_response_code(400);
        echo json_encode(['error' => $e->getMessage()]);
    }
}

/**
 * Obtener detalles del usuario
 */
function getUserDetails() {
    global $db;

    try {
        $user_id = (int)($_GET['user_id'] ?? 0);
        if ($user_id <= 0) {
            throw new Exception('ID de usuario inválido');
        }

        $cols = "id, username, email, first_name, last_name, status, last_login, created_at";
        if (columnExists($db, 'users', 'voiso_extension')) { $cols .= ", voiso_extension"; }
        $stmt = $db->prepare("SELECT $cols FROM users WHERE id = ?");
        $stmt->execute([$user_id]);
        $user = $stmt->fetch(PDO::FETCH_ASSOC);
        if (!$user) {
            throw new Exception('Usuario no encontrado');
        }

        $roles_stmt = $db->prepare("SELECT r.id, r.display_name FROM roles r INNER JOIN user_roles ur ON r.id = ur.role_id WHERE ur.user_id = ? ORDER BY r.display_name");
        $roles_stmt->execute([$user_id]);
        $roles = $roles_stmt->fetchAll(PDO::FETCH_ASSOC);

        // Desk asignado (último)
        $desk_stmt = $db->prepare("SELECT d.id, d.name FROM desks d INNER JOIN desk_users du ON d.id = du.desk_id WHERE du.user_id = ? ORDER BY du.assigned_at DESC LIMIT 1");
        $desk_stmt->execute([$user_id]);
        $desk = $desk_stmt->fetch(PDO::FETCH_ASSOC) ?: null;

        echo json_encode(['user' => $user, 'roles' => $roles, 'desk' => $desk]);
    } catch (Exception $e) {
        http_response_code(400);
        echo json_encode(['error' => $e->getMessage()]);
    }
}

/**
 * Actualizar usuario
 */
function updateUser() {
    global $db;

    try {
        $user_id    = (int)($_POST['user_id'] ?? 0);
        $email      = trim($_POST['email'] ?? '');
        $first_name = trim($_POST['first_name'] ?? '');
        $last_name  = trim($_POST['last_name'] ?? '');
        $status     = $_POST['status'] ?? 'active';
        $password   = $_POST['password'] ?? '';
        $roles      = isset($_POST['roles']) ? (array)$_POST['roles'] : [];
        $desk_id    = isset($_POST['desk_id']) ? (int)$_POST['desk_id'] : 0;
        $voiso_ext  = trim($_POST['voiso_extension'] ?? '');

        if ($user_id <= 0 || $email === '' || $first_name === '' || $last_name === '') {
            throw new Exception('ID de usuario, email, nombre y apellido son requeridos');
        }

        // Validar email único
        $stmt = $db->prepare("SELECT id FROM users WHERE email = ? AND id <> ? LIMIT 1");
        $stmt->execute([$email, $user_id]);
        if ($stmt->fetch(PDO::FETCH_ASSOC)) {
            throw new Exception('El email ya está en uso por otro usuario');
        }

        if ($password !== '') {
            $password_hash = password_hash($password, PASSWORD_DEFAULT);
            $upd = $db->prepare("UPDATE users SET email = ?, first_name = ?, last_name = ?, status = ?, password_hash = ?, updated_at = NOW() WHERE id = ?");
            $upd->execute([$email, $first_name, $last_name, $status, $password_hash, $user_id]);
        } else {
            $upd = $db->prepare("UPDATE users SET email = ?, first_name = ?, last_name = ?, status = ?, updated_at = NOW() WHERE id = ?");
            $upd->execute([$email, $first_name, $last_name, $status, $user_id]);
        }

        // Selección segura de columnas, evitando error si falta voiso_extension
        $cols = "id, username, email, first_name, last_name, status, last_login, created_at";
        if (columnExists($db, 'users', 'voiso_extension')) { $cols .= ", voiso_extension"; }
        $stmt = $db->prepare("SELECT $cols FROM users WHERE id = ?");
        $stmt->execute([$user_id]);
        // Actualizar extensión Voiso solo si la integración está configurada y existe la columna
        if (isVoisoConfigured($db) && columnExists($db, 'users', 'voiso_extension')) {
        // Permitir limpiar la extensión enviando cadena vacía
        $db->prepare("UPDATE users SET voiso_extension = ? WHERE id = ?")->execute([$voiso_ext !== '' ? $voiso_ext : null, $user_id]);
        }

        // Sincronizar roles
        $db->beginTransaction();
        $db->prepare("DELETE FROM user_roles WHERE user_id = ?")->execute([$user_id]);
        if (!empty($roles)) {
            $assign = $db->prepare("INSERT INTO user_roles (user_id, role_id, assigned_at) VALUES (?, ?, NOW())");
            foreach ($roles as $role_id) {
                $assign->execute([$user_id, (int)$role_id]);
            }
        }
        // Sincronizar desk (simple: uno)
        $db->prepare("DELETE FROM desk_users WHERE user_id = ?")->execute([$user_id]);
        if ($desk_id > 0) {
            $dchk = $db->prepare("SELECT id FROM desks WHERE id = ? AND status = 'active' LIMIT 1");
            $dchk->execute([$desk_id]);
            if ($dchk->fetch(PDO::FETCH_ASSOC)) {
                $du = $db->prepare("INSERT INTO desk_users (desk_id, user_id, assigned_at) VALUES (?, ?, NOW())");
                $du->execute([$desk_id, $user_id]);
            }
        }
        $db->commit();

        echo json_encode(['success' => true, 'message' => 'Usuario actualizado exitosamente']);
    } catch (Exception $e) {
        if ($db->inTransaction()) { $db->rollBack(); }
        http_response_code(400);
        echo json_encode(['error' => $e->getMessage()]);
    }
}

/**
 * Eliminar usuario
 */
function deleteUser() {
    global $db;

    try {
        $user_id = (int)($_POST['user_id'] ?? 0);
        if ($user_id <= 0) {
            throw new Exception('ID de usuario inválido');
        }
        if (isset($_SESSION['user_id']) && $user_id === (int)$_SESSION['user_id']) {
            throw new Exception('No puedes eliminar tu propia cuenta');
        }

        $db->beginTransaction();
        $db->prepare("DELETE FROM user_roles WHERE user_id = ?")->execute([$user_id]);
        $db->prepare("DELETE FROM users WHERE id = ?")->execute([$user_id]);
        $db->commit();

        echo json_encode(['success' => true, 'message' => 'Usuario eliminado exitosamente']);
    } catch (Exception $e) {
        if ($db->inTransaction()) { $db->rollBack(); }
        http_response_code(400);
        echo json_encode(['error' => $e->getMessage()]);
    }
}

?>