<?php
require_once __DIR__ . '/../db.php';

date_default_timezone_set('Asia/Kolkata');

$vms_sync = $conn->query("SELECT earnapp_token, balance, status, current_ip AS ip_address FROM vms");
if ($vms_sync) {
    while ($row = $vms_sync->fetch_assoc()) {
        $token = $row['earnapp_token'];
        if (empty($token)) continue;
        
        $current_balance = (float)$row['balance'];
        
        $last_record = $conn->query("SELECT redeem_balance FROM earnapp_history WHERE earnapp_token = '" . $conn->real_escape_string($token) . "' ORDER BY recorded_at DESC LIMIT 1")->fetch_assoc();
        
        $previous_balance = $last_record ? (float)$last_record['redeem_balance'] : 0;
        
        if (abs($current_balance - $previous_balance) < 0.0001) {
            continue;
        }
        
        $cashout_detected = 0;

        if (
            $previous_balance >= 0.05  
            && $current_balance <= 0.002 
        ) {
            $cashout_detected = 1;
        }
        
        $stmt = $conn->prepare("INSERT INTO earnapp_history (earnapp_token, ip_address, redeem_balance, cashout_detected, status, earning_date, recorded_at) VALUES (?, ?, ?, ?, ?, CURDATE(), NOW())");
        if ($stmt) {
            $stmt->bind_param("ssdis", $token, $row['ip_address'], $current_balance, $cashout_detected, $row['status']);
            $stmt->execute();
            $stmt->close();
        }
    }
}

$res = $conn->query("SELECT COUNT(*) AS c FROM vms");
$stats['total_vms'] = (int)$res->fetch_assoc()['c'];

$app_running = 0;
$app_paused  = 0;
$app_blocked = 0;

$res = $conn->query("SELECT LOWER(status) AS status, COUNT(*) AS c FROM vms GROUP BY LOWER(status)");
if ($res) {
    while ($r = $res->fetch_assoc()) {
        if ($r['status'] === 'running')  $app_running = (int)$r['c'];
        if ($r['status'] === 'paused' || $r['status'] === 'offline') $app_paused += (int)$r['c'];
        if ($r['status'] === 'blocked')  $app_blocked = (int)$r['c'];
    }
}

$res = $conn->query("SELECT COUNT(*) AS c FROM vms WHERE last_heartbeat IS NOT NULL AND last_heartbeat >= NOW() - INTERVAL 5 MINUTE");
$stats['online_vms'] = (int)$res->fetch_assoc()['c'];

$res = $conn->query("SELECT COUNT(*) AS c FROM vms WHERE last_heartbeat IS NULL OR last_heartbeat < NOW() - INTERVAL 5 MINUTE");
$stats['offline_vms'] = (int)$res->fetch_assoc()['c'];

