<?php
// Módulo Clientes - Listado (UX replicado de Leads)
if (session_status() === PHP_SESSION_NONE) { session_start(); }
if (!defined('BASE_PATH')) { define('BASE_PATH', dirname(dirname(__DIR__))); }
require_once BASE_PATH . '/database/config.php';
require_once BASE_PATH . '/database/connection.php';
require_once BASE_PATH . '/modules/shared/helpers.php';

if (!function_exists('isLoggedIn')) { function isLoggedIn(){ return isset($_SESSION['user_id']) && !empty($_SESSION['user_id']); } }
if (!isLoggedIn()) { header('Location: ' . route_url(['module'=>'auth','action'=>'login'])); exit; }

$db = Database::getInstance();
$pdo = $db->getConnection();

// Helper de permisos
if (!function_exists('userHasPermissionByName')) {
    function userHasPermissionByName(PDO $pdo, string $permName, int $userId): bool {
        if (empty($userId)) return false;
        $stmt = $pdo->prepare("SELECT 1 FROM role_permissions rp INNER JOIN permissions p ON rp.permission_id = p.id INNER JOIN user_roles ur ON rp.role_id = ur.role_id WHERE ur.user_id = ? AND p.name = ? LIMIT 1");
        $stmt->execute([$userId, $permName]);
        return (bool)$stmt->fetchColumn();
    }
}
if (!function_exists('isAdminRole')) {
    function isAdminRole(PDO $pdo, int $userId): bool {
        if ($userId <= 0) return false;
        $stmt = $pdo->prepare("SELECT 1 FROM user_roles ur INNER JOIN roles r ON ur.role_id = r.id WHERE ur.user_id = ? AND r.name = 'admin' LIMIT 1");
        $stmt->execute([$userId]);
        return (bool)$stmt->fetchColumn();
    }
}

$current_user_id = (int)($_SESSION['user_id'] ?? 0);
$canAccessClients = isAdminRole($pdo, $current_user_id)
    || userHasPermissionByName($pdo, 'clients.view', $current_user_id)
    || userHasPermissionByName($pdo, 'menu.clients.view', $current_user_id);
if (!$canAccessClients) { http_response_code(403); echo 'Acceso restringido'; exit; }

// Helpers de enmascarado
function maskGeneric($value, $first = 3, $last = 2) {
    $v = (string)$value; $len = strlen($v);
    if ($len <= ($first + $last)) { return str_repeat('*', max(0, $len)); }
    return substr($v, 0, $first) . str_repeat('*', $len - ($first + $last)) . substr($v, -$last);
}
function maskEmail($email, $first = 3, $last = 2) {
    $e = (string)$email;
    if (strpos($e, '@') === false) { return maskGeneric($e, $first, $last); }
    list($local, $domain) = explode('@', $e, 2);
    $localMasked = maskGeneric($local, $first, $last);
    $domainLen = strlen($domain);
    $domainMasked = $domainLen <= $last ? str_repeat('*', max(0, $domainLen)) : str_repeat('*', $domainLen - $last) . substr($domain, -$last);
    return $localMasked . '@' . $domainMasked;
}
function maskPhone($phone, $first = 3, $last = 2) {
    $digits = preg_replace('/\D+/', '', (string)$phone);
    $len = strlen($digits);
    if ($len === 0) { return ''; }
    $visibleStart = min($first, max(0, $len));
    $visibleEnd = min($last, max(0, $len - $visibleStart));
    return substr($digits, 0, $visibleStart) . str_repeat('*', max(0, $len - ($visibleStart + $visibleEnd))) . substr($digits, -$visibleEnd);
}

// Parámetros de filtros
$search = trim($_GET['search'] ?? '');
$status_filter = $_GET['status'] ?? '';
$desk_filter = $_GET['desk'] ?? '';
$assigned_filter = $_GET['assigned'] ?? '';
$online_filter = $_GET['online'] ?? '';
$country_filter = $_GET['country'] ?? '';

// Detectar soporte de desk_status para filtros
$hasClientDeskStatus = false;
try { $col = $pdo->query("SHOW COLUMNS FROM `clients` LIKE 'desk_status'"); $hasClientDeskStatus = (bool)$col->fetch(); } catch (Exception $e) { $hasClientDeskStatus = false; }
$statusExpr = $hasClientDeskStatus ? "c.desk_status" : "l.status";

// Presencia dinámica: usar last_seen si existe, si no updated_at/created_at
$hasClientLastSeen = false;
try { $col = $pdo->query("SHOW COLUMNS FROM `clients` LIKE 'last_seen'"); $hasClientLastSeen = (bool)$col->fetch(); } catch (Exception $e) { $hasClientLastSeen = false; }
$presenceExpr = $hasClientLastSeen
    ? "(c.last_seen IS NOT NULL AND TIMESTAMPDIFF(MINUTE, c.last_seen, NOW()) <= 5)"
    : "0";
$onlineCaseSQL = $hasClientLastSeen
    ? "CASE WHEN (c.last_seen IS NOT NULL AND TIMESTAMPDIFF(MINUTE, c.last_seen, NOW()) <= 5) THEN 1 ELSE 0 END AS is_online"
    : "0 AS is_online";

// Asignación directa en clients (columna opcional)
$hasClientAssigned = false;
try { $col = $pdo->query("SHOW COLUMNS FROM `clients` LIKE 'assigned_to'"); $hasClientAssigned = (bool)$col->fetch(); } catch (Exception $e) { $hasClientAssigned = false; }
$assignedExpr = $hasClientAssigned ? "COALESCE(c.assigned_to, l.assigned_to)" : "l.assigned_to";

// Construir WHERE
$where = [];
$params = [];
if ($search !== '') {
    $where[] = "(c.first_name LIKE ? OR c.last_name LIKE ? OR c.email LIKE ? OR c.phone LIKE ?)";
    $s = "%$search%"; $params = array_merge($params, [$s,$s,$s,$s]);
}
if (!empty($status_filter)) { $where[] = $statusExpr . " = ?"; $params[] = $status_filter; }
if (!empty($desk_filter)) { $where[] = "c.desk_id = ?"; $params[] = $desk_filter; }
if (!empty($assigned_filter)) { $where[] = $assignedExpr . " = ?"; $params[] = $assigned_filter; }
if (!empty($country_filter)) { $where[] = $countryExpr . " = ?"; $params[] = $country_filter; }
if (!empty($online_filter)) {
    if ($online_filter === 'online') { $where[] = $presenceExpr; }
    elseif ($online_filter === 'offline') { $where[] = "NOT(" . $presenceExpr . ")"; }
}
$whereSql = empty($where) ? '' : ('WHERE ' . implode(' AND ', $where));

