<?php
// /users.php
// v3: Full Responsive & Unified Grid View

// --- 1. GESTIÓN DE SESIÓN Y PERMISOS ---
session_start();
if (!isset($_SESSION['user_id'])) {
    header('Location: index.php');
    exit;
}
if ($_SESSION['user_rol'] === 'paciente') {
    header('Location: patient_dashboard.php');
    exit;
}

require_once 'db.php';
require_once 'mail_helpers.php';
require_once 'logger.php';
$user_rol = $_SESSION['user_rol'];
$user_id = $_SESSION['user_id'];
if (!defined('RECORDS_PER_PAGE')) {
    define('RECORDS_PER_PAGE', $_SESSION['records_per_page'] ?? 8);
}

// --- OBTENER PREFERENCIA DE FILTRO Y VISTA DEL USUARIO ---
$filtro_defecto = 0;
$user_view_prefs_json = '{}';
if (in_array($user_rol, ['superadmin', 'fisio'])) {
    $stmt_prefs = $db->prepare("SELECT filtro_personal_defecto, vista_defecto FROM cuentas WHERE id = ?");
    $stmt_prefs->execute([$user_id]);
    if ($user_prefs = $stmt_prefs->fetch(PDO::FETCH_ASSOC)) {
        $filtro_defecto = $user_prefs['filtro_personal_defecto'];
        $user_view_prefs_json = $user_prefs['vista_defecto'] ?? '{}';
    }
}