$today_res = $conn->query("
    SELECT IFNULL(SUM(GREATEST(0, t.today_max - IFNULL(y.prev_max, 0))), 0) AS total
    FROM (
        SELECT vm_id, MAX(CAST(balance AS DECIMAL(10,4))) AS today_max
        FROM earnapp_history WHERE DATE(recorded_at) = CURDATE()
        GROUP BY vm_id
    ) t
    LEFT JOIN (
        SELECT vm_id, MAX(CAST(balance AS DECIMAL(10,4))) AS prev_max
        FROM earnapp_history WHERE DATE(recorded_at) = CURDATE() - INTERVAL 1 DAY
        GROUP BY vm_id
    ) y ON y.vm_id = t.vm_id
");
$stats['earning_today'] = (float)($today_res->fetch_assoc()['total'] ?? 0);

$yesterday_res = $conn->query("
    SELECT IFNULL(SUM(GREATEST(0, y.yest_max - IFNULL(p.prev_max, 0))), 0) AS total
    FROM (
        SELECT vm_id, MAX(CAST(balance AS DECIMAL(10,4))) AS yest_max
        FROM earnapp_history WHERE DATE(recorded_at) = CURDATE() - INTERVAL 1 DAY
        GROUP BY vm_id
    ) y
    LEFT JOIN (
        SELECT vm_id, MAX(CAST(balance AS DECIMAL(10,4))) AS prev_max
        FROM earnapp_history WHERE DATE(recorded_at) = CURDATE() - INTERVAL 2 DAY
        GROUP BY vm_id
    ) p ON p.vm_id = y.vm_id
");
$stats['earning_yesterday'] = (float)($yesterday_res->fetch_assoc()['total'] ?? 0);

$week_res = $conn->query("
    SELECT IFNULL(SUM(daily_earned), 0) AS total
    FROM (
        SELECT t.vm_id, t.dt,
               GREATEST(0, t.day_max - IFNULL(p.prev_day_max, 0)) AS daily_earned
        FROM (
            SELECT vm_id, DATE(recorded_at) AS dt,
                   MAX(CAST(balance AS DECIMAL(10,4))) AS day_max
            FROM earnapp_history
            WHERE DATE(recorded_at) BETWEEN CURDATE() - INTERVAL 6 DAY AND CURDATE()
            GROUP BY vm_id, DATE(recorded_at)
        ) t
        LEFT JOIN (
            SELECT vm_id, DATE(recorded_at) AS dt,
                   MAX(CAST(balance AS DECIMAL(10,4))) AS prev_day_max
            FROM earnapp_history
            GROUP BY vm_id, DATE(recorded_at)
        ) p ON p.vm_id = t.vm_id AND p.dt = DATE_SUB(t.dt, INTERVAL 1 DAY)
    ) x
");
$stats['earning_week'] = (float)($week_res->fetch_assoc()['total'] ?? 0);

$month_start = date('Y-m-01');
$month_res = $conn->query("
    SELECT IFNULL(SUM(daily_earned), 0) AS total
    FROM (
        SELECT t.vm_id, t.dt,
               GREATEST(0, t.day_max - IFNULL(p.prev_day_max, 0)) AS daily_earned
        FROM (
            SELECT vm_id, DATE(recorded_at) AS dt,
                   MAX(CAST(balance AS DECIMAL(10,4))) AS day_max
            FROM earnapp_history
            WHERE DATE(recorded_at) BETWEEN '$month_start' AND CURDATE()
            GROUP BY vm_id, DATE(recorded_at)
        ) t
        LEFT JOIN (
            SELECT vm_id, DATE(recorded_at) AS dt,
                   MAX(CAST(balance AS DECIMAL(10,4))) AS prev_day_max
            FROM earnapp_history
            GROUP BY vm_id, DATE(recorded_at)
        ) p ON p.vm_id = t.vm_id AND p.dt = DATE_SUB(t.dt, INTERVAL 1 DAY)
    ) x
");
$stats['earning_month'] = (float)($month_res->fetch_assoc()['total'] ?? 0);

$tree = [];
$data_res = $conn->query("
    SELECT
        g.id AS g_id, g.name AS g_name,
        r.id AS r_id, r.name AS r_name,
        v.id AS v_id, v.unit_id, v.current_ip, v.last_heartbeat, v.status,
        CASE WHEN v.last_heartbeat IS NOT NULL AND v.last_heartbeat >= NOW() - INTERVAL 5 MINUTE THEN 1 ELSE 0 END AS is_online,
        COALESCE(v.balance, 0) AS balance,
        v.traffic, v.earnapp_token
    FROM groups g
    LEFT JOIN rdps r ON g.id = r.group_id
    LEFT JOIN vms v ON r.id = v.rdp_id
    ORDER BY g.name ASC, r.name ASC, v.unit_id ASC
");

if ($data_res) {
    while ($row = $data_res->fetch_assoc()) {
        $gid = $row['g_id'];
        $rid = $row['r_id'];
        if (!$gid) continue;
        if (!isset($tree[$gid])) {
            $tree[$gid] = ['id' => $gid, 'name' => $row['g_name'], 'rdps' => []];
        }
        if ($rid) {
            if (!isset($tree[$gid]['rdps'][$rid])) {
                $tree[$gid]['rdps'][$rid] = ['id' => $rid, 'name' => $row['r_name'], 'vms' => []];
            }
            if ($row['v_id'] !== null) {
                $tree[$gid]['rdps'][$rid]['vms'][] = $row;
            }
        }
    }
}

$jsGroupData = [];
foreach ($tree as $g) {
    $rdps = [];
    foreach ($g['rdps'] as $r) {
        $rdps[] = ['id' => $r['id'], 'name' => $r['name']];
    }
    $jsGroupData[] = ['id' => $g['id'], 'name' => $g['name'], 'rdps' => $rdps];
}

$total_lifetime_res = $conn->query("SELECT IFNULL(SUM(balance),0) AS total FROM vms");
$total_lifetime = (float)($total_lifetime_res->fetch_assoc()['total'] ?? 0);
?>

<style>
.ea-token-text { word-break: break-all; overflow-wrap: anywhere; white-space: normal; }
.grp-header { display: flex; align-items: center; justify-content: space-between; cursor: pointer; padding: 8px 10px; border-radius: 6px; user-select: none; gap: 10px; }
.grp-header:hover { background: rgba(255,255,255,0.04); }
.grp-left { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; }
.grp-name { font-weight: 600; font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.grp-chevron { font-size: 11px; color: #888; flex-shrink: 0; transition: transform 0.2s ease; }
.grp-chevron.open { transform: rotate(90deg); }
.grp-icons { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.rdp-box { background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.08); border-radius: 8px; margin-bottom: 12px; overflow: hidden; }
.rdp-header { display: flex; align-items: center; justify-content: space-between; padding: 8px 14px; cursor: pointer; background: rgba(255,255,255,0.04); user-select: none; gap: 10px; }
.rdp-header:hover { background: rgba(255,255,255,0.07); }
.rdp-header-left { display: flex; align-items: center; gap: 8px; flex: 1; }
.rdp-title-text { font-size: 13px; font-weight: 600; color: #ccc; }
.rdp-chevron { font-size: 10px; color: #666; transition: transform 0.2s ease; }
.rdp-chevron.open { transform: rotate(90deg); }
.rdp-earning-badge { background: rgba(40,200,100,0.15); border: 1px solid rgba(40,200,100,0.3); color: #4ecb71; font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: 20px; }
.rdp-meta { display: flex; align-items: center; gap: 8px; color: #888; font-size: 11px; flex-shrink: 0; }
.rdp-body { padding: 10px 12px 12px; display: none; }
.rdp-body.open { display: block; }
</style>

<script>
window.groupData = <?php echo json_encode($jsGroupData); ?>;
</script>

<div class="container-fluid px-4 py-3">
<div class="row mb-4 row-cols-8 g-2">
  <div class="col"><div class="card bg-dark text-white p-3 border-danger text-center"><h6>Total VMs</h6><h3><?= $stats['total_vms'] ?></h3></div></div>
  <div class="col"><div class="card bg-dark text-white p-3 border-success text-center"><h6>Online</h6><h3><?= $stats['online_vms'] ?></h3></div></div>
  <div class="col"><div class="card bg-dark text-white p-3 border-success text-center"><h6>App Running</h6><h3><?= $app_running ?></h3></div></div>
  <div class="col"><div class="card bg-dark text-white p-3 border-warning text-center"><h6>App Paused</h6><h3><?= $app_paused ?></h3></div></div>
  <div class="col"><div class="card bg-dark text-white p-3 border-danger text-center"><h6>IP Blocked</h6><h3><?= $app_blocked ?></h3></div></div>
  <div class="col"><div class="card bg-dark text-white p-3 border-warning text-center"><h6>Today</h6><h3>$<?= number_format($stats['earning_today'], 2) ?></h3></div></div>
<div class="col"><div class="card bg-dark text-white p-3 border-secondary text-center"><h6>Yesterday</h6><h3>$<?= number_format($stats['earning_yesterday'], 2) ?></h3></div></div>
<div class="col"><div class="card bg-dark text-white p-3 border-primary text-center"><h6>This Week</h6><h3>$<?= number_format($stats['earning_week'], 2) ?></h3></div></div>
<div class="col"><div class="card bg-dark text-white p-3 border-info text-center"><h6>This Month</h6><h3>$<?= number_format($stats['earning_month'], 2) ?></h3></div></div> 
</div>

<div class="row mb-3">
    <div class="col-md-6">
        <input id="searchInput" class="form-control mb-4 bg-dark text-white border-secondary" placeholder="Search..." onkeyup="app.search()">
    </div>
    <div class="col-md-6 text-end">
        <button class="ea-ibtn1" title="Toggle Telegram Notification" onclick="toggleTelegram()">
            <i id="tgIcon" class="fa fa-bell"></i>
        </button>
        <button class="ea-ibtn1" title="Restart All VMs" onclick="app.restartAllVms()"><i class="fa fa-power-off"></i></button>
        <button class="ea-ibtn1" title="Fetch Balance All" onclick="app.fetchAllBalances()"><i class="fa fa-dollar-sign"></i></button>
        <button class="ea-ibtn1" title="Add Group" onclick="app.openModal('group')"><i class="fa fa-folder"></i></button>
        <button class="ea-ibtn1" title="Add RDP" onclick="app.openModal('rdp')"><i class="fa fa-server"></i></button>
        <button class="ea-ibtn1" title="Add VM" onclick="app.openModal('vm')"><i class="fa fa-desktop"></i></button>
    </div>
</div>

<script>
function toggleTelegram() {
    fetch('/earnapp/toggle_telegram.php', { method: 'POST' })
        .then(r => r.text())
        .then(t => {
            t = t.trim();
            const icon = document.getElementById('tgIcon');

            if (t === 'ON') {
                icon.className = 'fa fa-bell';
                alert('Telegram Notification ON');
            } else if (t === 'OFF') {
                icon.className = 'fa fa-bell-slash';
                alert('Telegram Notification OFF');
            } else {
                alert('Telegram Notification Error');
            }
        })
        .catch(() => alert('Server Error'));
}
</script>

<div class="row">
    <div class="col-md-3 nav-col">
        <div class="card bg-dark text-white border-secondary nav-full">
            <div class="card-header nav-header">
                <span>Navigator</span>
                <i class="fa fa-chevron-left nav-toggle-icon" onclick="toggleNavigator()"></i>
            </div>
            <div class="list-group list-group-flush small nav-tree">
                <?php foreach ($tree as $g): ?>
                <div class="nav-group">
                    <div class="nav-group-title" onclick="toggleGroup(this)"><?= htmlspecialchars($g['name']) ?></div>
                    <div class="nav-group-body">
                        <?php foreach ($g['rdps'] as $r): ?>
                        <div class="nav-rdp">
                            <div class="nav-rdp-title" onclick="toggleRdp(this)">RDP: <?= htmlspecialchars($r['name']) ?></div>
                            <div class="nav-rdp-body">
                                <?php foreach ($r['vms'] as $v): ?>
                                <a href="#vm-card-<?= $v['v_id'] ?>" class="nav-vm"><?= htmlspecialchars($v['unit_id']) ?></a>
                                <?php endforeach; ?>
                            </div>
                        </div>
                        <?php endforeach; ?>
                    </div>
                </div>
                <?php endforeach; ?>
            </div>
        </div>
    </div>

    <div class="col-md-9 main-col">
        <div id="mainContent">

<?php foreach ($tree as $g):
    $rdpCount = count($g['rdps']);
    $vmCount  = 0;
    foreach ($g['rdps'] as $r) $vmCount += count($r['vms']);
?>

<div class="group-box mb-4 p-3 border border-secondary rounded bg-dark shadow searchable-item"
     data-name="<?= htmlspecialchars($g['name']) ?>" id="g-<?= $g['id'] ?>">

    <div class="grp-header" onclick="grpToggle(<?= $g['id'] ?>)">
        <div class="grp-left">
            <i class="fa fa-chevron-right grp-chevron" id="gc-<?= $g['id'] ?>"></i>
            <span class="grp-name"><?= htmlspecialchars($g['name']) ?></span>
        </div>
        <div class="grp-icons">
            <span class="dot green">1</span>
            <span class="dot red"><?= $rdpCount ?></span>
            <span class="dot yellow"><?= $vmCount ?></span>
            <button class="grp-ibtn" onclick="event.stopPropagation(); app.openRdpFromGroup(<?= $g['id'] ?>)"><i class="fa fa-server"></i></button>
            <button class="grp-ibtn" onclick="event.stopPropagation(); app.openVmFromGroup(<?= $g['id'] ?>)"><i class="fa fa-desktop"></i></button>
            <button class="grp-ibtn danger" onclick="event.stopPropagation(); app.deleteGroup(<?= $g['id'] ?>)"><i class="fa fa-trash"></i></button>
        </div>
    </div>

    <div id="gb-<?= $g['id'] ?>" style="display:none; margin-top:10px;">

        <?php foreach ($g['rdps'] as $r):
            $rdpId      = (int)$r['id'];
             
            $rdpVmTotal = count($r['vms']);
            $rdpOnline  = 0;
            foreach ($r['vms'] as $v) { if ((int)$v['is_online'] === 1) $rdpOnline++; }
        ?>

        <div class="rdp-box searchable-item" data-name="<?= htmlspecialchars($r['name']) ?>">

            <div class="rdp-header" onclick="rdpToggle(<?= $rdpId ?>)">
                <div class="rdp-header-left">
                    <i class="fa fa-chevron-right rdp-chevron" id="rc-<?= $rdpId ?>"></i>
                    <span class="rdp-title-text"><?= htmlspecialchars($r['name']) ?></span> 
                </div>
                <div class="rdp-meta">
                    <span style="color:#4ecb71;"><?= $rdpOnline ?> online</span>
                    <span>/</span>
                    <span><?= $rdpVmTotal ?> VMs</span>
                    <button class="grp-ibtn" onclick="event.stopPropagation(); app.openVmFromRdp(<?= $g['id'] ?>, <?= $rdpId ?>)"><i class="fa fa-plus"></i></button>
                </div>
            </div>

            <div class="rdp-body" id="rb-<?= $rdpId ?>">
                <div class="row">

<?php foreach ($r['vms'] as $v):
    $statusRaw   = strtolower(trim($v['status'] ?? 'unknown'));
    $isOnline    = ((int)$v['is_online'] === 1);
    $statusText  = $isOnline ? 'ONLINE' : 'OFFLINE';
    $statusClass = $isOnline ? 'on' : 'off';

    $statusColor = 'ok';
    if ($statusRaw === 'blocked' || $statusRaw === 'offline') $statusColor = 'bad';
    elseif ($statusRaw === 'paused') $statusColor = 'warn';

   $has_cashout = false;

    if ((float)$v['balance'] < 0.01) {
        $cashout_q = $conn->query(
            "SELECT 1 FROM earnapp_history 
             WHERE earnapp_token = '" . $conn->real_escape_string((string)($v['earnapp_token'] ?? '')) . "' 
             AND cashout_detected = 1 
             AND DATE(recorded_at) = CURDATE() 
             LIMIT 1"
        );
        $has_cashout = ($cashout_q && $cashout_q->num_rows > 0);
    }

    $balanceTxt  = '$' . number_format((float)$v['balance'], 2);
    $earnappLink = !empty($v['earnapp_token'])
        ? 'https://earnapp.com/dashboard/link/sdk-win-' . $v['earnapp_token']
        : null;
    $lastSeenTxt = !empty($v['last_heartbeat'])
        ? date('j/n/Y, g:i:s A', strtotime($v['last_heartbeat']))
        : 'Never';
    $hbDisplay = !empty($v['last_heartbeat'])
        ? date('H:i:s', strtotime($v['last_heartbeat']))
        : 'No heartbeat';
?>

<div class="col-12 searchable-item" data-name="<?= htmlspecialchars($v['unit_id']) ?>" id="vm-card-<?= $v['v_id'] ?>">
    <div class="ea-card">
        <div class="ea-left">
            <div class="ea-status <?= $statusClass ?>">
                <?= $statusText ?>
                <?php if (!$isOnline): ?><small>VM OFFLINE</small><?php endif; ?>
            </div>
            <div class="ea-left-meta">
                <div class="ea-vm"><?= htmlspecialchars($v['unit_id']) ?></div>
                <div class="ea-ip"><?= $v['current_ip'] ?: 'No IP' ?></div>
                <div class="ea-hb" style="margin-top:4px;font-size:12px;color:#aaa"><?= $hbDisplay ?></div>
            </div>
        </div>

        <div class="ea-center">
            <div class="ea-token-box" style="display:none; margin-top: 5px;">
                <?php if ($earnappLink): ?>
                    <div class="d-flex align-items-center bg-dark border border-secondary rounded p-1">
                        <span class="small text-white text-decoration-none text-truncate me-2" style="flex: 1; word-break: break-all; white-space: normal; line-height: 1.2;">
                            <?= htmlspecialchars($earnappLink) ?>
                        </span>
                        <button class="btn btn-sm btn-outline-secondary py-0 px-2" style="font-size: 12px;" onclick="app.copyText('<?= htmlspecialchars($earnappLink) ?>')" title="Copy Link">
                            <i class="fa fa-copy"></i>
                        </button>
                    </div>
                <?php else: ?>
                    <small class="text-muted">No token yet</small>
                <?php endif; ?>
            </div>
            <div class="ea-flags">
                <span>Status:
                    <?php if (!$isOnline): ?>
                        <b style="color:#dc3545;">OFFLINE</b>
                    <?php else: ?>
                        <b class="<?= $statusColor ?>"><?= strtoupper($statusRaw) ?></b>
                    <?php endif; ?>
                </span>
                
                <?php if ($has_cashout): ?>
                    <span class="ms-2 badge bg-success text-white border border-light" style="font-size: 10px; padding: 2px 5px;">
                        <i class="fa fa-money-bill-wave me-1"></i> CASHOUT
                    </span>
                <?php endif; ?>
            </div>
            <div class="ea-sync">Sync: <?= $lastSeenTxt ?></div>
            <div class="ea-balance">Balance: <b><?= $balanceTxt ?></b></div>
        </div>

        <div class="ea-right ea-icon-strip">
            <button class="ea-btn" title="Token" onclick="toggleToken(this)"><i class="fa fa-key"></i></button>
            <button class="ea-btn" title="Restart" onclick="app.restartVm(<?= $v['v_id'] ?>)"><i class="fa fa-power-off"></i></button>
            <button id="fetch-btn-<?= $v['v_id'] ?>" class="ea-btn" title="Fetch Balance" onclick="app.fetchBalance(<?= $v['v_id'] ?>)"><i class="fa fa-dollar-sign"></i></button>
            <button class="ea-btn" title="Terminal" onclick="app.openTerminal(<?= htmlspecialchars(json_encode($v)) ?>,'<?= addslashes($r['name']) ?>','<?= addslashes($g['name']) ?>')"><i class="fa fa-terminal"></i></button>
            <button class="ea-btn danger" onclick="app.deleteVm(<?= $v['v_id'] ?>)"><i class="fa fa-trash"></i></button>
        </div>
    </div>
</div>

<?php endforeach; ?>
                </div>
            </div>

        </div>
        <?php endforeach; ?>

    </div>
</div>

<?php endforeach; ?>

        </div>
    </div>
</div>
</div>

<div id="overlay" onclick="app.closeModal()"></div>
<?php include __DIR__.'/../modals/group.php'; ?>
<?php include __DIR__.'/../modals/rdp.php'; ?>
<?php include __DIR__.'/../modals/vm.php'; ?>

<div id="terminalModal" class="modal">
  <div class="modal-content bg-dark text-white border-danger" style="max-width:800px; width:95%">
    <div class="modal-header border-secondary">
      <h5 class="modal-title"><i class="fa fa-terminal me-2"></i> <span id="termTitle">Terminal</span></h5>
      <button class="btn-close btn-close-white" onclick="app.closeModal()"></button>
    </div>
    <div class="modal-body">
      <div class="mb-3 small p-2 bg-black border border-secondary rounded d-flex justify-content-around">
          <span>VM ID: <b id="termVmId"></b></span>
          <span>Group: <b id="termGroup"></b></span>
          <span>RDP: <b id="termRdp"></b></span>
      </div>
      <div class="mb-3">
        <label class="small text-muted">Install Command (PowerShell)</label>
        <div class="input-group">
          <input id="installCmd" class="form-control bg-black text-success small" readonly>
          <button class="btn btn-danger btn-sm" onclick="app.copy('installCmd')">Copy</button>
        </div>
      </div>
      <div class="mb-3">
        <label class="small text-muted">Uninstall Command</label>
        <div class="input-group">
          <input id="uninstallCmdInput" class="form-control bg-black text-white" readonly>
          <button class="btn btn-danger btn-sm" onclick="app.copy('uninstallCmdInput')">Copy</button>
        </div>
      </div>
    </div>
  </div>
</div>

<script>
window.app = {
    async api(action, data = {}) {
        try {
            const r = await fetch('pages/api.php?action=' + action, {
                method: 'POST',
                headers: {'Content-Type': 'application/json'},
                body: JSON.stringify(data)
            });
            const text = await r.text();
            try { return JSON.parse(text); }
            catch (e) { return {success: false, error: 'Invalid JSON'}; }
        } catch (e) {
            return {success: false, error: 'Network error'};
        }
    },

    copyText(text) {
        navigator.clipboard.writeText(text).catch(() => {
            const ta = document.createElement('textarea');
            ta.value = text;
            ta.style.cssText = 'position:fixed;opacity:0';
            document.body.appendChild(ta);
            ta.select();
            document.execCommand('copy');
            document.body.removeChild(ta);
        });
    },

    search() {
        const term = document.getElementById('searchInput').value.toLowerCase().trim();
        document.querySelectorAll('.group-box').forEach(group => {
            let groupMatch = false;
            group.querySelectorAll('.searchable-item[id^="vm-card"]').forEach(vm => {
                const name = (vm.getAttribute('data-name') || '').toLowerCase();
                const show = !term || name.includes(term);
                vm.style.display = show ? '' : 'none';
                if (show) {
                    groupMatch = true;
                    if (term) {
                        const rb = vm.closest('[id^="rb-"]');
                        if (rb) { rb.classList.add('open'); const rc = document.getElementById('rc-' + rb.id.replace('rb-','')); if(rc) rc.classList.add('open'); }
                        const gb = vm.closest('[id^="gb-"]');
                        if (gb) { gb.style.display = 'block'; const gc = document.getElementById('gc-' + gb.id.replace('gb-','')); if(gc) gc.classList.add('open'); }
                    }
                }
            });
            group.style.display = groupMatch || !term ? '' : 'none';
        });
    },

    openModal(type) {
        document.getElementById('overlay').style.display = 'block';
        const modal = document.getElementById(type === 'terminal' ? 'terminalModal' : 'modal-' + type);
        if (modal) modal.style.display = 'flex';
    },

    closeModal() {
        document.getElementById('overlay').style.display = 'none';
        document.querySelectorAll('.modal').forEach(m => m.style.display = 'none');
        ['vmInput','rdpInput','groupInput'].forEach(id => { const el = document.getElementById(id); if (el) el.value = ''; });
    },

    openTerminal(v, rName, gName) {
        const base = window.location.origin + window.location.pathname.split('/index.php')[0];
        document.getElementById('termTitle').innerText = v.unit_id;
        document.getElementById('termVmId').innerText = v.v_id;
        document.getElementById('termGroup').innerText = gName;
        document.getElementById('termRdp').innerText = rName;
        document.getElementById('installCmd').value = 'irm "' + base + '/static/install.ps1" -OutFile i.ps1; .\\i.ps1 -VMId ' + v.v_id + ' -UnitId "' + v.unit_id + '" -Group "' + gName + '" -RdpNickname "' + rName + '" -BackendUrl "' + base + '"';
        const uninst = document.getElementById('uninstallCmdInput');
        if (uninst) uninst.value = 'irm "' + base + '/static/uninstall.ps1" | iex';
        this.openModal('terminal');
    },

    copy(id) { const el = document.getElementById(id); el.select(); navigator.clipboard.writeText(el.value); },

    filterRdpList(groupId, preselectRdpId) {
        const rdpSelect = document.getElementById('vmRdpSelect');
        rdpSelect.innerHTML = '<option value="">-- Select RDP --</option>';
        if (!groupId) return;
        const group = window.groupData.find(g => g.id == groupId);
        if (!group || !group.rdps || !group.rdps.length) return;
        group.rdps.forEach((rdp, index) => {
            const opt = document.createElement('option');
            opt.value = rdp.id;
            opt.textContent = rdp.name;
            rdpSelect.appendChild(opt);
            if (preselectRdpId && rdp.id == preselectRdpId) rdpSelect.value = rdp.id;
            else if (!preselectRdpId && index === 0) rdpSelect.value = rdp.id;
        });
    },

    async addVM() {
        const rdpId  = document.getElementById('vmRdpSelect').value;
        const unitId = document.getElementById('vmInput').value.trim();
        if (!rdpId || !unitId) { alert('Please fill all fields'); return; }
        const btn = document.querySelector('#modal-vm .btn-danger');
        if (btn) { if (btn.dataset.submitting === 'true') return; btn.dataset.submitting = 'true'; btn.disabled = true; }
        const res = await this.api('add_vm', { rdp_id: rdpId, unit_id: unitId });
        if (btn) { btn.dataset.submitting = 'false'; btn.disabled = false; }
        if (res && res.success) location.reload();
        else alert('Failed: ' + (res?.error || 'Unknown error'));
    },

    async restartAllVms() {
        if (!confirm('Restart all VMs?')) return;
        const res = await this.api('send_global_command', { command: 'restart_vm' });
        alert(res && res.success ? 'Restart command sent to all VMs' : 'Failed');
    },

    async fetchAllBalances() {
        if (!confirm('Fetch balance for all VMs?')) return;
        const res = await this.api('send_global_command', { command: 'fetch_balance' });
        alert(res && res.success ? 'Balance fetch sent to all VMs' : 'Failed');
    },

    async restartVm(vmId) {
        if (!confirm('Restart this VM?')) return;
        const res = await this.api('send_command', { vm_id: parseInt(vmId), command: 'restart_vm' });
        alert(res && res.success ? 'Command sent' : 'Failed');
    },

    async fetchBalance(vmId) {
        const btn = document.getElementById('fetch-btn-' + vmId);
        if (btn) btn.disabled = true;
        const res = await this.api('send_command', { vm_id: parseInt(vmId), command: 'fetch_balance' });
        alert(res && res.success ? 'Request sent' : 'Failed');
        setTimeout(() => { if (btn) btn.disabled = false; }, 3000);
    },

    async deleteGroup(groupId) {
        if (!confirm('Delete this group permanently?')) return;
        const res = await this.api('delete_groups', { ids: [parseInt(groupId)] });
        if (res && res.success) location.reload();
        else alert('Delete failed');
    },

    async deleteVm(vmId) {
        if (!confirm('Delete this VM permanently?')) return;
        const res = await this.api('delete_vms', { ids: [parseInt(vmId)] });
        if (res && res.success) location.reload();
        else alert('Delete failed');
    },

    openRdpFromGroup(groupId) {
        document.getElementById('overlay').style.display = 'block';
        const modal = document.getElementById('modal-rdp');
        if (modal) { modal.style.display = 'flex'; const sel = document.getElementById('rdpGroupSelect'); if (sel) sel.value = groupId; }
    },

    openVmFromGroup(groupId) {
        const vmInput = document.getElementById('vmInput');
        if (vmInput) vmInput.value = '';
        const grpSel = document.getElementById('vmGroupSelect');
        if (grpSel) grpSel.value = String(groupId);
        this.filterRdpList(groupId);
        document.getElementById('overlay').style.display = 'block';
        const modal = document.getElementById('modal-vm');
        if (modal) modal.style.display = 'flex';
    },

    openVmFromRdp(groupId, rdpId) {
        const vmInput = document.getElementById('vmInput');
        if (vmInput) vmInput.value = '';
        const grpSel = document.getElementById('vmGroupSelect');
        if (grpSel) grpSel.value = String(groupId);
        this.filterRdpList(groupId, rdpId);
        document.getElementById('overlay').style.display = 'block';
        const modal = document.getElementById('modal-vm');
        if (modal) modal.style.display = 'flex';
    },

    async addRDP() {
        const name    = document.getElementById('rdpInput').value;
        const groupId = document.getElementById('rdpGroupSelect').value;
        if (!name || !groupId) { alert('Fill all fields'); return; }
        const res = await this.api('add_rdp', { name, group_id: parseInt(groupId) });
        if (res && res.success) location.reload();
        else alert('Failed to add RDP');
    },

    async addGroup() {
        const name = document.getElementById('groupInput').value;
        if (!name) return alert('Enter group name');
        const res = await this.api('add_group', { name });
        if (res && res.success) location.reload();
        else alert('Failed to add group');
    }
};

window.grpToggle = function(id) {
    const body = document.getElementById('gb-' + id);
    const icon = document.getElementById('gc-' + id);
    if (!body) return;
    const open = body.style.display === 'block';
    body.style.display = open ? 'none' : 'block';
    if (icon) icon.classList.toggle('open', !open);
};

window.rdpToggle = function(id) {
    const body = document.getElementById('rb-' + id);
    const icon = document.getElementById('rc-' + id);
    if (!body) return;
    const isOpen = body.classList.contains('open');
    body.classList.toggle('open', !isOpen);
    if (icon) icon.classList.toggle('open', !isOpen);
};

window.toggleGroup = function(el) {
    const body = el.nextElementSibling;
    if (body) body.style.display = (body.style.display === 'block') ? 'none' : 'block';
};

window.toggleRdp = function(el) {
    const body = el.nextElementSibling;
    if (body) body.style.display = (body.style.display === 'block') ? 'none' : 'block';
};

window.toggleToken = function(btn) {
    const box = btn.closest('.ea-card').querySelector('.ea-token-box');
    if (box) box.style.display = (box.style.display === 'none') ? 'block' : 'none';
};

window.toggleNavigator = function() {
    document.querySelector('.nav-col').classList.toggle('nav-collapsed');
};
</script>