// Restringir visibilidad: si no es admin ni tiene clients.view_all, ver solo asignados a sí mismo (cliente o lead)
if (!isAdminRole($pdo, $current_user_id) && !userHasPermissionByName($pdo, 'clients.view_all', $current_user_id)) {
    $whereSql = ($whereSql === '' ? 'WHERE ' : $whereSql . ' AND ') . ' (' . $assignedExpr . ' = ?)';
    $params[] = $current_user_id;
}

// Consulta principal
$selectAssignedClientCols = $hasClientAssigned ? "c.assigned_to AS client_assigned_to," : "NULL AS client_assigned_to,";
$joinAssignedClient = $hasClientAssigned ? "LEFT JOIN users ucli ON c.assigned_to = ucli.id" : "";
$hasClientDeskStatus = false;
try { $col = $pdo->query("SHOW COLUMNS FROM `clients` LIKE 'desk_status'"); $hasClientDeskStatus = (bool)$col->fetch(); } catch (Exception $e) { $hasClientDeskStatus = false; }
$deskStatusSelectSQL = $hasClientDeskStatus ? "c.desk_status" : "l.status";
$hasClientCountry = false;
try { $col = $pdo->query("SHOW COLUMNS FROM `clients` LIKE 'country'"); $hasClientCountry = (bool)$col->fetch(); } catch (Exception $e) { $hasClientCountry = false; }
$countryExpr = $hasClientCountry ? "COALESCE(c.country, l.country)" : "l.country";
$hasPresenceTable = false;
try {
  $stp = $pdo->query("SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'client_presence'");
  $hasPresenceTable = ((int)$stp->fetchColumn() > 0);
} catch (Throwable $__) { $hasPresenceTable = false; }
$sql = "SELECT 
            c.id, c.first_name, c.last_name, c.email, c.phone, c.status, c.created_at, c.updated_at,
            c.balance, c.equity, c.margin_percent, c.pnl, c.desk_id, " . $deskStatusSelectSQL . " AS desk_status, " . $selectAssignedClientCols . "
            l.id AS lead_id, " . $countryExpr . " AS country, l.assigned_to AS lead_assigned_to,
            ulead.first_name AS lead_assigned_first_name, ulead.last_name AS lead_assigned_last_name,
            " . ($hasClientAssigned ? "ucli.first_name AS client_assigned_first_name, ucli.last_name AS client_assigned_last_name," : "NULL AS client_assigned_first_name, NULL AS client_assigned_last_name,") . "
            d.name AS desk_name,
            $onlineCaseSQL,
            " . ($hasPresenceTable ? "cp.last_seen" : "NULL") . " AS presence_last_seen
        FROM clients c
        LEFT JOIN leads l ON c.lead_id = l.id
        LEFT JOIN users ulead ON l.assigned_to = ulead.id
        " . $joinAssignedClient . "
        " . ($hasPresenceTable ? "LEFT JOIN client_presence cp ON cp.client_id = c.id" : "") . "
        LEFT JOIN desks d ON c.desk_id = d.id
        $whereSql
        ORDER BY c.created_at DESC";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$clients = $stmt->fetchAll(PDO::FETCH_ASSOC);

// Stats
$totalClients = $activeClients = $inactiveClients = $suspendedClients = 0;
try {
    $totalClients = (int)$pdo->query("SELECT COUNT(*) FROM clients")->fetchColumn();
    $activeClients = (int)$pdo->query("SELECT COUNT(*) FROM clients WHERE status = 'active'")->fetchColumn();
    $inactiveClients = (int)$pdo->query("SELECT COUNT(*) FROM clients WHERE status = 'inactive'")->fetchColumn();
    $suspendedClients = (int)$pdo->query("SELECT COUNT(*) FROM clients WHERE status = 'suspended'")->fetchColumn();
} catch (Exception $e) {}

// Datos para filtros
// Desks activos siempre
$desks = [];
try { $desks = $pdo->query("SELECT id, name FROM desks WHERE status = 'active' ORDER BY name")->fetchAll(); } catch (Exception $e) {}

// Estados: si hay desk seleccionado, usar permitidos de ese desk; si no, todos los del sistema
$statuses = [];
try {
  if (!empty($desk_filter)) {
    $st = $pdo->prepare("SELECT DISTINCT status FROM desk_allowed_statuses WHERE desk_id = ? ORDER BY status");
    $st->execute([$desk_filter]);
    $statuses = $st->fetchAll(PDO::FETCH_COLUMN) ?: [];
  } else {
    // Todos los estatus del sistema: unión de desk_allowed_statuses de desks activos + existentes en clientes/leads
    $rows1 = $pdo->query("SELECT DISTINCT das.status FROM desk_allowed_statuses das INNER JOIN desks d ON das.desk_id = d.id WHERE d.status='active' ORDER BY das.status")->fetchAll(PDO::FETCH_COLUMN) ?: [];
    $rows2 = $pdo->query("SELECT DISTINCT desk_status FROM clients WHERE desk_status IS NOT NULL AND desk_status <> '' ORDER BY desk_status")->fetchAll(PDO::FETCH_COLUMN) ?: [];
    $rows3 = $pdo->query("SELECT DISTINCT status FROM leads WHERE status IS NOT NULL AND status <> '' ORDER BY status")->fetchAll(PDO::FETCH_COLUMN) ?: [];
    $set = [];
    foreach (array_merge($rows1, $rows2, $rows3) as $s) { if (!empty($s)) { $set[$s] = true; } }
    $statuses = array_keys($set);
    sort($statuses);
  }
} catch (Exception $e) {}