// --- 2. GESTOR DE PETICIONS AJAX ---
if (isset($_REQUEST['ajax'])) {
    header('Content-Type: application/json');
    $action = $_REQUEST['action'] ?? 'read_pacients';

    try {
        switch ($action) {
            case 'read_pacients':
            case 'read_fisios':
                $rol_to_read = ($action === 'read_pacients') ? 'paciente' : 'fisio';
                if ($rol_to_read === 'fisio' && $user_rol !== 'superadmin') { throw new Exception('Accés denegat.'); }

                $page = (int)($_GET['page'] ?? 1);
                $search = $_GET['search'] ?? '';
                $statusFilter = $_GET['statusFilter'] ?? 'activo';
                $validFilters = ['activo', 'baja', 'tots', 'auto_registre'];
                if (!in_array($statusFilter, $validFilters)) { $statusFilter = 'activo'; }

                $valid_sorts = ['apellido', 'fecha_creacion', 'registrar_name'];
                $sort = in_array($_GET['sort'] ?? '', $valid_sorts) ? $_GET['sort'] : 'fecha_creacion';
                $order = ($_GET['order'] ?? 'DESC') === 'ASC' ? 'ASC' : 'DESC';
                $filterMine = ($_GET['filterMine'] ?? 'false') === 'true';

                $params = [
                    ':search' => '%' . $search . '%',
                    ':user_id_for_access' => $user_id
                ];

                if ($rol_to_read === 'fisio') {
                    $whereClause = "WHERE c.rol IN ('fisio', 'superadmin') AND (c.nombre LIKE :search OR c.apellido LIKE :search OR c.email LIKE :search)";
                } else { // 'paciente'
                    $whereClause = "WHERE c.rol = :rol AND (c.nombre LIKE :search OR c.apellido LIKE :search OR c.email LIKE :search)";
                    $params[':rol'] = $rol_to_read;
                }

                if ($statusFilter === 'activo' || $statusFilter === 'baja') {
                    $whereClause .= " AND c.status = :status";
                    $params[':status'] = $statusFilter;
                } elseif ($statusFilter === 'auto_registre' && $rol_to_read === 'paciente') {
                    $whereClause .= " AND c.id_fisio_registrador IS NULL AND c.status = 'activo'";
                }

                if ($filterMine && $rol_to_read === 'paciente') {
                    $whereClause .= " AND c.id_fisio_registrador = :user_id";
                    $params[':user_id'] = $user_id;
                }

                $sql_access_check = "
                    EXISTS (
                        SELECT 1 FROM tratamientos t
                        LEFT JOIN tratamiento_fisios_asignados tfa ON t.id = tfa.tratamiento_id
                        WHERE t.paciente_id = c.id
                          AND (t.creator_fisio_id = :user_id_for_access OR tfa.fisio_id = :user_id_for_access)
                    )
                ";

                $totalQuery = "SELECT COUNT(*) FROM cuentas c $whereClause";
                $totalStmt = $db->prepare($totalQuery);
                $totalParams = $params;
                unset($totalParams[':user_id_for_access']);
                $totalStmt->execute($totalParams);
                $totalRecords = $totalStmt->fetchColumn();
                $totalPages = ceil($totalRecords / RECORDS_PER_PAGE);

                $offset = ($page - 1) * RECORDS_PER_PAGE;

                $orderByColumn = match ($sort) {
                    'apellido' => 'LOWER(c.apellido)',
                    'fecha_creacion' => 'c.fecha_creacion',
                    'registrar_name' => 'LOWER(reg.apellido)',
                    default => 'LOWER(c.apellido)',
                };

                $dataQuery = "SELECT c.id, c.nombre, c.apellido, c.email, c.telefono, c.fecha_creacion, c.rol, c.status, c.fecha_baja, c.motivo_baja,
                                     c.id_fisio_registrador,
                                     c.avatar,
                                     ($sql_access_check) as has_treatment_access,
                                     CONCAT(reg.nombre, ' ', reg.apellido) as nombre_fisio_registrador
                              FROM cuentas c
                              LEFT JOIN cuentas reg ON c.id_fisio_registrador = reg.id
                              $whereClause
                              ORDER BY $orderByColumn $order
                              LIMIT :limit OFFSET :offset";

                $dataStmt = $db->prepare($dataQuery);
                foreach ($params as $key => $val) $dataStmt->bindValue($key, $val);
                $dataStmt->bindValue(':limit', RECORDS_PER_PAGE, PDO::PARAM_INT);
                $dataStmt->bindValue(':offset', $offset, PDO::PARAM_INT);
                $dataStmt->execute();
                $users = $dataStmt->fetchAll(PDO::FETCH_ASSOC);

                foreach ($users as &$user) {
                    $user['initials'] = strtoupper(mb_substr($user['nombre'] ?? '', 0, 1) . mb_substr($user['apellido'] ?? '', 0, 1));
                    if ($rol_to_read === 'paciente' && empty($user['nombre_fisio_registrador'])) {
                        $user['nombre_fisio_registrador'] = 'Auto-registre';
                    }
                }

                echo json_encode(['status' => 'success', 'data' => $users, 'pagination' => ['currentPage' => $page, 'totalPages' => $totalPages, 'currentSort' => $sort, 'currentOrder' => $order]]);
                break;

            case 'get_user_data':
                $user_to_edit_id = (int)$_GET['id'];
                 if ($user_rol === 'fisio') {
                     $stmt = $db->prepare("SELECT id, nombre, apellido, email, telefono, avatar, fecha_creacion, rol, status, motivo_baja, fecha_baja FROM cuentas WHERE id = ? AND rol = 'paciente'");
                 } else { // Superadmin
                     $stmt = $db->prepare("SELECT id, nombre, apellido, email, telefono, avatar, fecha_creacion, rol, status, motivo_baja, fecha_baja FROM cuentas WHERE id = ?");
                 }
                 $stmt->execute([$user_to_edit_id]);
                 $user_data = $stmt->fetch(PDO::FETCH_ASSOC);
                 if (!$user_data) { throw new Exception('Usuari no trobat o sense permisos.'); }

                 if ($user_data['fecha_creacion']) {
                     try { $user_data['fecha_creacion_formatted'] = (new DateTime($user_data['fecha_creacion']))->format('d/m/Y H:i'); }
                     catch (Exception $e) { $user_data['fecha_creacion_formatted'] = 'Data invàlida'; }
                 } else { $user_data['fecha_creacion_formatted'] = 'N/A'; }

                 if ($user_data['fecha_baja']) {
                     try { $user_data['fecha_baja_formatted'] = (new DateTime($user_data['fecha_baja']))->format('d/m/Y'); }
                     catch (Exception $e) { $user_data['fecha_baja_formatted'] = 'Data invàlida'; }
                 } else { $user_data['fecha_baja_formatted'] = null; }

                 echo json_encode(['status' => 'success', 'data' => $user_data]);
                 break;

            case 'check_superadmin_count':
                if ($user_rol !== 'superadmin') { throw new Exception('Accés denegat.'); }
                $stmt_count = $db->query("SELECT COUNT(id) FROM cuentas WHERE rol = 'superadmin' AND status = 'activo'");
                $count = $stmt_count->fetchColumn();
                echo json_encode(['status' => 'success', 'count' => $count]);
                break;

            case 'update_user':
                $user_to_update_id = (int)$_POST['id'];
                if (!in_array($user_rol, ['superadmin', 'fisio'])) { throw new Exception('Accés denegat.'); }
                $nombre = trim($_POST['nombre']); $apellido = trim($_POST['apellido']); $telefono = trim($_POST['telefono']);
                $motivo_baja = trim($_POST['motivo_baja']) ?: null;
                if (empty($nombre) || empty($apellido)) { throw new Exception('Nom i cognoms són obligatoris.'); }
                $stmt_role = $db->prepare("SELECT rol, email FROM cuentas WHERE id = ?"); $stmt_role->execute([$user_to_update_id]); $current_data = $stmt_role->fetch(PDO::FETCH_ASSOC);
                if (!$current_data) { throw new Exception("L'usuari que intentes actualitzar no existeix."); }
                $current_rol = $current_data['rol']; $current_email = $current_data['email'];

                if ($user_rol === 'superadmin' && isset($_POST['rol'])) {
                    $new_rol = $_POST['rol'];
                    if (in_array($new_rol, ['paciente', 'fisio', 'superadmin'])) {
                        if ($current_rol === 'superadmin' && $new_rol !== 'superadmin' && $user_to_update_id != $user_id) {
                            $stmt_count = $db->query("SELECT COUNT(id) FROM cuentas WHERE rol = 'superadmin' AND status = 'activo'");
                            if ($stmt_count->fetchColumn() <= 1) { throw new Exception("No es pot canviar el rol de l'últim Superadmin."); }
                        }
                        if($user_to_update_id == $user_id && $new_rol !== 'superadmin') { throw new Exception("No pots canviar el teu propi rol."); }
                        $current_rol = $new_rol;
                    }
                }

                $stmt = $db->prepare("UPDATE cuentas SET nombre = ?, apellido = ?, telefono = ?, email = ?, rol = ?, motivo_baja = ? WHERE id = ?");
                $stmt->execute([$nombre, $apellido, $telefono, $current_email, $current_rol, $motivo_baja, $user_to_update_id]);

                if($current_rol === 'paciente') {
                    $log_details_update = "Datos personales del Paciente ID: $user_to_update_id actualizados. Nombre: $nombre $apellido";
                    registrar_log($db, 'PATIENT_MODIFIED', $user_id, $_SESSION['user_nombre'], $log_details_update, $user_to_update_id, null);
                }

                echo json_encode(['status' => 'success', 'message' => 'Dades de l\'usuari actualitzades.', 'saved_user_id' => $user_to_update_id]);
                break;

            case 'create_user':
                $rol_a_crear = $_POST['rol'];
                if ($user_rol === 'fisio' && $rol_a_crear !== 'paciente') { throw new Exception('No tens permís per a crear este tipus d\'usuari.'); }
                if ($user_rol !== 'superadmin' && $rol_a_crear === 'superadmin') { throw new Exception('Només un Superadmin pot crear altres Superadmins.'); }
                if (!in_array($rol_a_crear, ['paciente', 'fisio', 'superadmin'])) { throw new Exception('Rol no vàlid.'); }

                $nombre = trim($_POST['nombre']); $apellido = trim($_POST['apellido']); $email = trim($_POST['email']); $telefono = trim($_POST['telefono']); $password = $_POST['password']; $password_confirm = $_POST['password_confirm'];
                if (empty($nombre) || empty($apellido) || empty($email) || empty($password)) { throw new Exception('Tots els camps amb * són obligatoris.'); }
                if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { throw new Exception("El format de l'email no és vàlid."); }
                if ($password !== $password_confirm) { throw new Exception('Les contrasenyes no coincideixen.'); }
                if (!preg_match('/^(?=.*\d)(?=.*[A-Z]).{6,12}$/', $password)) { throw new Exception('La contrasenya ha de tindre entre 6 i 12 caràcters, amb una majúscula i un número.'); }
                $stmt = $db->prepare("SELECT id FROM cuentas WHERE email = ?"); $stmt->execute([$email]);
                if ($stmt->fetch()) { throw new Exception("L'email ja està registrat."); }
                $hashed_password = password_hash($password, PASSWORD_DEFAULT);
                $id_fisio_registrador = ($rol_a_crear === 'paciente') ? $user_id : null;

                $stmt = $db->prepare("INSERT INTO cuentas (nombre, apellido, email, telefono, password, rol, id_fisio_registrador, status, is_archived) VALUES (?, ?, ?, ?, ?, ?, ?, 'activo', 0)");
                $stmt->execute([$nombre, $apellido, $email, $telefono, $hashed_password, $rol_a_crear, $id_fisio_registrador]);
                $nuevo_user_id = $db->lastInsertId();

                $log_details_create = "Nuevo usuario CREADO (ID: $nuevo_user_id). Rol: $rol_a_crear. Email: $email";
                registrar_log($db, 'USER_REGISTERED', $user_id, $_SESSION['user_nombre'], $log_details_create, $nuevo_user_id, null);

                $stmt_check = $db->prepare("SELECT is_enabled FROM email_settings WHERE setting_name = 'new_user_admin' LIMIT 1");
                $stmt_check->execute();

                if ($stmt_check->fetchColumn() == 1) {
                                    try {
                                        // --- ★ CÓDIGO A INSERTAR: DETECCIÓN DINÁMICA DE URL ★ ---
                                        $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
                                        $domain = $_SERVER['HTTP_HOST'];
                                        // Detectar carpeta actual y eliminar barras finales
                                        $path = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/');
                                        $base_url = $protocol . $domain . $path . '/';
                                        // --- ★ FIN CÓDIGO A INSERTAR ★ ---

                                        $logo_path = __DIR__ . '/logos/img_defecte.png';
                                        $embedded_logo = [['path' => $logo_path, 'cid' => 'logo_avant']];

                                        // --- ★ LÍNEA MODIFICADA: Se cambia el href fijo por $base_url ★ ---
                                        $body_nuevo_usuario = "<div style='font-family: Arial, sans-serif; line-height: 1.6; max-width: 600px; margin: auto; padding: 20px; border: 1px solid #ddd; border-radius: 8px;'><div style='text-align: center; margin-bottom: 20px;'><img src='cid:logo_avant' alt='Logo de la Clínica' style='width: 200px; height: auto;'></div><h1 style='color: #333; text-align: center; font-size: 24px;'>Benvingut/da, " . htmlspecialchars($nombre) . "!</h1><p>Un administrador d'AVANT ONLINE ha creat un compte per a tu.</p><ul style='list-style-type: none; padding-left: 0; background-color: #f9f9f9; border: 1px solid #eee; padding: 15px; border-radius: 5px;'><li><strong>Email:</strong> " . htmlspecialchars($email) . "</li><li><strong>Contrasenya Inicial:</strong> <strong style='font-size: 1.1em; color: #d9534f;'>" . htmlspecialchars($password) . "</strong></li></ul><p style='text-align: center; font-size: 0.9em; color: #555;'>(Et recomanem canviar aquesta contrasenya després del primer inici).</p><p style='text-align: center; margin-top: 30px;'><a href='" . $base_url . "' style='background-color: #0d6efd; color: white; padding: 12px 20px; text-decoration: none; border-radius: 5px; font-weight: bold;'>Accedir a la plataforma</a></p></div>";

                                        send_platform_email($email, "Benvingut/da a AVANT ONLINE!", $body_nuevo_usuario, true, $embedded_logo);
                                    } catch (Exception $e) { error_log("FALLO EMAIL: " . $e->getMessage()); }
                                }

                echo json_encode(['status' => 'success', 'message' => 'Usuari creat correctament.', 'saved_user_id' => $nuevo_user_id]);
                break;

            case 'dar_baja_usuario':
                if (!in_array($user_rol, ['superadmin', 'fisio'])) { throw new Exception('Accés denegat.'); }
                $user_to_deactivate_id = (int)$_POST['id'];
                $motivo_baja = trim($_POST['motivo_baja']) ?: null;

                $stmt_check = $db->prepare("SELECT rol, status FROM cuentas WHERE id = ?"); $stmt_check->execute([$user_to_deactivate_id]); $user_info = $stmt_check->fetch(PDO::FETCH_ASSOC);
                if (!$user_info) { throw new Exception("L'usuari no existeix."); }
                if ($user_info['status'] === 'baja') { throw new Exception("L'usuari ja està donat de baixa."); }
                if ($user_info['rol'] === 'fisio' && $user_rol !== 'superadmin') { throw new Exception('Només un administrador pot donar de baixa a un fisio.'); }
                if ($user_info['rol'] === 'superadmin' && $user_to_deactivate_id === $user_id) { throw new Exception('No pots donar de baixa el teu propi compte d\'administrador.'); }
                if ($user_info['rol'] === 'superadmin' && $user_rol === 'superadmin') {
                    $stmt_count = $db->query("SELECT COUNT(id) FROM cuentas WHERE rol = 'superadmin' AND status = 'activo'");
                    if ($stmt_count->fetchColumn() <= 1) { throw new Exception("No es pot donar de baixa a l'últim Superadmin actiu."); }
                }

                $db->beginTransaction();
                try {
                    $stmt_baja = $db->prepare("UPDATE cuentas SET status = 'baja', fecha_baja = CURDATE(), motivo_baja = ? WHERE id = ?");
                    $stmt_baja->execute([$motivo_baja, $user_to_deactivate_id]);

                    if ($user_info['rol'] === 'paciente') {
                        $stmt_treat = $db->prepare("UPDATE tratamientos SET status = 'Omés' WHERE paciente_id = ? AND status IN ('En curs', 'Programat')"); $stmt_treat->execute([$user_to_deactivate_id]);
                        $log_details_baja = "Paciente ID: $user_to_deactivate_id dado de BAJA. Motivo: " . ($motivo_baja ?: 'N/A');
                        registrar_log($db, 'PATIENT_ARCHIVED', $user_id, $_SESSION['user_nombre'], $log_details_baja, $user_to_deactivate_id, null);
                    }

                    $db->commit(); echo json_encode(['status' => 'success', 'message' => 'Usuari donat de baixa correctament.']);
                } catch (Exception $e) { $db->rollBack(); throw new Exception("Error en donar de baixa: " . $e->getMessage()); }
                break;

            case 'reactivar_usuario':
                 if (!in_array($user_rol, ['superadmin', 'fisio'])) { throw new Exception('Accés denegat.'); }
                 $user_to_reactivate_id = (int)$_POST['id'];
                 $stmt_check = $db->prepare("SELECT rol, status FROM cuentas WHERE id = ?"); $stmt_check->execute([$user_to_reactivate_id]); $user_info = $stmt_check->fetch(PDO::FETCH_ASSOC);
                 if (!$user_info) { throw new Exception("L'usuari no existeix."); }
                 if ($user_info['status'] === 'activo') { throw new Exception("L'usuari ja està actiu."); }
                 if ($user_info['rol'] === 'fisio' && $user_rol !== 'superadmin') { throw new Exception('Només un administrador pot reactivar a un fisio.'); }

                 $stmt_react = $db->prepare("UPDATE cuentas SET status = 'activo', fecha_baja = NULL WHERE id = ?");
                 $stmt_react->execute([$user_to_reactivate_id]);

                 if($user_info['rol'] === 'paciente') {
                     $log_details_react = "Paciente ID: $user_to_reactivate_id REACTIVADO.";
                     registrar_log($db, 'PATIENT_ARCHIVED', $user_id, $_SESSION['user_nombre'], $log_details_react, $user_to_reactivate_id, null);
                 }

                 echo json_encode(['status' => 'success', 'message' => 'Usuari reactivat correctament.']);
                 break;

            case 'delete_user':
                if ($user_rol !== 'superadmin') { throw new Exception('Accés denegat.'); }
                $user_to_delete_id = (int)$_POST['id'];
                $stmt_check = $db->prepare("SELECT rol, status, nombre, apellido FROM cuentas WHERE id = ?"); $stmt_check->execute([$user_to_delete_id]); $user_to_delete = $stmt_check->fetch(PDO::FETCH_ASSOC);
                if (!$user_to_delete) { throw new Exception("L'usuari no existeix."); }
                if ($user_to_delete['status'] !== 'baja') { throw new Exception("L'usuari ha d'estar 'de baixa' per a ser eliminat."); }

                if (in_array($user_to_delete['rol'], ['fisio', 'superadmin'])) {
                    $stmt_admin_check = $db->prepare("SELECT id FROM cuentas WHERE rol = 'superadmin' AND id != ? ORDER BY id LIMIT 1");
                    $stmt_admin_check->execute([$user_to_delete_id]);
                    $admin = $stmt_admin_check->fetch();
                    if (!$admin) { throw new Exception("No es pot eliminar l'únic Superadmin."); }
                    $admin_id = $admin['id'];

                    $db->beginTransaction();
                    try {
                        $db->prepare("UPDATE cuentas SET id_fisio_registrador = ? WHERE id_fisio_registrador = ?")->execute([$admin_id, $user_to_delete_id]);
                        $db->prepare("UPDATE videos SET id_uploader = ? WHERE id_uploader = ?")->execute([$admin_id, $user_to_delete_id]);
                        $db->prepare("UPDATE images SET id_uploader = ? WHERE id_uploader = ?")->execute([$admin_id, $user_to_delete_id]);
                        $db->prepare("UPDATE ejercicios SET id_creator = ? WHERE id_creator = ?")->execute([$admin_id, $user_to_delete_id]);
                        $db->prepare("UPDATE tratamientos SET creator_fisio_id = ? WHERE creator_fisio_id = ?")->execute([$admin_id, $user_to_delete_id]);
                        $db->prepare("DELETE FROM tratamiento_fisios_asignados WHERE fisio_id = ?")->execute([$user_to_delete_id]);
                        $db->prepare("DELETE FROM archivado_personal WHERE fisio_id = ?")->execute([$user_to_delete_id]);
                        $db->prepare("DELETE FROM cuentas WHERE id = ?")->execute([$user_to_delete_id]);
                        $db->commit(); echo json_encode(['status' => 'success', 'message' => 'Compte eliminat i recursos reassignats.']);
                    } catch (Exception $e) { $db->rollBack(); throw new Exception("Error: " . $e->getMessage()); }
                } else {
                    $db->beginTransaction();
                    try {
                        $log_details_delete = "Paciente ELIMINADO permanentemente (ID: $user_to_delete_id). Nombre: " . $user_to_delete['nombre'] . " " . $user_to_delete['apellido'];
                        registrar_log($db, 'PATIENT_DELETED', $user_id, $_SESSION['user_nombre'], $log_details_delete, $user_to_delete_id, null);

                        $stmt_treat_ids = $db->prepare("SELECT id FROM tratamientos WHERE paciente_id = ?"); $stmt_treat_ids->execute([$user_to_delete_id]); $treatment_ids = $stmt_treat_ids->fetchAll(PDO::FETCH_COLUMN);
                        if (!empty($treatment_ids)) {
                            $placeholders = implode(',', array_fill(0, count($treatment_ids), '?'));
                            $db->prepare("DELETE FROM tratamiento_evolucion WHERE tratamiento_ejercicio_id IN (SELECT id FROM tratamiento_ejercicios WHERE tratamiento_id IN ($placeholders))")->execute($treatment_ids);
                            $db->prepare("DELETE FROM tratamiento_ejercicios WHERE tratamiento_id IN ($placeholders)")->execute($treatment_ids);
                            $db->prepare("DELETE FROM tratamiento_fisios_asignados WHERE tratamiento_id IN ($placeholders)")->execute($treatment_ids);
                            $db->prepare("DELETE FROM tratamientos WHERE id IN ($placeholders)")->execute($treatment_ids);
                        }
                        $stmt = $db->prepare("DELETE FROM cuentas WHERE id = ?"); $stmt->execute([$user_to_delete_id]);
                        $db->commit();
                        echo json_encode(['status' => 'success', 'message' => 'Pacient eliminat permanentment.']);
                    } catch (Exception $e) { $db->rollBack(); throw new Exception("Error: " . $e->getMessage()); }
                }
                break;

            case 'update_preferences':
                if (!in_array($user_rol, ['superadmin', 'fisio'])) { throw new Exception('Accés denegat.'); }
                $filtro = isset($_POST['filtro_personal_defecto']) && $_POST['filtro_personal_defecto'] == 1 ? 1 : 0;
                $stmt = $db->prepare("UPDATE cuentas SET filtro_personal_defecto = ? WHERE id = ?");
                $stmt->execute([$filtro, $user_id]);
                echo json_encode(['status' => 'success', 'message' => 'Preferències actualitzades.']);
                break;

            case 'save_view_preference':
                if (!in_array($user_rol, ['superadmin', 'fisio'])) { throw new Exception('Accés denegat.'); }
                $page_name = $_POST['page_name'] ?? ''; $view_mode = $_POST['view_mode'] ?? '';
                if (empty($page_name) || !in_array($view_mode, ['grid', 'list'])) { throw new Exception('Dades invàlides.'); }
                $stmt_get = $db->prepare("SELECT vista_defecto FROM cuentas WHERE id = ?"); $stmt_get->execute([$user_id]); $current_prefs_json = $stmt_get->fetchColumn();
                $prefs = json_decode($current_prefs_json, true); if (!is_array($prefs)) { $prefs = []; }
                $prefs[$page_name] = $view_mode;
                $new_prefs_json = json_encode($prefs);
                $stmt_set = $db->prepare("UPDATE cuentas SET vista_defecto = ? WHERE id = ?"); $stmt_set->execute([$new_prefs_json, $user_id]);
                echo json_encode(['status' => 'success', 'message' => 'Preferència guardada.']);
                break;

            default:
                throw new Exception('Acció no vàlida.');
        }
    } catch (Exception $e) {
        if (isset($db) && $db->inTransaction()) $db->rollBack();
        http_response_code(400);
        error_log("Error AJAX users.php: " . $e->getMessage());
        echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
    }
    exit;
}

$page_title = "Gestió d'Usuaris - AVANT ONLINE";
include 'partials/header.php';
?>

<style>
    .status-badge { font-size: 0.75em; font-weight: 600; padding: 0.3em 0.6em; border-radius: 0.25rem; vertical-align: middle; }
    .status-badge.bg-success { background-color: #bbdefb !important; color: #1e88e5 !important; }
    .status-badge.bg-secondary { color: white !important; }
    .role-badge { font-size: 0.75em; font-weight: 600; padding: 0.3em 0.6em; border-radius: 0.25rem; vertical-align: middle; }
    .role-badge.bg-danger { background-color: #dc3545 !important; color: white !important; }
    .role-badge.bg-info { background-color: #0dcaf0 !important; color: #000 !important; }
    .contact-icon { margin-right: 0.5rem; font-size: 0.9em; color: #6c757d; }
    .contact-phone { margin-top: 0.25rem; font-size: 0.9em; }
    .initial-circle { width: 36px; height: 36px; border-radius: 50%; background-color: var(--custom-brand-purple); color: white; display: flex; align-items: center; justify-content: center; font-weight: bold; flex-shrink: 0; object-fit: cover; border: 2px solid white; box-shadow: 0 1px 3px rgba(0,0,0,0.3); }
    .sortable-header { cursor: pointer; user-select: none; }
    .sortable-header .bi-arrow-down-up { opacity: 0.4; }
    .dropdown-item i.bi { margin-right: 0.5rem; }
    td .dropdown, .card-footer .dropdown { position: static; }
    .btn-outline-secondary.dropdown-toggle:hover::after, .btn-outline-secondary.dropdown-toggle[aria-expanded="true"]::after { border-top-color: white; }
    .dropdown-toggle:hover .bi-gear-fill, .dropdown-toggle[aria-expanded="true"] .bi-gear-fill { color: white; }
    .password-group { position: relative; }
    .password-toggle-btn { position: absolute; top: 50%; right: 0.75rem; transform: translateY(-50%); background: none; border: none; cursor: pointer; color: #6c757d; z-index: 10; }
    .btn-check:checked+.btn-outline-primary { background-color: var(--bs-primary); color: white; }
    .clear-search-btn { position: absolute; right: 0; top: 0; height: 100%; z-index: 3; display: none; background: transparent; border: none; padding: 0.375rem 0.75rem; color: #6c757d; }
    .clear-search-btn:hover { color: #212529; }
    #fisioSummaryModal .modal-body { max-height: 65vh; overflow-y: auto; }
    @media (max-width: 767.98px) { .toggle-view-btn { display: none !important; } }
</style>

<main class="main-content container mt-4" style="max-width: 1420px;">
    <div class="d-flex justify-content-between align-items-center mb-3 users-header-bar">
        <h4><i class="bi bi-people-fill me-2"></i><?= $user_rol === 'superadmin' ? "Gestió de Pacients i Fisioterapeutes" : "Gestió de Pacients" ?></h4>
        <div class="btn-group">
            <?php if (in_array($user_rol, ['superadmin', 'fisio'])): ?>
            <button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#createUserModal"><i class="bi bi-person-plus me-2"></i><?= $user_rol === 'superadmin' ? "Donar d'alta nou usuari" : "Donar d'alta nou pacient" ?></button>
            <?php endif; ?>
        </div>
    </div>

    <div class="card shadow-sm">
        <div class="card-body">
            <?php if ($user_rol === 'superadmin'): ?>
            <ul class="nav nav-tabs mb-3" id="userTabs" role="tablist">
                <li class="nav-item" role="presentation"><button class="nav-link active" id="pacients-tab" data-bs-toggle="tab" data-bs-target="#pacients-panel" type="button">Pacients</button></li>
                <li class="nav-item" role="presentation"><button class="nav-link" id="fisios-tab" data-bs-toggle="tab" data-bs-target="#fisios-panel" type="button">Fisioterapeutes i Admins</button></li>
            </ul>
            <?php endif; ?>

            <div class="tab-content" id="userTabsContent">
                <div class="tab-pane fade show active" id="pacients-panel" role="tabpanel">
                    <div class="row g-2 mb-3">
                        <div class="col-12 col-md-auto">
                            <div class="d-flex align-items-center h-100">
                                <?php if (in_array($user_rol, ['superadmin', 'fisio'])): ?>
                                <div class="form-check form-switch me-3 text-nowrap">
                                    <input class="form-check-input" type="checkbox" role="switch" id="filterMyPatients">
                                    <label class="form-check-label" for="filterMyPatients">Només els meus</label>
                                </div>
                                <?php endif; ?>
                                <div class="flex-grow-1 mobile-filter-flex-grow" style="max-width: 220px;">
                                     <select id="patientStatusFilter" class="form-select">
                                        <option value="activo" selected>Estat: Alta</option>
                                        <option value="baja">Estat: Baixa</option>
                                        <option value="auto_registre">Estat: Auto-registre</option>
                                        <option value="tots">Tots els estats</option>
                                    </select>
                                </div>
                            </div>
                        </div>
                        <div class="col-12 col-md">
                            <div class="d-flex align-items-center justify-content-start justify-content-md-end flex-wrap gap-2">
                                <div class="input-group mobile-filter-full-width" style="max-width: 300px; position: relative;">
                                    <span class="input-group-text"><i class="bi bi-search"></i></span>
                                    <input type="text" id="patientSearchInput" class="form-control" placeholder="Cercar pacients...">
                                    <button class="clear-search-btn" type="button" id="clearPatientSearchBtn"><i class="bi bi-x"></i></button>
                                </div>
                                <div class="btn-group mobile-filter-btn-group" role="group">
                                    <button type="button" class="btn btn-outline-secondary toggle-view-btn active" id="listViewBtnPatient" data-view="list" title="Vista en Llista"><i class="bi bi-list"></i></button>
                                    <button type="button" class="btn btn-outline-secondary toggle-view-btn" id="gridViewBtnPatient" data-view="grid" title="Vista en Quadrícula"><i class="bi bi-grid-fill"></i></button>
                                </div>
                                <div class="btn-group mobile-filter-btn-group" id="patient-sort-buttons-group">
                                    <button class="btn btn-outline-secondary sort-btn active" data-sort="fecha_creacion" data-order="DESC" title="Ordenar per Data d'Alta"><i class="bi bi-calendar3"></i></button>
                                    <button class="btn btn-outline-secondary sort-btn" data-sort="apellido" data-order="ASC" title="Ordenar per Nom/Cognoms"><i class="bi bi-sort-alpha-down"></i></button>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div id="patient-table-container"></div>
                    <div id="patient-pagination-container" class="mt-3"></div>
                </div>

                <?php if ($user_rol === 'superadmin'): ?>
                <div class="tab-pane fade" id="fisios-panel" role="tabpanel">
                    <div class="row g-2 mb-3">
                        <div class="col-12 col-md-auto">
                            <div class="d-flex align-items-center h-100">
                                <div class="flex-grow-1 mobile-filter-flex-grow" style="max-width: 220px;">
                                    <select id="fisioStatusFilter" class="form-select">
                                        <option value="activo" selected>Estat: Alta</option>
                                        <option value="baja">Estat: Baixa</option>
                                        <option value="tots">Tots els estats</option>
                                    </select>
                                </div>
                            </div>
                        </div>
                        <div class="col-12 col-md">
                            <div class="d-flex align-items-center justify-content-start justify-content-md-end flex-wrap gap-2">
                                <div class="input-group mobile-filter-full-width" style="max-width: 300px; position: relative;">
                                    <span class="input-group-text"><i class="bi bi-search"></i></span>
                                    <input type="text" id="fisioSearchInput" class="form-control" placeholder="Cercar fisioterapeutes...">
                                    <button class="clear-search-btn" type="button" id="clearFisioSearchBtn"><i class="bi bi-x"></i></button>
                                </div>
                                <div class="btn-group mobile-filter-btn-group" role="group">
                                    <button type="button" class="btn btn-outline-secondary toggle-view-btn active" id="listViewBtnFisio" data-view="list" title="Vista en Llista"><i class="bi bi-list"></i></button>
                                    <button type="button" class="btn btn-outline-secondary toggle-view-btn" id="gridViewBtnFisio" data-view="grid" title="Vista en Quadrícula"><i class="bi bi-grid-fill"></i></button>
                                </div>
                                 <div class="btn-group mobile-filter-btn-group" id="fisio-sort-buttons-group">
                                     <button class="btn btn-outline-secondary sort-btn active" data-sort="apellido" data-order="ASC" title="Ordenar per Nom/Cognoms"><i class="bi bi-sort-alpha-down"></i></button>
                                     <button class="btn btn-outline-secondary sort-btn" data-sort="fecha_creacion" data-order="DESC" title="Ordenar per Data d'Alta"><i class="bi bi-calendar3"></i></button>
                                 </div>
                             </div>
                        </div>
                    </div>
                    <div id="fisio-table-container"></div>
                    <div id="fisio-pagination-container" class="mt-3"></div>
                </div>
                <?php endif; ?>
            </div>
        </div>
    </div>
</main>

<?php if (in_array($user_rol, ['superadmin', 'fisio'])): ?>
<div class="modal fade" id="createUserModal" tabindex="-1">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header"><h5 class="modal-title"><?= $user_rol === 'superadmin' ? "Donar d'alta nou usuari" : "Donar d'alta nou pacient" ?></h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>
            <div class="modal-body">
                <form id="createUserForm">
                    <div class="row">
                        <div class="col-md-6 mb-3"><label class="form-label">Nom <span class="text-danger">*</span></label><input type="text" name="nombre" class="form-control" required></div>
                        <div class="col-md-6 mb-3"><label class="form-label">Cognoms <span class="text-danger">*</span></label><input type="text" name="apellido" class="form-control" required></div>
                    </div>
                    <div class="row">
                        <div class="col-md-6 mb-3"><label class="form-label">Email <span class="text-danger">*</span></label><input type="email" name="email" class="form-control" required></div>
                        <div class="col-md-6 mb-3"><label class="form-label">Telèfon</label><input type="tel" name="telefono" class="form-control"></div>
                    </div>
                     <?php if ($user_rol === 'superadmin'): ?>
                     <div class="row"><div class="col-md-6 mb-3"><label class="form-label">Rol <span class="text-danger">*</span></label><select name="rol" class="form-select" required><option value="paciente" selected>Pacient</option><option value="fisio">Fisioterapeuta</option><option value="superadmin">Superadmin</option></select></div></div>
                     <?php else: ?><input type="hidden" name="rol" value="paciente"><?php endif; ?>
                    <div class="row">
                        <div class="col-md-6 mb-3"><label class="form-label">Contrasenya Inicial <span class="text-danger">*</span></label><div class="password-group"><input type="password" name="password" class="form-control" required><button type="button" class="password-toggle-btn"><i class="bi bi-eye-slash"></i></button></div></div>
                        <div class="col-md-6 mb-3"><label class="form-label">Confirmar Contrasenya <span class="text-danger">*</span></label><div class="password-group"><input type="password" name="password_confirm" class="form-control" required><button type="button" class="password-toggle-btn"><i class="bi bi-eye-slash"></i></button></div></div>
                    </div>
                    <div class="modal-footer mt-3"><button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel·lar</button><button type="submit" class="btn btn-primary">Crear Usuari</button></div>
                </form>
            </div>
        </div>
    </div>
</div>
<?php endif; ?>

<div class="modal fade" id="editUserModal" tabindex="-1">
    <div class="modal-dialog modal-lg"> <div class="modal-content">
            <div class="modal-header"><h5 class="modal-title">Editar Dades de l'Usuari</h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>
            <div class="modal-body">
                <form id="editUserForm">
                    <input type="hidden" name="id">
                    <div class="row">
                        <div class="col-md-7">
                            <div class="row">
                                <div class="col-md-6 mb-3"><label class="form-label">Nom</label><input type="text" name="nombre" class="form-control" required></div>
                                <div class="col-md-6 mb-3"><label class="form-label">Cognoms</label><input type="text" name="apellido" class="form-control" required></div>
                                <div class="col-md-6 mb-3"><label class="form-label">Email (no editable)</label><input type="email" name="email" class="form-control" disabled></div>
                                <div class="col-md-6 mb-3"><label class="form-label">Telèfon</label><input type="tel" name="telefono" class="form-control"></div>
                                <div class="col-md-6 mb-3"><label class="form-label">Data d'Alta (no editable)</label><input type="text" name="fecha_creacion_formatted" class="form-control" disabled></div>
                                <?php if ($user_rol === 'superadmin'): ?>
                                <div class="col-md-6 mb-3" id="editUserRolRow" style="display: none;"><label class="form-label">Rol</label><select name="rol" id="editUserRol" class="form-select"><option value="paciente">Pacient</option><option value="fisio">Fisioterapeuta</option><option value="superadmin">Superadmin</option></select></div>
                                <?php endif; ?>
                                <div class="col-md-6 mb-3" id="editUserFechaBajaGroup" style="display: none;"><label class="form-label">Data de Baixa (no editable)</label><input type="text" name="fecha_baja_formatted" class="form-control" disabled></div>
                            </div>
                            <div class="mb-3"><label for="editUserMotivoBaja" class="form-label">Motiu de la baixa (si ha tingut lloc)</label><textarea class="form-control" id="editUserMotivoBaja" name="motivo_baja" rows="3" placeholder="No s'ha especificat cap motiu..."></textarea></div>
                        </div>
                        <div class="col-md-5 d-flex flex-column align-items-center pt-3 pt-md-0">
                            <label class="form-label mb-2">Foto de Perfil</label>
                            <div class="text-center"><img id="editUserAvatarPreview" src="" alt="Avatar" class="img-thumbnail rounded-circle" style="width: 150px; height: 150px; object-fit: cover; display: none;"><div id="editUserAvatarFallback" class="initial-circle mx-auto" style="width: 150px; height: 150px; font-size: 4rem; display: none; background-color: #6c757d;">??</div></div>
                        </div>
                    </div>
                    <div class="modal-footer mt-3"><button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel·lar</button><button type="submit" class="btn btn-primary">Guardar Canvis</button></div>
                </form>
            </div>
        </div>
    </div>
</div>
<div class="modal fade" id="userActionConfirmModal" tabindex="-1">
    <div class="modal-dialog"><div class="modal-content"><div class="modal-header"><h5 class="modal-title" id="userActionConfirmModalLabel"></h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div><div class="modal-body" id="userActionConfirmModalBody"></div><div class="modal-footer"><button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel·lar</button><button type="button" class="btn btn-primary" id="confirmUserActionBtn">Confirmar</button></div></div></div>
</div>

<div class="modal fade" id="fisioSummaryModal" tabindex="-1">
    <div class="modal-dialog modal-lg modal-dialog-scrollable"><div class="modal-content"><div class="modal-header"><h5 class="modal-title" id="fisioSummaryModalLabel">Resum d'Activitat</h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div><div class="modal-body" id="fisioSummaryModalBody"><div class="text-center p-5"><div class="spinner-border text-primary"></div></div></div><div class="modal-footer"><button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Tancar</button></div></div></div>
</div>

<?php include 'partials/footer.php'; ?>

<script>const USER_VIEW_PREFERENCES = <?php echo $user_view_prefs_json; ?>;</script>
<script>
function loadFisioDetailedSummary(targetId, targetTabId = null) {
    const modalTitle = 'Resum Detallat de la Càrrega de Treball';
    const fisioSummaryModalEl = document.getElementById('fisioSummaryModal');
    const fisioSummaryModalInstance = fisioSummaryModalEl ? bootstrap.Modal.getOrCreateInstance(fisioSummaryModalEl) : null;
    if (!fisioSummaryModalInstance) return;
    const params = { ajax: true, action: 'get_fisio_detailed_summary' };
    if (targetId && targetId !== 0) { params.target_id = targetId; }
    $('#fisioSummaryModalLabel').text(modalTitle);
    $('#fisioSummaryModalBody').html('<div class="text-center p-5"><div class="spinner-border text-primary"></div><p class="mt-2">Carregant dades...</p></div>');
    fisioSummaryModalInstance.show();
    $.getJSON('reports_ajax.php', params).done(function(response) {
            if (response.status === 'success' && response.html) {
                $('#fisioSummaryModalBody').html(response.html);
                if (targetTabId) { setTimeout(() => { const el = document.getElementById(targetTabId); if(el) bootstrap.Tab.getOrCreateInstance(el)?.show(); else { const first = fisioSummaryModalEl.querySelector('.nav-tabs .nav-link, .nav-pills .nav-link'); if(first) bootstrap.Tab.getOrCreateInstance(first).show(); } }, 100); }
                else { const first = fisioSummaryModalEl.querySelector('.nav-tabs .nav-link, .nav-pills .nav-link'); if (first && !first.classList.contains('active')) bootstrap.Tab.getOrCreateInstance(first).show(); }
            } else { $('#fisioSummaryModalBody').html('<div class="alert alert-warning">Error: ' + escapeHtml(response.message || 'Desconegut.') + '</div>'); }
        }).fail(xhr => { $('#fisioSummaryModalBody').html('<div class="alert alert-danger">Error: ' + escapeHtml(xhr.responseJSON?.message || 'Connexió.') + '</div>'); });
}

$(document).ready(function() {
    const FILTER_MINE_DEFAULT = <?= $filtro_defecto ?> == 1;
    const CURRENT_USER_ROL = '<?= $user_rol ?>';
    const CURRENT_USER_ID = <?= $user_id ?>;
    const IS_SUPERADMIN = CURRENT_USER_ROL === 'superadmin';
    const IS_IMPERSONATING = <?= isset($_SESSION['admin_origen_id']) ? 'true' : 'false' ?>;
    const createUserModal = $('#createUserModal').length ? new bootstrap.Modal('#createUserModal') : null;
    const editUserModal = $('#editUserModal').length ? new bootstrap.Modal('#editUserModal') : null;
    const userActionConfirmModal = $('#userActionConfirmModal').length ? new bootstrap.Modal('#userActionConfirmModal') : null;

    function isMobileView() { return window.innerWidth < 767.98; }
    const fisioSummaryModalEl_fix = document.getElementById('fisioSummaryModal');
    if (fisioSummaryModalEl_fix) { fisioSummaryModalEl_fix.addEventListener('hidden.bs.modal', () => $('.dropdown-toggle[aria-expanded="true"]').dropdown('toggle')); }
    let userToManage = { id: null, name: '', role: '', status: '' };
    let pendingAction = null;
    const urlParams_usr = new URLSearchParams(window.location.search);
    const urlStatus = urlParams_usr.get('status');
    const initialStatus = (urlStatus === 'baja' || urlStatus === 'auto_registre' || urlStatus === 'tots') ? urlStatus : 'activo';
    let initialFilterMine = FILTER_MINE_DEFAULT;
    if (urlParams_usr.get('filter') === 'mine') { initialFilterMine = true; }
    const initialTab = urlParams_usr.get('tab');
    const initialPatientView = USER_VIEW_PREFERENCES['pacientes'] || 'list';

    let patientState = { page: 1, search: '', sort: 'fecha_creacion', order: 'DESC', filterMine: initialFilterMine, viewMode: isMobileView() ? 'grid' : initialPatientView, statusFilter: initialStatus };
    let fisioState = { page: 1, search: '', sort: 'apellido', order: 'ASC', viewMode: isMobileView() ? 'grid' : 'list', statusFilter: initialStatus };
    let fisiosLoaded = false;

    function getInitialSortIcon(currentSort, currentOrder, columnName) { if (currentSort === columnName) { return currentOrder === 'ASC' ? '<i class="bi bi-caret-up-fill ms-2"></i>' : '<i class="bi bi-caret-down-fill ms-2"></i>'; } const validCols = ['apellido', 'fecha_creacion', 'registrar_name']; if (!validCols.includes(columnName)) return ''; return '<i class="bi bi-arrow-down-up ms-2 text-muted opacity-50"></i>'; }
    function escapeHtml(text) { if (typeof text !== 'string') return ''; const map = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#039;' }; return text.replace(/[&<>"']/g, m => map[m]); }

    function fetchPacients() {
        $('#patient-table-container').css('opacity', 0.5);
        return $.getJSON('users.php', { ajax: true, action: 'read_pacients', ...patientState }).done(res => {
            $('#patient-table-container').css('opacity', 1);
            if (res.status === 'success') {
                renderUsers(res.data, 'patient', res.pagination.currentSort, res.pagination.currentOrder);
                renderPagination(res.pagination, 'patient');
                updateSortButtons('patient', res.pagination.currentSort, res.pagination.currentOrder);
            } else { $('#patient-table-container').html(`<div class="alert alert-warning">${escapeHtml(res.message || 'No s\'han trobat.')}</div>`); }
        }).fail(xhr => { $('#patient-table-container').css('opacity', 1).html('<div class="alert alert-danger">Error carregant.</div>'); });
    }
    <?php if ($user_rol === 'superadmin'): ?>
    function fetchFisios() {
        $('#fisio-table-container').css('opacity', 0.5);
        return $.getJSON('users.php', { ajax: true, action: 'read_fisios', ...fisioState }).done(res => {
            $('#fisio-table-container').css('opacity', 1);
            if (res.status === 'success') {
                renderUsers(res.data, 'fisio', res.pagination.currentSort, res.pagination.currentOrder);
                renderPagination(res.pagination, 'fisio');
                updateSortButtons('fisio', res.pagination.currentSort, res.pagination.currentOrder);
            } else { $('#fisio-table-container').html(`<div class="alert alert-warning">${escapeHtml(res.message || 'No s\'han trobat.')}</div>`); }
        }).fail(xhr => { $('#fisio-table-container').css('opacity', 1).html('<div class="alert alert-danger">Error carregant.</div>'); });
    }
    <?php endif; ?>

    function updateSortButtons(type, currentSort, currentOrder) {
        const groupSelector = type === 'patient' ? '#patient-sort-buttons-group' : '#fisio-sort-buttons-group';
        const state = type === 'patient' ? patientState : fisioState;
        $(groupSelector + ' .sort-btn').removeClass('active');
        if (state.viewMode === 'grid') {
             const sortSelector = `[data-sort="${currentSort}"]`;
             $(groupSelector).find(sortSelector).addClass('active');
        }
    }

    function renderUsers(data, type, currentSort, currentOrder) {
        const isPatient = type === 'patient';
        const container = isPatient ? $('#patient-table-container') : $('#fisio-table-container');
        const state = isPatient ? patientState : fisioState;
        container.empty();

        if (!data || data.length === 0) {
            container.html(`<div class="alert alert-secondary text-center">No s'han trobat ${isPatient ? 'pacients' : 'fisioterapeutes'} amb els filtres seleccionats.</div>`);
            return;
        }

        if (state.viewMode === 'grid') {
            container.removeClass('table-responsive').addClass('row g-4');
            data.forEach(item => {
                const statusLabel = item.status === 'activo' ? 'Alta' : 'Baixa';
                const statusClass = item.status === 'activo' ? 'bg-success' : 'bg-secondary';
                const statusBadge = `<span class="status-badge ${statusClass}" title="Estat: ${statusLabel}">${statusLabel}</span>`;
                const buttonsHtml = renderActionButtons(item);
                let bajaDateHtml = '';
                if (state.statusFilter === 'baja' && item.fecha_baja) { bajaDateHtml = `<p class="card-text small mb-0 text-danger">Data Baixa: ${new Date(item.fecha_baja).toLocaleDateString('ca-ES')}</p>`; }
                const cardOpacityClass = item.status === 'baja' ? 'opacity-75' : '';

                let avatarHtml = '';
                if (item.avatar) {
                    avatarHtml = `<img src="${escapeHtml(item.avatar)}" alt="Avatar" class="rounded-circle border ms-3" style="width: 60px; height: 60px; object-fit: cover; flex-shrink: 0;">`;
                } else {
                    avatarHtml = `<div class="rounded-circle bg-secondary text-white d-flex align-items-center justify-content-center border ms-3" style="width: 60px; height: 60px; font-size: 1.5rem; font-weight: bold; flex-shrink: 0;">${item.initials || '??'}</div>`;
                }

                let roleBadgeHtml = '';
                if (!isPatient) {
                     if (item.rol === 'superadmin') { roleBadgeHtml = `<span class="role-badge bg-danger mb-1 d-inline-block">Superadmin</span><br>`; }
                     else { roleBadgeHtml = `<span class="role-badge bg-info mb-1 d-inline-block">Fisio</span><br>`; }
                }

                const cardHtml = `
                <div class="col-md-6 col-lg-4">
                    <div class="card h-100 shadow-sm ${cardOpacityClass}">
                        <div class="card-body">
                            <div class="d-flex justify-content-between align-items-start mb-3">
                                <div style="min-width: 0;">
                                    ${roleBadgeHtml}
                                    <h5 class="card-title mb-1 text-truncate" title="${escapeHtml(item.apellido)}, ${escapeHtml(item.nombre)}">
                                        ${escapeHtml(item.apellido)}, ${escapeHtml(item.nombre)}
                                    </h5>
                                    <a href="mailto:${escapeHtml(item.email)}" class="text-muted small text-decoration-none d-block text-truncate" target="_blank">
                                        ${escapeHtml(item.email)}
                                    </a>
                                    <p class="card-text small mt-2 mb-0 text-muted">
                                        <i class="bi bi-telephone contact-icon"></i> ${escapeHtml(item.telefono) || 'N/A'}
                                    </p>
                                </div>
                                ${avatarHtml}
                            </div>

                            <div class="mt-3 pt-2 border-top">
                                <div class="d-flex justify-content-between align-items-center mb-2">
                                     <small class="text-muted">Estat:</small>
                                     ${statusBadge}
                                </div>
                                ${bajaDateHtml}
                            </div>
                        </div>
                        <div class="card-footer bg-light d-flex justify-content-between align-items-center">
                            <small class="text-muted" style="font-size: 0.75rem;">Alta: ${item.fecha_creacion ? new Date(item.fecha_creacion).toLocaleDateString('ca-ES') : 'N/A'}</small>
                            ${buttonsHtml}
                        </div>
                    </div>
                </div>`;
                container.append(cardHtml);
            });
        } else {
            container.removeClass('row g-4').addClass('table-responsive');
            const showBajaDate = state.statusFilter === 'baja';
            const headerBajaDate = showBajaDate ? `<th class="text-nowrap" style="width: 12%;">Data de Baixa</th>` : '';
            let headerFisioReg = '';
            let headerRol = '';
            if (isPatient) { headerFisioReg = `<th class="sortable-header" data-sort="registrar_name" style="width: 13%;">Registrat per${getInitialSortIcon(currentSort, currentOrder, 'registrar_name')}</th>`; }
            else { headerRol = `<th style="width: 10%;">Rol</th>`; }

            let tableHtml = `<table class="table table-hover align-middle"><thead><tr>
                <th class="sortable-header" data-sort="apellido" style="width: 25%;">Nom Complet${getInitialSortIcon(currentSort, currentOrder, 'apellido')}</th>
                <th style="width: 22%;">Contacte</th>
                ${headerRol}
                <th style="width: 8%;">Estat</th>
                ${headerFisioReg}
                <th class="sortable-header text-nowrap" data-sort="fecha_creacion" style="width: 12%;">Data${getInitialSortIcon(currentSort, currentOrder, 'fecha_creacion')}</th>
                ${headerBajaDate}
                <th class="text-end" style="width: 8%;">Accions</th>
            </tr></thead><tbody>`;

            data.forEach(item => {
                const opacityClass = item.status === 'baja' ? 'opacity-75' : '';
                const statusLabel = item.status === 'activo' ? 'Alta' : 'Baixa';
                const statusClass = item.status === 'activo' ? 'bg-success' : 'bg-secondary';
                const statusBadge = `<span class="status-badge ${statusClass}" title="Estat: ${statusLabel}">${statusLabel}</span>`;
                const buttonsHtml = renderActionButtons(item);
                const fichaLink = (isPatient && item.status === 'activo') ? `fitxa_pacient.php?id=${item.id}` : '#';
                const bajaDateColData = showBajaDate ? `<td class="${opacityClass}">${item.fecha_baja ? new Date(item.fecha_baja).toLocaleDateString('ca-ES') : 'N/A'}</td>` : '';
                let fisioColData = '';
                let rolColData = '';
                if (isPatient) { fisioColData = `<td class="${opacityClass}">${escapeHtml(item.nombre_fisio_registrador)}</td>`; }
                else {
                    let rolBadge = '';
                    if (item.rol === 'superadmin') { rolBadge = `<span class="role-badge bg-danger">Superadmin</span>`; }
                    else { rolBadge = `<span class="role-badge bg-info">Fisio</span>`; }
                    rolColData = `<td class="${opacityClass}">${rolBadge}</td>`;
                }

                let avatarHtml = '';
                if (item.avatar) { avatarHtml = `<img src="${escapeHtml(item.avatar)}" alt="Avatar" class="initial-circle me-3" style="object-fit: cover;">`; }
                else { avatarHtml = `<div class="initial-circle me-3">${item.initials || '??'}</div>`; }

                const nameCell = `<a href="${fichaLink}" class="text-decoration-none text-dark d-flex align-items-center ${item.status === 'baja' ? 'pe-none' : ''}">${avatarHtml}<div class="fw-bold">${escapeHtml(item.apellido)}, ${escapeHtml(item.nombre)}</div></a>`;
                const contactCell = `<div><i class="bi bi-envelope contact-icon"></i><a href="mailto:${escapeHtml(item.email)}" class="text-secondary text-decoration-none" target="_blank">${escapeHtml(item.email)}</a></div>${item.telefono ? `<div class="d-flex align-items-center contact-phone"><i class="bi bi-telephone contact-icon"></i>${escapeHtml(item.telefono)}</div>` : ''}`;

                tableHtml += `<tr>
                    <td class="${opacityClass}">${nameCell}</td>
                    <td class="${opacityClass}">${contactCell}</td>
                    ${rolColData}
                    <td class="${opacityClass}">${statusBadge}</td>
                    ${fisioColData}
                    <td class="${opacityClass}">${item.fecha_creacion ? new Date(item.fecha_creacion).toLocaleDateString('ca-ES') : 'N/A'}</td>
                    ${bajaDateColData}
                    <td class="text-end">${buttonsHtml}</td>
                </tr>`;
            });
            container.html(tableHtml + '</tbody></table>');
        }
        new bootstrap.Tooltip(container[0], { selector: '[data-bs-toggle="tooltip"]' });
    }

    function renderActionButtons(item) {
            const canManageGlobal = CURRENT_USER_ROL === 'superadmin';
            const canEdit = CURRENT_USER_ROL === 'superadmin' || (CURRENT_USER_ROL === 'fisio' && item.rol === 'paciente');
            const isPatient = item.rol === 'paciente';
            const userName = `${escapeHtml(item.nombre || '')} ${escapeHtml(item.apellido || '')}`;
            let buttons = '';

            if (isPatient) {
                const isRegistrador = (item.id_fisio_registrador == CURRENT_USER_ID);
                const canAccessTreatment = (IS_SUPERADMIN || item.has_treatment_access == 1 || isRegistrador);
                const disabledClass = (item.status === 'baja' || !canAccessTreatment) ? 'disabled' : '';
                const ariaDisabled = disabledClass ? 'aria-disabled="true" tabindex="-1"' : '';
                const linkHref = (item.status === 'baja' || !canAccessTreatment) ? '#' : `fitxa_pacient.php?id=${item.id}`;
                buttons += `<li><a class="dropdown-item ${disabledClass}" href="${linkHref}" ${ariaDisabled}><i class="bi bi-person-badge"></i>Àrea de Tractaments</a></li>`;
                const canImpersonatePatient = canAccessTreatment && item.status === 'activo' && !IS_IMPERSONATING;
                const impersonateDisabledClass = !canImpersonatePatient ? 'disabled' : '';
                const impersonateAriaDisabled = !canImpersonatePatient ? 'aria-disabled="true" tabindex="-1"' : '';
                let impersonateTitle = 'Suplantar pacient';
                if (IS_IMPERSONATING) { impersonateTitle = 'No es pot suplantar: ja estàs suplantant a un usuari.'; }
                else if (item.status === 'baja') { impersonateTitle = 'No es pot suplantar un usuari de baixa'; }
                else if (!canAccessTreatment) { impersonateTitle = 'No tens accés a aquest pacient'; }
                buttons += `<li><a class="dropdown-item impersonate-btn ${impersonateDisabledClass}" href="#" data-id="${item.id}" data-name="${userName}" ${impersonateAriaDisabled} title="${impersonateTitle}"><i class="bi bi-person-bounding-box text-info"></i> Suplantar Pacient</a></li>`;
            } else if (canManageGlobal) {
                buttons += `<li><a class="dropdown-item summary-btn" href="#" data-id="${item.id}" data-name="${userName}"><i class="bi bi-bar-chart-line"></i> Veure Activitat</a></li>`;
                const canImpersonateAdmin = (item.id != CURRENT_USER_ID && item.status === 'activo' && !IS_IMPERSONATING);
                if (canImpersonateAdmin) { buttons += `<li><a class="dropdown-item impersonate-btn" href="#" data-id="${item.id}" data-name="${userName}"><i class="bi bi-person-bounding-box text-info"></i> Suplantar Usuari</a></li>`; }
                else if (IS_IMPERSONATING) { buttons += `<li><a class="dropdown-item impersonate-btn disabled" href="#" data-id="${item.id}" data-name="${userName}" aria-disabled="true" tabindex="-1" title="No es pot suplantar: ja estàs suplantant a un usuari."><i class="bi bi-person-bounding-box text-info"></i> Suplantar Usuari</a></li>`; }
            }

            if (!IS_IMPERSONATING) {
                if (canEdit) { buttons += `<li><a class="dropdown-item edit-btn" href="#" data-id="${item.id}"><i class="bi bi-pencil"></i> Dades personals</a></li>`; }
                if (item.status === 'activo') {
                    if ( (isPatient && canEdit) || (canManageGlobal && item.id != CURRENT_USER_ID) ) { buttons += `<li><hr class="dropdown-divider"></li><li><a class="dropdown-item baja-btn" href="#" data-id="${item.id}" data-name="${userName}" data-role="${item.rol}"><i class="bi bi-person-dash text-warning"></i> Donar de Baixa</a></li>`; }
                } else if (item.status === 'baja') {
                    if ( (isPatient && canEdit) || canManageGlobal ) { buttons += `<li><hr class="dropdown-divider"></li><li><a class="dropdown-item reactivar-btn" href="#" data-id="${item.id}" data-name="${userName}" data-role="${item.rol}"><i class="bi bi-person-check text-success"></i> Reactivar Compte</a></li>`; }
                    if (canManageGlobal) { buttons += `<li><a class="dropdown-item delete-btn" href="#" data-id="${item.id}" data-name="${userName}" data-role="${item.rol}"><i class="bi bi-trash text-danger"></i> Eliminar Permanentment</a></li>`; }
                }
            }
            return `<div class="dropdown" title="Gestionar Usuari"><button class="btn btn-sm btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false"><i class="bi bi-gear-fill"></i></button><ul class="dropdown-menu dropdown-menu-end">${buttons}</ul></div>`;
        }

    function renderPagination(pagination, type) { const container = type === 'patient' ? $('#patient-pagination-container') : $('#fisio-pagination-container'); container.empty(); if (!pagination || pagination.totalPages <= 1) return; let paginationHtml = `<nav><ul class="pagination justify-content-center">`; for (let i = 1; i <= pagination.totalPages; i++) { paginationHtml += `<li class="page-item ${i === pagination.currentPage ? 'active' : ''}"><a class="page-link" href="#" data-page="${i}">${i}</a></li>`; } container.html(paginationHtml + '</ul></nav>'); }

    function setupSearch(inputId, clearBtnId, state, fetchFunction) { let searchTimeout; const inputElement = $(inputId); const clearButton = $(clearBtnId); inputElement.on('keyup input', function() { const hasValue = $(this).val().length > 0; clearButton.toggle(hasValue); clearTimeout(searchTimeout); searchTimeout = setTimeout(() => { state.search = $(this).val(); state.page = 1; fetchFunction(); }, 300); }); clearButton.on('click', () => inputElement.val('').trigger('input').focus()); }
    setupSearch('#patientSearchInput', '#clearPatientSearchBtn', patientState, fetchPacients);
    <?php if ($user_rol === 'superadmin'): ?> setupSearch('#fisioSearchInput', '#clearFisioSearchBtn', fisioState, fetchFisios); <?php endif; ?>
    $('#filterMyPatients').on('change', function() { patientState.filterMine = $(this).is(':checked'); patientState.page = 1; fetchPacients(); });
    $('#patientStatusFilter').on('change', function() { patientState.statusFilter = $(this).val(); patientState.page = 1; fetchPacients(); });
    <?php if ($user_rol === 'superadmin'): ?> $('#fisioStatusFilter').on('change', function() { fisioState.statusFilter = $(this).val(); fisioState.page = 1; fetchFisios(); }); <?php endif; ?>

    $('#pacients-panel .toggle-view-btn').on('click', function() {
        const newViewMode = $(this).data('view');
        if (patientState.viewMode === newViewMode) return;
        patientState.viewMode = newViewMode;
        $('#pacients-panel .toggle-view-btn').removeClass('active');
        $(this).addClass('active');
        if (newViewMode === 'list') { $('#patient-sort-buttons-group').hide(); } else { $('#patient-sort-buttons-group').show(); }
        $.post('users.php', { ajax: true, action: 'save_view_preference', page_name: 'pacientes', view_mode: newViewMode }, 'json').fail(xhr => console.error('Error guardant pref.', xhr.responseText));
        fetchPacients();
    });

    $('#fisios-panel .toggle-view-btn').on('click', function() {
        const newViewMode = $(this).data('view');
        if (fisioState.viewMode === newViewMode) return;
        fisioState.viewMode = newViewMode;
        $('#fisios-panel .toggle-view-btn').removeClass('active');
        $(this).addClass('active');
        if (newViewMode === 'list') { $('#fisio-sort-buttons-group').hide(); } else { $('#fisio-sort-buttons-group').show(); }
        fetchFisios();
    });

    $(document).on('click', '#patient-sort-buttons-group .sort-btn, #fisio-sort-buttons-group .sort-btn, #patient-table-container .sortable-header, #fisio-table-container .sortable-header', function() {
        const newSort = $(this).data('sort');
        if (!newSort) return;
        const isPatientTab = $(this).closest('#pacients-panel, #patient-sort-buttons-group').length > 0;
        const state = isPatientTab ? patientState : fisioState;
        const fetchFunction = isPatientTab ? fetchPacients : fetchFisios;
        const validSorts = ['apellido', 'fecha_creacion', 'registrar_name'];
        if (!validSorts.includes(newSort)) { return; }
        let defaultOrder = (newSort === 'apellido' || newSort === 'registrar_name') ? 'ASC' : 'DESC';
        if ($(this).hasClass('sort-btn') && $(this).data('order')) { defaultOrder = $(this).data('order'); }
        if (state.sort === newSort) { state.order = state.order === 'ASC' ? 'DESC' : 'ASC'; } else { state.sort = newSort; state.order = defaultOrder; }
        state.page = 1;
        fetchFunction();
    });

    $(document).on('click', '#patient-pagination-container .page-link', function(e) { e.preventDefault(); patientState.page = $(this).data('page'); fetchPacients(); });
    <?php if ($user_rol === 'superadmin'): ?> $(document).on('click', '#fisio-pagination-container .page-link', function(e) { e.preventDefault(); fisioState.page = $(this).data('page'); fetchFisios(); }); $('button[data-bs-target="#fisios-panel"]').on('shown.bs.tab', function() { if (!fisiosLoaded) { fetchFisios(); fisiosLoaded = true; } }); <?php endif; ?>

    <?php if (in_array($user_rol, ['superadmin', 'fisio'])): ?>
    $('#createUserForm').on('submit', function(e) {
        e.preventDefault();
        const $form = $(this);
        const $submitBtn = $form.find('button[type="submit"]');
        const originalBtnText = $submitBtn.text();
        $submitBtn.prop('disabled', true).html('<span class="spinner-border spinner-border-sm me-2" role="status" aria-hidden="true"></span>Creant...');
        $.post('users.php', `ajax=true&action=create_user&${$form.serialize()}`, 'json').done(res => {
                if(res.status === 'success'){
                    showToast(res.message, 'success');
                    createUserModal?.hide();
                    $form[0].reset();
                    const createdRole = $form.find('[name="rol"]').val();
                    const isPatient = (createdRole === 'paciente');
                    if (isPatient) { location.href = 'users.php?tab=pacients&status=activo'; } else { location.href = 'users.php?tab=fisios&status=activo'; }
                } else { showToast(res.message || 'Error', 'danger'); }
            }).fail(xhr => showToast(xhr.responseJSON?.message || 'Error', 'danger')).always(() => { $submitBtn.prop('disabled', false).html(originalBtnText); });
    });
    <?php endif; ?>

    $(document).on('click', '.edit-btn', function() { const id = $(this).data('id'); $.getJSON('users.php', { ajax: true, action: 'get_user_data', id: id }).done(res => { if (res.status === 'success' && res.data) {
            const form = $('#editUserForm');
            const avatarPreview = $('#editUserAvatarPreview');
            const avatarFallback = $('#editUserAvatarFallback');
            if (res.data.avatar) { avatarPreview.attr('src', res.data.avatar).show(); avatarFallback.hide(); } else { const initials = (res.data.nombre ? res.data.nombre.charAt(0) : '') + (res.data.apellido ? res.data.apellido.charAt(0) : ''); avatarFallback.text(initials.toUpperCase() || '??').show(); avatarPreview.hide(); }
            form.find('[name="id"]').val(res.data.id); form.find('[name="nombre"]').val(res.data.nombre); form.find('[name="apellido"]').val(res.data.apellido); form.find('[name="email"]').val(res.data.email); form.find('[name="telefono"]').val(res.data.telefono); form.find('[name="fecha_creacion_formatted"]').val(res.data.fecha_creacion_formatted); form.find('[name="motivo_baja"]').val(res.data.motivo_baja || ''); const fechaBajaGroup = form.find('#editUserFechaBajaGroup'); if (res.data.status === 'baja' && res.data.fecha_baja_formatted) { form.find('[name="fecha_baja_formatted"]').val(res.data.fecha_baja_formatted); fechaBajaGroup.show(); } else { fechaBajaGroup.hide(); form.find('[name="fecha_baja_formatted"]').val(''); }
            <?php if ($user_rol === 'superadmin'): ?>
            const rolSelect = form.find('#editUserRol');
            const rolRow = form.find('#editUserRolRow');
            rolSelect.find('option[value="paciente"]').show();
            if (res.data.rol === 'paciente') { rolSelect.val('paciente'); rolRow.hide(); rolSelect.prop('disabled', true); } else { rolRow.show(); rolSelect.val(res.data.rol); rolSelect.find('option[value="paciente"]').hide(); if (res.data.id == CURRENT_USER_ID) { rolSelect.prop('disabled', true).attr('title', "No pots canviar el teu propi rol."); } else if (res.data.rol === 'superadmin') { $.getJSON('users.php', { ajax: true, action: 'check_superadmin_count' }).done(countRes => { if (countRes.status === 'success' && countRes.count <= 1) { rolSelect.prop('disabled', true).attr('title', "No es pot canviar el rol de l'últim Superadmin."); } else { rolSelect.prop('disabled', false).attr('title', ''); } }); } else { rolSelect.prop('disabled', false).attr('title', ''); } }
            <?php endif; ?>
            editUserModal?.show(); } else { showToast(res.message || 'Error', 'danger'); } }).fail(xhr => showToast(xhr.responseJSON?.message || 'Error', 'danger')); });

    $('#editUserForm').on('submit', function(e) { e.preventDefault(); const emailInput = $(this).find('[name="email"]'); emailInput.prop('disabled', false);
        const rolInput = $(this).find('#editUserRol');
        const rolInputWasDisabled = rolInput.prop('disabled');
        if (rolInput.length) rolInput.prop('disabled', false);
        const fullFormData = $(this).serialize();
        emailInput.prop('disabled', true);
        if (rolInput.length) rolInput.prop('disabled', rolInputWasDisabled);
        $.post('users.php', `ajax=true&action=update_user&${fullFormData}`, 'json').done(res => {
                if(res.status === 'success'){
                    showToast(res.message, 'success');
                    editUserModal?.hide();
                    const idToHighlight = res.saved_user_id;
                    const editedUserRole = rolInput.val() || 'paciente';
                    const isPatient = (editedUserRole === 'paciente');
                    const fetchFunction = isPatient ? fetchPacients : fetchFisios;
                    const state = isPatient ? patientState : fisioState;
                    fetchFunction().done(() => {
                        if (idToHighlight) {
                            let elementToFlash;
                            if (state.viewMode === 'grid') { elementToFlash = $(`.card .edit-btn[data-id="${idToHighlight}"]`).closest('.card'); }
                            else { elementToFlash = $(`tr .edit-btn[data-id="${idToHighlight}"]`).closest('tr'); }
                            if (typeof flashElement === 'function' && elementToFlash && elementToFlash.length > 0) { setTimeout(() => { flashElement(elementToFlash); }, 50); }
                        }
                    });
                } else { showToast(res.message || 'Error', 'danger'); }
            }).fail(xhr => showToast(xhr.responseJSON?.message || 'Error', 'danger'));
    });

    $(document).on('click', '.baja-btn, .reactivar-btn, .delete-btn', function(e) {
        e.preventDefault();
        if (IS_IMPERSONATING) { showToast('Las acciones de gestión están deshabilitadas durante la suplantación.', 'warning'); return; }
        if ($(this).hasClass('baja-btn')) { pendingAction = 'dar_baja_usuario'; } else if ($(this).hasClass('reactivar-btn')) { pendingAction = 'reactivar_usuario'; } else if ($(this).hasClass('delete-btn')) { pendingAction = 'delete_user'; } else { return; }
        userToManage.id = $(this).data('id'); userToManage.name = $(this).data('name'); userToManage.role = $(this).data('role'); userToManage.status = $(this).hasClass('baja-btn') ? 'activo' : 'baja';
        const labels = { dar_baja_usuario: 'Donar de Baixa a l\'Usuari', reactivar_usuario: 'Reactivar a l\'Usuari', delete_user: 'Eliminar Usuari Permanentment' };
        const bodies = {
            dar_baja_usuario: `<p>Estàs segur que vols donar de baixa a <strong>${escapeHtml(userToManage.name)}</strong>?</p><p class="small text-muted">Aquesta acció canviarà el seu estat a "Baixa" i els seus tractaments actius passaran a "Omés".</Lp><label for="motivoBajaTextarea" class="form-label">Motiu de la baixa (opcional):</label><textarea id="motivoBajaTextarea" class="form-control" rows="3"></textarea>`,
            reactivar_usuario: `<p>Estàs segur que vols reactivar el compte de <strong>${escapeHtml(userToManage.name)}</strong>?</p><p class="small text-muted">L'usuari podrà tornar a accedir a la plataforma.</p>`,
            delete_user: `<p class="text-danger fw-bold">ADVERTÈNCIA: ACCIÓ IRREVERSIBLE</p><p>Estàs segur que vols eliminar permanentment el compte de <strong>${escapeHtml(userToManage.name)}</strong>?</p><p class="small text-muted">Aquesta acció eliminarà l'usuari i totes les seues dades associades (tractaments, evolucions, etc.) de la base de dades. Aquesta acció no es pot desfer.</p>`
        };
        const buttons = { dar_baja_usuario: ['Sí, Donar de Baixa', 'btn-warning'], reactivar_usuario: ['Sí, Reactivar', 'btn-success'], delete_user: ['Sí, Eliminar Permanentment', 'btn-danger'] };
        $('#userActionConfirmModalLabel').text(labels[pendingAction]);
        $('#userActionConfirmModalBody').html(bodies[pendingAction]);
        $('#confirmUserActionBtn').text(buttons[pendingAction][0]).removeClass('btn-danger btn-success btn-warning').addClass(buttons[pendingAction][1]);
        userActionConfirmModal?.show();
    });

    $('#confirmUserActionBtn').on('click', function() {
        if (IS_IMPERSONATING) { showToast('Las acciones de gestión están deshabilitadas durante la suplantación.', 'warning'); return; }
        if (!pendingAction || !userToManage.id) return;
        const action = pendingAction; const userId = userToManage.id; const userRole = userToManage.role; const button = $(this);
        let postData = { ajax: true, action: action, id: userId };
        if (action === 'dar_baja_usuario') { postData.motivo_baja = $('#motivoBajaTextarea').val(); }
        const originalButtonText = $(this).text();
        button.prop('disabled', true).html('<span class="spinner-border spinner-border-sm"></span> Processant...');
        const isPatient = (userRole === 'paciente');
        const state = isPatient ? patientState : fisioState;
        const fetchFunction = isPatient ? fetchPacients : fetchFisios;
        const statusFilterDropdown = isPatient ? $('#patientStatusFilter') : $('#fisioStatusFilter');
        let currentItemCount = 0;
        if (isPatient) { currentItemCount = (state.viewMode === 'grid') ? $('#patient-table-container').find('.card').length : $('#patient-table-container').find('tbody tr').length; }
        else { currentItemCount = (state.viewMode === 'grid') ? $('#fisio-table-container').find('.card').length : $('#fisio-table-container').find('tbody tr').length; } // <-- Add grid logic for fisio

        if (action === 'delete_user') {
            let elementToDelete;
            if (state.viewMode === 'grid') { elementToDelete = $(`.card .edit-btn[data-id="${userId}"]`).closest('.card'); }
            else { elementToDelete = $(`tr .edit-btn[data-id="${userId}"]`).closest('tr'); }
            userActionConfirmModal?.hide();
            if (elementToDelete.length > 0) {
                elementToDelete.addClass('flash-delete');
                setTimeout(() => {
                    $.post('users.php', postData, 'json').done(res => {
                        if (res.status === 'success') {
                            showToast(res.message, 'success');
                            if (state.statusFilter === 'baja' && currentItemCount === 1) {
                                showToast('Últim usuari de baixa eliminat. Tornant a la vista "Alta".', 'success');
                                state.statusFilter = 'activo';
                                statusFilterDropdown.val('activo');
                                fetchFunction();
                            } else { fetchFunction(); }
                        } else { showToast(res.message || 'Error', 'danger'); elementToDelete.removeClass('flash-delete'); }
                    }).fail(xhr => { showToast(xhr.responseJSON?.message || 'Error', 'danger'); elementToDelete.removeClass('flash-delete'); }).always(() => { button.prop('disabled', false).text(originalButtonText); pendingAction = null; userToManage = { id: null, name: '', role: '', status: '' }; });
                }, 1500);
            } else {
                $.post('users.php', postData, 'json').done(res => {
                    if (res.status === 'success') {
                        showToast(res.message, 'success');
                        if (state.statusFilter === 'baja' && currentItemCount === 1) {
                            showToast('Últim usuari de baixa eliminat. Tornant a la vista "Alta".', 'info');
                            state.statusFilter = 'activo';
                            statusFilterDropdown.val('activo');
                            fetchFunction();
                        } else { fetchFunction(); }
                    } else { showToast(res.message || 'Error', 'danger'); }
                }).fail(xhr => showToast(xhr.responseJSON?.message || 'Error', 'danger')).always(() => { button.prop('disabled', false).text(originalButtonText); pendingAction = null; userToManage = { id: null, name: '', role: '', status: '' }; });
            }
        } else {
            $.post('users.php', postData, 'json').done(res => {
                if (res.status === 'success') {
                    showToast(res.message, 'success');
                    userActionConfirmModal?.hide();
                    if (userRole === 'paciente') {
                        const idToHighlight = userId;
                        let newStatus = null;
                        if (action === 'dar_baja_usuario') { newStatus = 'baja'; } else if (action === 'reactivar_usuario') { newStatus = 'activo'; }
                        if (newStatus) {
                            patientState.statusFilter = newStatus;
                            $('#patientStatusFilter').val(newStatus);
                            fetchPacients().done(() => {
                                if (idToHighlight) {
                                    let elementToFlash;
                                    if (patientState.viewMode === 'grid') { elementToFlash = $(`.card .edit-btn[data-id="${idToHighlight}"]`).closest('.card'); }
                                    else { elementToFlash = $(`tr .edit-btn[data-id="${idToHighlight}"]`).closest('tr'); }
                                    if (typeof flashElement === 'function' && elementToFlash && elementToFlash.length > 0) { setTimeout(() => { flashElement(elementToFlash); }, 50); }
                                }
                            });
                        } else { fetchPacients(); }
                    } else if (userRole === 'fisio' || userRole === 'superadmin') {
                        <?php if ($user_rol === 'superadmin'): ?> fetchFisios(); <?php else: ?> fetchPacients(); <?php endif; ?>
                    } else {
                        fetchPacients();
                        <?php if ($user_rol === 'superadmin'): ?> if (typeof fetchFisios === 'function' && fisiosLoaded) fetchFisios(); <?php endif; ?>
                    }
                } else { showToast(res.message || 'Error', 'danger'); }
            }).fail(xhr => showToast(xhr.responseJSON?.message || 'Error', 'danger')).always(() => { button.prop('disabled', false).text(originalButtonText); pendingAction = null; userToManage = { id: null, name: '', role: '', status: '' }; });
        }
    });

    $('#userActionConfirmModal').on('hidden.bs.modal', function () { $('#userActionConfirmModalBody').html(''); });

    $(document).on('click', '.impersonate-btn', function(e) {
        e.preventDefault();
        if (IS_IMPERSONATING) { showToast('Ya estás suplantando a un usuario. Cierra la sesión de suplantación actual primero.', 'warning'); return; }
        if ($(this).hasClass('disabled')) return;
        const userIdToImpersonate = $(this).data('id');
        const userName = $(this).data('name');
        if (confirm(`Estàs segur que vols "suplantar" a ${userName}?\n\nVeuràs la plataforma exactament com la veu aquest usuari. Podràs tornar al teu compte des d'una barra d'advertència superior.`)) {
            window.location.href = `impersonate.php?id=${userIdToImpersonate}`;
        }
    });

    <?php if ($user_rol === 'superadmin'): ?> $(document).on('click', '.summary-btn', function() { const fisioId = $(this).data('id'); loadFisioDetailedSummary(fisioId); }); <?php endif; ?>
    $(document).on('click', '.open-summary-modal-link', function(e) { e.preventDefault(); const targetTab = $(this).data('target-tab'); let targetUserId = null; if ($(this).hasClass('summary-btn')) { targetUserId = $(this).data('id'); } loadFisioDetailedSummary(targetUserId, targetTab); });

    if ($('#filterMyPatients').length > 0) { $('#filterMyPatients').prop('checked', patientState.filterMine); }
    $(`#patientStatusFilter`).val(patientState.statusFilter);
    <?php if ($user_rol === 'superadmin'): ?> $(`#fisioStatusFilter`).val(fisioState.statusFilter); $('#fisio-sort-buttons-group').hide(); <?php endif; ?>

    $('#pacients-panel .toggle-view-btn').removeClass('active');
    if (patientState.viewMode === 'grid') { $('#gridViewBtnPatient').addClass('active'); $('#patient-sort-buttons-group').show(); } else { $('#listViewBtnPatient').addClass('active'); $('#patient-sort-buttons-group').hide(); }

    <?php if ($user_rol === 'superadmin'): ?>
    if (initialTab === 'fisios') {
        new bootstrap.Tab($('#fisios-tab')).show();
        fetchFisios(); fisiosLoaded = true; fetchPacients();
    } else { new bootstrap.Tab($('#pacients-tab')).show(); fetchPacients(); }
    <?php else: ?> fetchPacients(); <?php endif; ?>
});
</script>
</body>
</html>