// Agentes: si hay desk seleccionado, mostrar solo los del desk; si no, todos activos
$users = [];
try {
  if (!empty($desk_filter)) {
    $st = $pdo->prepare("SELECT u.id, u.first_name, u.last_name FROM desk_users du INNER JOIN users u ON du.user_id = u.id WHERE du.desk_id = ? AND u.status = 'active' ORDER BY u.first_name, u.last_name");
    $st->execute([$desk_filter]);
    $users = $st->fetchAll() ?: [];
  } else {
    $users = $pdo->query("SELECT id, first_name, last_name FROM users WHERE status = 'active' ORDER BY first_name, last_name")->fetchAll() ?: [];
  }
} catch (Exception $e) {}
$countries = [];
try { $countries = $pdo->query("SELECT DISTINCT country FROM leads WHERE country IS NOT NULL AND country <> '' ORDER BY country")->fetchAll(PDO::FETCH_COLUMN); } catch (Exception $e) {}

// Permisos de masking
$canViewClientEmailFull = userHasPermissionByName($pdo, 'client_email_mask', $current_user_id) || userHasPermissionByName($pdo, 'clients.view_email_full', $current_user_id);
$canViewClientPhoneFull = userHasPermissionByName($pdo, 'client_number_mask', $current_user_id) || userHasPermissionByName($pdo, 'clients.view_phone_full', $current_user_id);

// Permisos para acciones de íconos
$canManualDeposit = userHasPermissionByName($pdo, 'clients.manual_deposit', $current_user_id);
$canCreateAccount = userHasPermissionByName($pdo, 'clients.create_account', $current_user_id);
$canImpersonate = userHasPermissionByName($pdo, 'clients.impersonate', $current_user_id);
$canBulkEdit = userHasPermissionByName($pdo, 'clients.edit', $current_user_id) || userHasPermissionByName($pdo, 'clients.change_status', $current_user_id);

// Render
$page_title = 'Clientes';
$current_module = 'clients';
$current_action = 'index';
ob_start();
?>
<div class="roles-header">
    <div class="header-left">
        <h1 class="page-title">
            <svg class="title-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <path d="M16 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/>
                <circle cx="12" cy="7" r="4"/>
            </svg>
            Gestión de Clientes
        </h1>
        <p class="page-subtitle">Administra clientes, estados y actividad financiera.</p>
    </div>
</div>

<section class="stats-grid" style="margin-bottom:1rem;">
    <div class="stat-card" data-stat-key="total">
        <div class="stat-icon bg-blue-500">
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M16 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
        </div>
        <div class="stat-content">
            <div class="stat-number"><?php echo number_format($totalClients, 0, ',', '.'); ?></div>
            <div class="stat-label">Total</div>
        </div>
    </div>
    <div class="stat-card" data-stat-key="active">
        <div class="stat-icon bg-green-500">
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 12l2 2 4-4"/><circle cx="12" cy="12" r="10"/></svg>
        </div>
        <div class="stat-content"><div class="stat-number"><?php echo number_format($activeClients, 0, ',', '.'); ?></div><div class="stat-label">Activos</div></div>
    </div>
    <div class="stat-card" data-stat-key="inactive">
        <div class="stat-icon bg-yellow-500">
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="9"/><path d="M9 12h6"/></svg>
        </div>
        <div class="stat-content"><div class="stat-number"><?php echo number_format($inactiveClients, 0, ',', '.'); ?></div><div class="stat-label">Inactivos</div></div>
    </div>
    <div class="stat-card" data-stat-key="suspended">
        <div class="stat-icon bg-teal-500">
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="9"/><path d="M4 4l16 16"/></svg>
        </div>
        <div class="stat-content"><div class="stat-number"><?php echo number_format($suspendedClients, 0, ',', '.'); ?></div><div class="stat-label">Suspendidos</div></div>
    </div>
</section>

<section class="card" style="margin-bottom:1rem;">
  <div class="card-body">
    <form method="GET" class="filters-form">
      <input type="hidden" name="module" value="clients">
      <div class="search-box">
        <svg class="search-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
        <input type="text" name="search" value="<?php echo htmlspecialchars($search); ?>" placeholder="Buscar por nombre, email o teléfono..." class="search-input">
      </div>
      <div class="filter-group">
        <select name="status" id="filterStatus" class="filter-select">
          <option value="">Todos los estados</option>
          <?php foreach ($statuses as $st): ?>
            <option value="<?php echo htmlspecialchars($st); ?>" <?php echo ($status_filter===$st)?'selected':''; ?>><?php echo htmlspecialchars($st); ?></option>
          <?php endforeach; ?>
        </select>
        <select name="desk" id="filterDesk" class="filter-select">
          <option value="">Todos los escritorios</option>
          <?php foreach ($desks as $d): ?>
            <option value="<?php echo (int)$d['id']; ?>" <?php echo ($desk_filter==(string)$d['id'])?'selected':''; ?>><?php echo htmlspecialchars($d['name']); ?></option>
          <?php endforeach; ?>
        </select>
        <select name="assigned" id="filterAssigned" class="filter-select">
          <option value="">Todos los agentes</option>
          <?php foreach ($users as $u): ?>
            <option value="<?php echo (int)$u['id']; ?>" <?php echo ($assigned_filter==(string)$u['id'])?'selected':''; ?>><?php echo htmlspecialchars($u['first_name'] . ' ' . $u['last_name']); ?></option>
          <?php endforeach; ?>
        </select>
        <select name="country" class="filter-select">
          <option value="">Todos los países</option>
          <?php foreach ($countries as $coun): ?>
            <option value="<?php echo htmlspecialchars($coun); ?>" <?php echo ($country_filter===$coun)?'selected':''; ?>><?php echo htmlspecialchars($coun); ?></option>
          <?php endforeach; ?>
        </select>
        <select name="online" class="filter-select">
          <option value="">Todos (Online/Offline)</option>
          <option value="online" <?php echo ($online_filter==='online')?'selected':''; ?>>Online</option>
          <option value="offline" <?php echo ($online_filter==='offline')?'selected':''; ?>>Offline</option>
        </select>
      </div>
      <div class="filter-actions">
        <button type="submit" class="btn-primary">Filtrar</button>
        <a href="?module=clients" class="btn-secondary">Limpiar</a>
      </div>
    </form>
  </div>
  <style>
    .filters-form{display:grid;gap:12px}
    .search-box{position:relative}
    .search-icon{position:absolute;left:12px;top:50%;transform:translateY(-50%);color:#64748b}
    .search-input{width:100%;padding:.75rem 1rem .75rem 2.25rem;border:1px solid var(--border-light);border-radius:10px}
    .filter-group{display:grid;grid-template-columns:repeat(6,1fr);gap:12px}
    .filter-select{width:100%;min-height:40px;padding:.5rem .75rem;border:1px solid var(--border-light);border-radius:10px}
    .filter-actions{display:flex;gap:12px;justify-content:space-between;align-items:center}
    @media (max-width:1024px){.filter-group{grid-template-columns:repeat(3,1fr)}}
    @media (max-width:640px){.filter-group{grid-template-columns:1fr}}
  </style>
</section>

<section class="card">
    <div class="card-body">
        <form id="bulkForm" method="post" action="<?php echo module_url('clients/actions.php'); ?>" style="display:none; margin-bottom:12px" class="bulk-actions">
          <input type="hidden" name="action" value="bulk_update">
          <input type="hidden" name="redirect" value="<?php echo route_url(['module'=>'clients']); ?>">
          <div class="bulk-info"><span class="bulk-count">0</span> clientes seleccionados</div>
          <div class="bulk-buttons" style="display:flex; gap:10px; flex-wrap:wrap; align-items:center">
            <select name="new_status" id="bulkStatusSelect" class="filter-select" style="min-width:200px">
              <option value="">Cambiar estado...</option>
            </select>
            <select name="new_desk_id" class="filter-select" style="min-width:200px">
              <option value="">Cambiar desk...</option>
              <?php foreach ($desks as $d): ?>
                <option value="<?php echo (int)$d['id']; ?>"><?php echo htmlspecialchars($d['name']); ?></option>
              <?php endforeach; ?>
            </select>
            <select name="new_assigned_user_id" id="bulkAgentSelect" class="filter-select" style="min-width:220px">
              <option value="">Asignar agente...</option>
              
            </select>
            <button type="submit" class="btn-primary">Aplicar</button>
            <button type="button" id="bulkClear" class="btn-secondary">Limpiar selección</button>
            <button type="button" class="bulk-close btn-ghost" title="Cerrar">&times;</button>
          </div>
        </form>
        <style>
          .bulk-actions{position:fixed;left:50%;bottom:18px;transform:translateX(-50%);background:#fff;border:1px solid #e5e7eb;border-radius:16px;box-shadow:0 20px 40px rgba(0,0,0,.12);padding:10px 14px;z-index:2500;display:none;min-width:640px}
          .bulk-actions .bulk-info{font-weight:700;color:#334155;margin-bottom:6px}
          .bulk-actions .filter-select{height:38px;border-radius:10px}
          .bulk-actions .btn-primary{background:linear-gradient(180deg,#3b82f6,#2563eb);border:0;border-radius:10px;height:38px;padding:0 14px;color:#fff}
          .bulk-actions .btn-secondary{background:#f3f4f6;border:1px solid #e5e7eb;border-radius:10px;height:38px;padding:0 12px;color:#111827}
          .bulk-actions .btn-ghost{background:transparent;border:0;color:#64748b; height:38px; padding:0 10px}
          @media (max-width:768px){ .bulk-actions{min-width:unset;width:94vw} .bulk-actions .bulk-buttons{flex-direction:column; align-items:stretch} }
        </style>
        <div class="table-responsive">
        <table class="data-table" id="clientsTable">
            <thead>
                <tr>
                    <th style="width:36px"><input type="checkbox" id="selectAll"></th>
                    <th>Nombre</th>
                    <th>Email</th>
                    <th>Teléfono</th>
                    <th>País</th>
                    <th>Asignado a</th>
                    <th>Desk</th>
                    <th>Status</th>
                    <th>Online</th>
                    <th>Balance</th>
                    <th>Equity</th>
                    <th>% Margen</th>
                    <th>PnL</th>
                    <th>Creado</th>
                    <th>Acciones</th>
                </tr>
            </thead>
            <tbody>
            <?php foreach ($clients as $c): ?>
                <tr data-client-id="<?php echo (int)$c['id']; ?>" data-desk-id="<?php echo (int)($c['desk_id'] ?? 0); ?>">
                    <td><input type="checkbox" class="rowSelect" value="<?php echo (int)$c['id']; ?>"></td>
                    <td><?php echo htmlspecialchars(($c['first_name'] ?? '') . ' ' . ($c['last_name'] ?? '')); ?></td>
                    <?php $emailDisplay = $canViewClientEmailFull ? ($c['email'] ?? '') : maskEmail($c['email'] ?? '');
                          $phoneDisplay = $canViewClientPhoneFull ? ($c['phone'] ?? '') : maskPhone($c['phone'] ?? ''); ?>
                    <td><?php echo htmlspecialchars($emailDisplay); ?></td>
                    <td><?php echo htmlspecialchars($phoneDisplay); ?></td>
                    <td><?php echo htmlspecialchars($c['country'] ?? ''); ?></td>
                    <?php 
                      $assignedName = '';
                      if (!empty($c['client_assigned_to'])) { $assignedName = trim(($c['client_assigned_first_name'] ?? '') . ' ' . ($c['client_assigned_last_name'] ?? '')); }
                      elseif (!empty($c['lead_assigned_to'])) { $assignedName = trim(($c['lead_assigned_first_name'] ?? '') . ' ' . ($c['lead_assigned_last_name'] ?? '')); }
                      if ($assignedName === '') $assignedName = 'Sin asignar';
                    ?>
                    <td><?php echo htmlspecialchars($assignedName); ?></td>
                    <td><?php echo htmlspecialchars($c['desk_name'] ?? ''); ?></td>
                    <td><span class="status-badge bg-teal-100 text-teal-800"><?php echo htmlspecialchars($c['desk_status'] ?? ''); ?></span></td>
                    <td>
                        <?php if (!empty($c['is_online'])): ?>
                            <span class="status-badge bg-emerald-100 text-emerald-800">ONLINE</span>
                        <?php else: ?>
                            <span class="status-badge bg-gray-100 text-gray-800">OFFLINE</span>
                        <?php endif; ?>
                    </td>
                    <td><?php echo number_format((float)($c['balance'] ?? 0), 2, ',', '.'); ?></td>
                    <td><?php echo number_format((float)($c['equity'] ?? 0), 2, ',', '.'); ?></td>
                    <td><?php echo number_format((float)($c['margin_percent'] ?? 0), 2, ',', '.'); ?>%</td>
                    <td><?php echo number_format((float)($c['pnl'] ?? 0), 2, ',', '.'); ?></td>
                    <td><?php echo htmlspecialchars($c['created_at'] ?? ''); ?></td>
                    <td>
                        <div class="action-buttons">
                          <a href="<?php echo route_url(['module'=>'clients','action'=>'view','id'=>(int)$c['id']]); ?>" class="action-btn-small view" title="Ver">
                            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
                          </a>
                          <?php if ($canManualDeposit): ?>
                          <a href="#" data-client-id="<?php echo (int)$c['id']; ?>" class="action-btn-small deposit js-open-deposit" title="Depósito manual">
                            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="7" width="20" height="14" rx="2"/><path d="M2 11h20M6 15h2"/></svg>
                          </a>
                          <?php endif; ?>
                          <?php if ($canCreateAccount): ?>
                          <a href="#" data-client-id="<?php echo (int)$c['id']; ?>" class="action-btn-small create js-open-create-account" title="Crear cuenta">
                            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="4" width="18" height="16" rx="3"/><path d="M12 8v8M8 12h8"/></svg>
                          </a>
                          <?php endif; ?>
                          <?php if ($canImpersonate): ?>
                          <a href="<?php echo module_url('clients/api/traderroom_impersonate.php'); ?>?client_id=<?php echo (int)$c['id']; ?>" class="action-btn-small user" title="Abrir Trader Room" target="_blank" rel="noopener">
                            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="8" r="4"/><path d="M4 20v-2a6 6 0 0 1 12 0v 2"/></svg>
                          </a>
                          <?php endif; ?>
                        </div>
                    </td>
                </tr>
            <?php endforeach; ?>
            </tbody>
        </table>
        </div>
    </div>
</section>
<script>
(function(){
  var sa = document.getElementById('selectAll');
  if (sa) {
    sa.addEventListener('change', function(){
      document.querySelectorAll('#clientsTable .rowSelect').forEach(function(cb){ cb.checked = sa.checked; });
      updateBulkBar();
    });
  }
  function selectedIds(){ return Array.prototype.slice.call(document.querySelectorAll('#clientsTable .rowSelect:checked')).map(function(cb){ return cb.value; }); }
  function selectedDesks(){ return Array.prototype.slice.call(document.querySelectorAll('#clientsTable .rowSelect:checked')).map(function(cb){ var tr = cb.closest('tr'); return tr ? tr.getAttribute('data-desk-id') : ''; }).filter(function(x){ return !!x; }); }
  function updateBulkBar(){
    var ids = selectedIds();
    var bar = document.getElementById('bulkForm');
    var cnt = document.getElementById('bulkCount');
    if (!bar) return;
    var cntEl = bar.querySelector('.bulk-count');
    // Anclar al viewport para evitar que se mueva con el contenido
    if (bar.parentNode !== document.body) { document.body.appendChild(bar); }
    if (ids.length){ bar.style.display='block'; if (cntEl) cntEl.textContent = ids.length; }
    else { bar.style.display='none'; if (cntEl) cntEl.textContent = '0'; }
    var dkSel = bar.querySelector('select[name="new_desk_id"]');
    var stSel = document.getElementById('bulkStatusSelect');
    var agSel = document.getElementById('bulkAgentSelect');
    var desks = selectedDesks(); var uniqueDesks = Array.from(new Set(desks));
    if (uniqueDesks.length === 1 && uniqueDesks[0]) { if (dkSel) dkSel.value = uniqueDesks[0]; loadDeskStatuses(uniqueDesks[0]); loadDeskAgents(uniqueDesks[0]); }
    else {
      // Si el usuario seleccionó desk manualmente, usarlo
      var currentDesk = dkSel ? (dkSel.value||'') : '';
      if (currentDesk) { loadDeskStatuses(currentDesk); loadDeskAgents(currentDesk); }
      else { if (stSel) stSel.innerHTML = '<option value="">Cambiar estado...</option>'; if (agSel) agSel.innerHTML = '<option value="">Asignar agente...</option>'; }
    }
  }
  document.addEventListener('change', function(ev){ if (ev.target && ev.target.classList && ev.target.classList.contains('rowSelect')){ updateBulkBar(); } });
  var bulkClear = document.getElementById('bulkClear'); if (bulkClear){ bulkClear.addEventListener('click', function(){ document.querySelectorAll('#clientsTable .rowSelect').forEach(function(cb){ cb.checked=false; }); if (sa) sa.checked=false; updateBulkBar(); }); }
  var bulkForm = document.getElementById('bulkForm'); if (bulkForm){ bulkForm.addEventListener('submit', function(ev){ var ids = selectedIds(); if (!ids.length){ ev.preventDefault(); return; } var hidden = document.createElement('input'); hidden.type='hidden'; hidden.name='client_ids'; hidden.value = ids.join(','); bulkForm.appendChild(hidden); }); }
  var bulkClose = document.querySelector('#bulkForm .bulk-close'); if (bulkClose){ bulkClose.addEventListener('click', function(){ document.querySelectorAll('#clientsTable .rowSelect').forEach(function(cb){ cb.checked=false; }); if (sa) sa.checked=false; updateBulkBar(); }); }
  function loadDeskStatuses(deskId){ var stSel = document.getElementById('bulkStatusSelect'); if (!stSel) return; stSel.innerHTML = '<option value="">Cargando estados...</option>'; fetch('<?php echo module_url('clients/api/get_desk_statuses.php'); ?>?desk_id='+encodeURIComponent(deskId)).then(function(r){return r.json()}).then(function(j){ var arr = (j && j.success && Array.isArray(j.statuses)) ? j.statuses : []; stSel.innerHTML = '<option value="">Cambiar estado...</option>' + arr.map(function(s){ return '<option value="'+s+'">'+s.replace('_',' ')+'</option>'; }).join(''); }).catch(function(){ stSel.innerHTML = '<option value="">Error cargando</option>'; }); }
  function loadDeskAgents(deskId){ var agSel = document.getElementById('bulkAgentSelect'); if (!agSel) return; agSel.innerHTML = '<option value="">Cargando agentes...</option>'; fetch('<?php echo module_url('clients/api/get_desk_users.php'); ?>?desk_id='+encodeURIComponent(deskId)).then(function(r){return r.json()}).then(function(j){ var arr = (j && j.success && Array.isArray(j.users)) ? j.users : []; agSel.innerHTML = '<option value="">Asignar agente...</option>' + arr.map(function(u){ return '<option value="'+u.id+'">'+(u.full_name||('Usuario '+u.id))+'</option>'; }).join(''); }).catch(function(){ agSel.innerHTML = '<option value="">Error cargando</option>'; }); }
  var dkSelGlobal = document.querySelector('select[name="new_desk_id"]'); if (dkSelGlobal){ dkSelGlobal.addEventListener('change', function(){ var val = this.value||''; if (val){ loadDeskStatuses(val); loadDeskAgents(val); } }); }
  window.addEventListener('storage', function(ev){ try { if (ev.key === 'clients_status_changed' && ev.newValue){ var data = JSON.parse(ev.newValue); var tr = document.querySelector('tr[data-client-id="'+data.client_id+'"]'); if (tr){ var cell = tr.querySelector('td:nth-child(7) .status-badge'); if (cell){ cell.textContent = data.status; } } localStorage.removeItem('clients_status_changed'); } } catch(e){} });
})();
</script>
<script>
(function(){
  var bf = document.getElementById('bulkForm');
  if (bf) {
    bf.addEventListener('submit', function(ev){
      var ids = Array.prototype.slice.call(document.querySelectorAll('#clientsTable .rowSelect:checked')).map(function(cb){ return cb.value; });
      if (!ids.length) { ev.preventDefault(); return; }
      var stSel = bf.querySelector('select[name="new_status"]');
      var dkSel = bf.querySelector('select[name="new_desk_id"]');
      var agSel = bf.querySelector('select[name="new_assigned_user_id"]');
      var parts = [];
      if (stSel && stSel.value) parts.push('Estado: ' + stSel.options[stSel.selectedIndex].text);
      if (dkSel && dkSel.value) parts.push('Desk: ' + dkSel.options[dkSel.selectedIndex].text);
      if (agSel && agSel.value) parts.push('Agente: ' + agSel.options[agSel.selectedIndex].text);
      var msg = 'Aplicar a ' + ids.length + ' clientes';
      if (parts.length) msg += '\n' + parts.join('\n');
      if (!confirm(msg)) { ev.preventDefault(); }
    });
  }
  var p = new URLSearchParams(window.location.search);
  var toast;
  function showToast(text, ok){
    if (toast) { try{ toast.remove(); }catch(e){} }
    toast = document.createElement('div');
    toast.style.position='fixed'; toast.style.right='16px'; toast.style.top='16px'; toast.style.zIndex='3000'; toast.style.padding='10px 12px'; toast.style.borderRadius='10px'; toast.style.boxShadow='0 10px 20px rgba(0,0,0,.12)';
    if (ok) { toast.style.background='#dcfce7'; toast.style.color='#166534'; }
    else { toast.style.background='#fee2e2'; toast.style.color='#7f1d1d'; }
    toast.textContent = text;
    document.body.appendChild(toast);
    setTimeout(function(){ if (toast && toast.remove) toast.remove(); }, 5000);
  }
  if (p.get('message')==='bulk_updated'){
    var count = p.get('count') || '0';
    var status = p.get('status') || '0';
    var desk = p.get('desk') || '0';
    var ok = p.get('assigned_ok') || '0';
    var skipNoDesk = p.get('assigned_skip_no_desk') || '0';
    var skipNoLead = p.get('assigned_skip_no_lead') || '0';
    var skipNotInDesk = p.get('assigned_skip_not_in_desk') || '0';
    var parts = [];
    parts.push('Total: ' + count);
    if (status!=='0') parts.push('Estado: ' + status);
    if (desk!=='0') parts.push('Desk: ' + desk);
    if (ok!=='0' || skipNoDesk!=='0' || skipNoLead!=='0' || skipNotInDesk!=='0'){
      parts.push('Asignados OK: ' + ok);
      if (skipNoDesk!=='0') parts.push('Sin desk: ' + skipNoDesk);
      if (skipNoLead!=='0') parts.push('Sin lead vinculado: ' + skipNoLead);
      if (skipNotInDesk!=='0') parts.push('Usuario fuera de desk: ' + skipNotInDesk);
    }
    showToast('Actualización masiva aplicada · ' + parts.join(' · '), true);
    var qs = window.location.search.replace(/([?&])message=[^&]*(&|$)/,'$1').replace(/([?&])count=[^&]*(&|$)/,'$1');
    qs = qs.replace(/([?&])status=[^&]*(&|$)/,'$1').replace(/([?&])desk=[^&]*(&|$)/,'$1').replace(/([?&])assigned_ok=[^&]*(&|$)/,'$1').replace(/([?&])assigned_skip_no_desk=[^&]*(&|$)/,'$1').replace(/([?&])assigned_skip_no_lead=[^&]*(&|$)/,'$1').replace(/([?&])assigned_skip_not_in_desk=[^&]*(&|$)/,'$1');
    qs = qs.replace(/[?&]$/,'');
    history.replaceState(null,'', window.location.pathname + (qs?qs:''));
  }
  if (p.get('error')){
    var txt = 'Error en acción masiva';
    if (p.get('error')==='bulk_empty') txt = 'Selecciona clientes para aplicar acciones';
    showToast(txt, false);
    var qs2 = window.location.search.replace(/([?&])error=[^&]*(&|$)/,'$1');
    qs2 = qs2.replace(/[?&]$/,'');
    history.replaceState(null,'', window.location.pathname + (qs2?qs2:''));
  }
})();
</script>
<div id="depositModal" class="modal" style="display:none; position:fixed; top:50%; left:50%; transform:translate(-50%,-50%); z-index:2000; width:560px;">
  <div class="modal-content" style="position:relative; width:100%; background:var(--bg-primary); border:1px solid var(--border-light); border-radius:12px; box-shadow:var(--shadow-lg); animation: fadeInUp .28s cubic-bezier(0.4,0,0.2,1);">
    <div class="modal-header" style="display:flex; align-items:center; justify-content:space-between; padding:14px 16px; border-bottom:1px solid var(--border-light)">
      <h3 style="margin:0; font-size:1.1rem; color:var(--text-primary)">Depósito manual</h3>
      <button type="button" class="close-modal" aria-label="Cerrar" style="border:0; background:transparent; font-size:22px; color:var(--text-muted); padding:4px 8px">&times;</button>
    </div>
    <div class="modal-body" style="padding:16px">
      <form id="depositForm" method="post" action="<?php echo module_url('clients/actions.php'); ?>" style="display:grid; gap:12px">
        <input type="hidden" name="action" value="manual_deposit">
        <input type="hidden" name="client_id" id="depClientId" value="0">
        <input type="hidden" name="redirect" value="<?php echo route_url(['module'=>'clients']); ?>">
        <div class="form-group">
          <label>Cuenta destino</label>
          <select name="account_id" id="depAccountSelect" class="filter-select" required>
            <option value="">Cargando...</option>
          </select>
        </div>
        <div class="form-group">
          <label>Monto</label>
          <input type="number" step="0.01" min="0.01" name="amount" class="search-input" required>
        </div>
        <div class="form-group" style="display:grid; grid-template-columns:1fr auto; gap:12px">
          <div>
            <label>Moneda</label>
            <input type="text" name="currency" id="depCurrency" value="USD" class="search-input" required readonly>
          </div>
          <div>
            <label>Método</label>
            <input type="text" name="method" value="manual" class="search-input" readonly>
          </div>
        </div>
        <div class="filter-actions" style="display:flex; gap:12px; justify-content:flex-end">
          <button type="submit" class="btn-primary">Registrar depósito</button>
          <button type="button" class="btn-secondary js-close-deposit">Cancelar</button>
        </div>
      </form>
    </div>
  </div>
</div>
<script>
(function(){
  var modal = document.getElementById('depositModal');
  function close(){ if (modal) modal.style.display='none'; }
  function openFor(clientId){
    if (!modal) return;
    document.getElementById('depClientId').value = String(clientId||0);
    modal.style.display='flex';
    try{ document.body.style.overflow='hidden'; }catch(e){}
    var sel = document.getElementById('depAccountSelect');
    var cur = document.getElementById('depCurrency');
    sel.innerHTML = '<option value="">Cargando...</option>';
    var depAccounts = [];
    fetch('<?php echo module_url('clients/api/get_accounts.php'); ?>?client_id=' + encodeURIComponent(clientId))
      .then(function(r){ return r.json(); })
      .then(function(d){
        var arr = Array.isArray(d && d.accounts) ? d.accounts : [];
        depAccounts = arr;
        if (arr.length === 0){ sel.innerHTML = '<option value="">Sin cuentas activas</option>'; return; }
        sel.innerHTML = arr.map(function(a){
          var t = '#' + (a.account_number||'') + ' · ' + (a.account_type||'') + ' · ' + String(a.currency||'').toUpperCase();
          return '<option value="' + a.id + '">' + t + '</option>';
        }).join('');
        try{ if (cur && arr[0] && arr[0].currency) { cur.value = String(arr[0].currency).toUpperCase(); } }catch(e){}
      }).catch(function(){ sel.innerHTML = '<option value="">Error al cargar</option>'; });

    sel.addEventListener('change', function(){
      var id = parseInt(sel.value||0,10);
      var a = depAccounts.find(function(x){ return Number(x.id)===id; });
      if (a && cur) { cur.value = String(a.currency||'USD').toUpperCase(); }
    });
  }
  document.addEventListener('click', function(ev){
    var el = ev.target.closest('.js-open-deposit');
    if (el){ ev.preventDefault(); var id = el.getAttribute('data-client-id'); openFor(id); }
    if (ev.target.closest('.close-modal') || ev.target.closest('.js-close-deposit')){ close(); try{ document.body.style.overflow='auto'; }catch(e){} }
  });
})();
</script>

<?php $msg = $_GET['message'] ?? ''; if ($msg === 'account_created'): $acc = htmlspecialchars($_GET['acc'] ?? ''); $atype = htmlspecialchars($_GET['type'] ?? ''); $cur = htmlspecialchars($_GET['currency'] ?? ''); $lev = htmlspecialchars($_GET['leverage'] ?? ''); ?>
<div id="accountCreatedModal" class="modal" style="display:block; position:fixed; top:50%; left:50%; transform:translate(-50%,-50%); z-index:2100; width:560px;">
  <div class="modal-content" style="position:relative; width:100%; background:var(--bg-primary); border:1px solid var(--border-light); border-radius:12px; box-shadow:var(--shadow-lg); animation: fadeInUp .28s cubic-bezier(0.4,0,0.2,1);">
    <div class="modal-header" style="display:flex; align-items:center; justify-content:space-between; padding:14px 16px; border-bottom:1px solid var(--border-light)">
      <h3 style="margin:0; font-size:1.1rem; color:var(--text-primary)">Cuenta creada satisfactoriamente</h3>
      <button type="button" class="close-modal js-close-created" aria-label="Cerrar" style="border:0; background:transparent; font-size:22px; color:var(--text-muted); padding:4px 8px">&times;</button>
    </div>
    <div class="modal-body" style="padding:16px">
      <div class="form-group"><label>Número de cuenta</label><input type="text" value="<?php echo $acc; ?>" class="search-input" readonly></div>
      <div class="form-group" style="display:grid; grid-template-columns:repeat(3,1fr); gap:12px">
        <div><label>Tipo</label><input type="text" value="<?php echo $atype; ?>" class="search-input" readonly></div>
        <div><label>Moneda</label><input type="text" value="<?php echo $cur; ?>" class="search-input" readonly></div>
        <div><label>Apalancamiento</label><input type="text" value="<?php echo $lev ? ('1:' . $lev) : ''; ?>" class="search-input" readonly></div>
      </div>
      <div class="filter-actions" style="display:flex; gap:12px; justify-content:flex-end; margin-top:12px">
        <a href="<?php echo route_url(['module'=>'clients']); ?>" class="btn-primary">Aceptar</a>
      </div>
    </div>
  </div>
</div>
<script>
(function(){
  document.addEventListener('click', function(ev){ if (ev.target.closest('.js-close-created')){ var m=document.getElementById('accountCreatedModal'); if(m) m.style.display='none'; } });
})();
</script>
<?php endif; ?>

<?php if (($msg ?? '') === 'deposit_recorded'): $damt = htmlspecialchars($_GET['amount'] ?? ''); $dc = htmlspecialchars($_GET['currency'] ?? ''); $da = htmlspecialchars($_GET['account'] ?? ''); $dm = htmlspecialchars($_GET['method'] ?? ''); ?>
<div id="depositRecordedModal" class="modal" style="display:block; position:fixed; top:50%; left:50%; transform:translate(-50%,-50%); z-index:2100; width:560px;">
  <div class="modal-content" style="position:relative; width:100%; background:var(--bg-primary); border:1px solid var(--border-light); border-radius:12px; box-shadow:var(--shadow-lg); animation: fadeInUp .28s cubic-bezier(0.4,0,0.2,1);">
    <div class="modal-header" style="display:flex; align-items:center; justify-content:space-between; padding:14px 16px; border-bottom:1px solid var(--border-light)">
      <h3 style="margin:0; font-size:1.1rem; color:var(--text-primary)">Depósito registrado</h3>
      <button type="button" class="close-modal js-close-deposit-ok" aria-label="Cerrar" style="border:0; background:transparent; font-size:22px; color:var(--text-muted); padding:4px 8px">&times;</button>
    </div>
    <div class="modal-body" style="padding:16px">
      <div class="form-group"><label>Cuenta</label><input type="text" value="<?php echo $da; ?>" class="search-input" readonly></div>
      <div class="form-group" style="display:grid; grid-template-columns:repeat(3,1fr); gap:12px">
        <div><label>Monto</label><input type="text" value="<?php echo $damt; ?>" class="search-input" readonly></div>
        <div><label>Moneda</label><input type="text" value="<?php echo $dc; ?>" class="search-input" readonly></div>
        <div><label>Método</label><input type="text" value="<?php echo $dm; ?>" class="search-input" readonly></div>
      </div>
      <div class="filter-actions" style="display:flex; gap:12px; justify-content:flex-end; margin-top:12px">
        <a href="<?php echo route_url(['module'=>'clients']); ?>" class="btn-primary">Aceptar</a>
      </div>
    </div>
  </div>
</div>
<script>
(function(){
  document.addEventListener('click', function(ev){ if (ev.target.closest('.js-close-deposit-ok')){ var m=document.getElementById('depositRecordedModal'); if(m) m.style.display='none'; } });
})();
</script>
<?php endif; ?>

<div id="createAccountModal" class="modal" style="display:none; position:fixed; top:50%; left:50%; transform:translate(-50%,-50%); z-index:2000; width:560px;">
  <div class="modal-content" style="position:relative; width:100%; background:var(--bg-primary); border:1px solid var(--border-light); border-radius:12px; box-shadow:var(--shadow-lg); animation: fadeInUp .28s cubic-bezier(0.4,0,0.2,1);">
    <div class="modal-header" style="display:flex; align-items:center; justify-content:space-between; padding:14px 16px; border-bottom:1px solid var(--border-light)">
      <h3 style="margin:0; font-size:1.1rem; color:var(--text-primary)">Crear cuenta</h3>
      <button type="button" class="close-modal js-close-create" aria-label="Cerrar" style="border:0; background:transparent; font-size:22px; color:var(--text-muted); padding:4px 8px">&times;</button>
    </div>
    <div class="modal-body" style="padding:16px">
      <form id="createAccountForm" method="post" action="<?php echo module_url('clients/actions.php'); ?>" style="display:grid; gap:12px">
        <input type="hidden" name="action" value="create_account">
        <input type="hidden" name="client_id" id="caClientId" value="0">
        <input type="hidden" name="redirect" value="<?php echo route_url(['module'=>'clients']); ?>">
        <div class="form-group">
          <label>Tipo de cuenta</label>
          <select name="account_type" id="caType" class="filter-select" required>
            <option value="standard">Estándar</option>
            <option value="premium">Premium</option>
            <option value="vip">VIP</option>
            <option value="demo">Demo</option>
          </select>
        </div>
        <div class="form-group">
          <label>Moneda</label>
          <input type="text" name="currency" value="USD" class="search-input" required readonly>
        </div>
        <div class="filter-actions" style="display:flex; gap:12px; justify-content:flex-end">
          <button type="submit" class="btn-primary">Crear cuenta</button>
          <button type="button" class="btn-secondary js-close-create">Cancelar</button>
        </div>
      </form>
    </div>
  </div>
</div>
<script>
(function(){
  var modal = document.getElementById('createAccountModal');
  function close(){ if (modal) { modal.style.display='none'; try{ document.body.style.overflow='auto'; }catch(e){} } }
  function openFor(clientId){ if (!modal) return; document.getElementById('caClientId').value = String(clientId||0); modal.style.display='block'; try{ document.body.style.overflow='hidden'; }catch(e){} }
  document.addEventListener('click', function(ev){
    var el = ev.target.closest('.js-open-create-account');
    if (el){ ev.preventDefault(); var id = el.getAttribute('data-client-id'); openFor(id); }
    if (ev.target.closest('.js-close-create')){ close(); }
  });
})();
</script>
<?php
$content = ob_get_clean();
include BASE_PATH . '/modules/shared/layout.php';
return;
?>
  // Filtros dinámicos por desk
  var fd = document.getElementById('filterDesk');
  var fs = document.getElementById('filterStatus');
  var fa = document.getElementById('filterAssigned');
  function setOptions(sel, items, placeholder){ if (!sel) return; var current = sel.value; sel.innerHTML = '<option value="">'+placeholder+'</option>' + items.map(function(x){ var v = (x.value!=null?x.value:x); var t = (x.text!=null?x.text:x); var selAttr = (String(v)===String(current))?' selected':''; return '<option value="'+v+'"'+selAttr+'>'+t+'</option>'; }).join(''); }
  function loadFilterData(){ var deskId = fd ? (fd.value||'') : ''; var sUrl = '<?php echo module_url('clients/api/get_desk_statuses.php'); ?>' + (deskId?('?desk_id='+encodeURIComponent(deskId)):''); var uUrl = '<?php echo module_url('clients/api/get_desk_users.php'); ?>' + (deskId?('?desk_id='+encodeURIComponent(deskId)):''); fetch(sUrl).then(function(r){return r.json()}).then(function(j){ var arr = (j && j.success && Array.isArray(j.statuses)) ? j.statuses : []; setOptions(fs, arr.map(function(s){ return {value:s, text:s}; }), 'Todos los estados'); }).catch(function(){}); fetch(uUrl).then(function(r){return r.json()}).then(function(j){ var arr = (j && j.success && Array.isArray(j.users)) ? j.users : []; setOptions(fa, arr.map(function(u){ return {value:u.id, text:(u.full_name||('Usuario '+u.id))}; }), 'Todos los agentes'); }).catch(function(){}); }
  if (fd){ fd.addEventListener('change', function(){ loadFilterData(); }); }
  // Cargar al iniciar para reflejar desk seleccionado
  loadFilterData();
