<?php
ini_set('display_errors', 0);
error_reporting(E_ALL);
header('Content-Type: application/json');

session_start();
require_once __DIR__ . '/../db.php';

$jsonInput = file_get_contents('php://input');
$input     = json_decode($jsonInput, true) ?? [];
$action    = $_GET['action'] ?? ($input['action'] ?? ($_POST['action'] ?? ''));

if (empty($action)) {
    echo json_encode(['success' => false, 'error' => 'No action provided']);
    exit;
}

$agentActions = ['fetch_command', 'ack_command', 'command_result'];

if (!in_array($action, $agentActions)) {
    if (!isset($_SESSION['user_id'])) {
        echo json_encode(['success' => false, 'error' => 'Unauthorized']);
        exit;
    }
}

$uid   = 0;
$admin = false;
$groupIdList = '0'; 

if (isset($_SESSION['user_id'])) {
    $uid         = currentUserId();
    $admin       = isAdmin();
    $groupIds    = getUserGroupIds($conn, $uid, $admin);
    $groupIdList = implode(',', $groupIds);
    if (empty($groupIdList)) $groupIdList = '0';
}

date_default_timezone_set('Asia/Kolkata');

switch ($action) {

    case 'fetch_command':
        $vmId = (int)($_GET['vm_id'] ?? 0);
        if ($vmId <= 0) { echo json_encode(null); exit; }
        
        $r   = $conn->query("SELECT id, command FROM vm_commands WHERE vm_id=$vmId AND status='pending' ORDER BY id ASC LIMIT 1");
        $row = $r ? $r->fetch_assoc() : null;
        
        if (!$row) { echo json_encode(null); exit; }
        
        $conn->query("UPDATE vm_commands SET status='sent' WHERE id=" . (int)$row['id']);
        echo json_encode(['id' => (int)$row['id'], 'action' => $row['command']]);
        exit;

    case 'ack_command':
        $id    = (int)($_GET['id']    ?? 0);
        $vmId  = (int)($_GET['vm_id'] ?? 0);
        $stmt  = $conn->prepare("UPDATE vm_commands SET status='done', completed_at=UTC_TIMESTAMP() WHERE id=? AND vm_id=?");
        $stmt->bind_param("ii", $id, $vmId);
        $stmt->execute();
        echo json_encode(['ok' => true]);
        exit;

    case 'command_result':
        $stmt    = $conn->prepare("UPDATE vm_commands SET status='done', result=CONCAT('[', ?, '] ', ?), completed_at=UTC_TIMESTAMP() WHERE id=?");
        $success = !empty($input['success']) ? 'OK' : 'FAIL';
        $msg     = isset($input['message']) ? $input['message'] : '';
        $cmdId   = isset($input['command_id']) ? $input['command_id'] : 0;
        $stmt->bind_param("ssi", $success, $msg, $cmdId);
        $stmt->execute();
        echo json_encode(['ok' => true]);
        exit;

    case 'send_command':
        $vmId = (int)($input['vm_id'] ?? 0);
        $cmd  = strtolower(trim($input['command'] ?? ''));
        if ($vmId <= 0 || $cmd === '') { echo json_encode(['success' => false]); exit; }
        $stmt = $conn->prepare("INSERT INTO vm_commands (vm_id, command, status, created_at) VALUES (?, ?, 'pending', UTC_TIMESTAMP())");
        $stmt->bind_param("is", $vmId, $cmd);
        echo json_encode(['success' => (bool)$stmt->execute()]);
        exit;

    case 'delete_command':
    case 'delete_commands':
    case 'delete_vm_commands':
        $rawIds = [];
        $sources = [$input, $_GET, $_POST];

        foreach ($sources as $source) {
            if (!is_array($source)) continue;
            
            if (isset($source[0]) && is_numeric($source[0])) {
                foreach ($source as $v) {
                    if (is_numeric($v)) $rawIds[] = $v;
                }
            }
            
            $keys = ['ids', 'id', 'command_id'];
            foreach ($keys as $k) {
                if (isset($source[$k])) {
                    $val = $source[$k];
                    if (is_array($val)) {
                        foreach ($val as $v) {
                            if (is_numeric($v)) $rawIds[] = $v;
                        }
                    } elseif (is_string($val) && strpos($val, ',') !== false) {
                        foreach (explode(',', $val) as $v) {
                            if (is_numeric($v)) $rawIds[] = $v;
                        }
                    } elseif (is_numeric($val)) {
                        $rawIds[] = $val;
                    }
                }
            }
        }

        $ids = array_unique(array_filter(array_map('intval', $rawIds), function($x){ return $x > 0; }));

        if (empty($ids)) { 
            echo json_encode(['success' => false, 'error' => 'No valid ID provided']); 
            exit; 
        }

        $idList = implode(',', $ids);

        if (!$admin) {
            $sql = "DELETE vc FROM vm_commands vc INNER JOIN vms v ON v.id = vc.vm_id INNER JOIN rdps r ON r.id = v.rdp_id WHERE vc.id IN ($idList) AND r.group_id IN ($groupIdList)";
        } else {
            $sql = "DELETE FROM vm_commands WHERE id IN ($idList)";
        }

        if ($conn->query($sql)) {
            echo json_encode(['success' => true]);
        } else {
            echo json_encode(['success' => false, 'error' => 'DB Error: ' . $conn->error]);
        }
        exit;

    case 'send_global_command':
        $cmd = strtolower(trim($input['command'] ?? 'fetch_balance'));
        $safeCmd = in_array($cmd, ['fetch_balance', 'restart_vm', 'stop_agent', 'fetch_balance_global']) ? $cmd : 'fetch_balance';
        $stmt = $conn->prepare("
            INSERT INTO vm_commands (vm_id, command, status, created_at)
            SELECT v.id, ?, 'pending', UTC_TIMESTAMP()
            FROM vms v
            JOIN rdps r ON r.id = v.rdp_id
            WHERE r.group_id IN ($groupIdList) AND v.unit_id IS NOT NULL
        ");
        $stmt->bind_param("s", $safeCmd);
        $stmt->execute();
        echo json_encode(['success' => $stmt->affected_rows > 0]);
        exit;

    case 'load_all':
        $groups = [];
        $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.balance, v.traffic, v.status
            FROM `groups` g
            LEFT JOIN rdps r ON g.id = r.group_id
            LEFT JOIN vms v ON r.id = v.rdp_id
            WHERE g.id IN ($groupIdList)
            ORDER BY g.name, r.name, v.unit_id
        ");
        while ($row = $res->fetch_assoc()) {
            $gId = $row['g_id'];
            if (!isset($groups[$gId])) $groups[$gId] = ['id' => $gId, 'name' => $row['g_name'], 'rdps' => []];
            if ($row['r_id']) {
                if (!isset($groups[$gId]['rdps'][$row['r_id']])) $groups[$gId]['rdps'][$row['r_id']] = ['id' => $row['r_id'], 'name' => $row['r_name'], 'vms' => []];
                if ($row['v_id']) $groups[$gId]['rdps'][$row['r_id']]['vms'][] = $row;
            }
        }
        $final = [];
        foreach ($groups as $g) { $g['rdps'] = array_values($g['rdps']); $final[] = $g; }
        echo json_encode(['success' => true, 'data' => ['data' => $final, 'server_time' => date('Y-m-d H:i:s')]]);
        exit;

    case 'add_group':
        $name = trim(isset($input['name']) ? $input['name'] : '');
        if (strlen($name) < 2) { echo json_encode(array('success' => false, 'error' => 'Name too short')); exit; }
        $tenantVal = 'NULL';
        if (!isSuperAdmin()) {
            $tRes = $conn->query("SELECT tenant_id FROM users WHERE id=" . (int)$uid . " LIMIT 1");
            $tRow = $tRes ? $tRes->fetch_assoc() : null;
            if ($tRow && $tRow['tenant_id'] !== null) {
                $tenantVal = (int)$tRow['tenant_id'];
            } else {
                $tenantVal = (int)$uid;
            }
        }
        $ok = $conn->query("INSERT INTO `groups` (name, tenant_id) VALUES ('" . $conn->real_escape_string($name) . "', " . $tenantVal . ")");
        $gid = $conn->insert_id;
        if ($ok && !isSuperAdmin() && $gid) {
            $conn->query("INSERT IGNORE INTO user_groups (user_id, group_id) VALUES (" . (int)$uid . ", $gid)");
        }
        echo json_encode(array('success' => (bool)$ok, 'group_id' => $gid));
        exit;

    case 'add_rdp':
        $name    = trim(isset($input['name']) ? $input['name'] : '');
        $groupId = (int)(isset($input['group_id']) ? $input['group_id'] : 0);
        if (!$name || !$groupId) { echo json_encode(array('success' => false, 'error' => 'Missing fields')); exit; }
        if (!$admin) {
            $chk = $conn->query("SELECT id FROM user_groups WHERE group_id=" . $groupId . " AND user_id=" . (int)$uid . " LIMIT 1");
            if (!$chk || $chk->num_rows === 0) { echo json_encode(array('success' => false, 'error' => 'Access denied')); exit; }
        } elseif (!isSuperAdmin()) {
            $tRes = $conn->query("SELECT tenant_id FROM users WHERE id=" . (int)$uid . " LIMIT 1");
            $tRow = $tRes ? $tRes->fetch_assoc() : null;
            $myTenant = ($tRow && $tRow['tenant_id'] !== null) ? (int)$tRow['tenant_id'] : (int)$uid;
            $gChk = $conn->query("SELECT id FROM `groups` WHERE id=" . $groupId . " AND tenant_id=" . $myTenant . " LIMIT 1");
            if (!$gChk || $gChk->num_rows === 0) { echo json_encode(array('success' => false, 'error' => 'Access denied')); exit; }
        }
        $ok = $conn->query("INSERT INTO rdps (name, group_id) VALUES ('" . $conn->real_escape_string($name) . "'," . $groupId . ")");
        echo json_encode(array('success' => (bool)$ok));
        exit;

    case 'add_vm':
        $rdpId  = (int)(isset($input['rdp_id'])  ? $input['rdp_id']  : 0);
        $vmName = trim(isset($input['unit_id']) ? $input['unit_id'] : '');
        if ($rdpId <= 0 || $vmName === '') { echo json_encode(array('success' => false, 'error' => 'Input missing')); exit; }

        if ($admin) {
            $r_res = $conn->query("SELECT r.name, r.group_id, g.name as group_name FROM rdps r JOIN `groups` g ON g.id=r.group_id WHERE r.id=$rdpId");
        } else {
            $r_res = $conn->query("SELECT r.name, r.group_id, g.name as group_name FROM rdps r JOIN `groups` g ON g.id=r.group_id JOIN user_groups ug ON ug.group_id=g.id WHERE r.id=$rdpId AND ug.user_id=" . (int)$uid);
        }
        if (!$r_res || $r_res->num_rows === 0) { echo json_encode(array('success' => false, 'error' => 'RDP not found or access denied')); exit; }
        $r         = $r_res->fetch_assoc();
        $groupId   = (int)$r['group_id'];
        $groupName = $r['group_name'];
        $rdpName   = $r['name'];

        $existing = $conn->query("SELECT id FROM vms WHERE unit_id='" . $conn->real_escape_string($vmName) . "' AND rdp_id=$rdpId LIMIT 1");
        if ($existing && $existing->num_rows > 0) { echo json_encode(array('success' => false, 'error' => 'VM already exists in this RDP')); exit; }

        $safeName  = $conn->real_escape_string($vmName);
        $safeGName = $conn->real_escape_string($groupName);
        $safeRName = $conn->real_escape_string($rdpName);
        $ok = $conn->query("INSERT INTO vms (unit_id, rdp_id, group_id, group_name, rdp_nickname, status, last_heartbeat) VALUES ('$safeName', $rdpId, $groupId, '$safeGName', '$safeRName', 'Offline', NULL)");
        $newId = $conn->insert_id;
        echo json_encode(array('success' => (bool)$ok, 'vm_id' => $ok ? $newId : null, 'error' => $ok ? null : $conn->error));
        exit;

    case 'delete_vms':
        $ids    = array_map('intval', $input['ids'] ?? []);
        if (empty($ids)) { echo json_encode(['success' => false]); exit; }
        $idList = implode(',', $ids);
        $conn->query("DELETE FROM vm_commands WHERE vm_id IN ($idList)");
        $conn->query("DELETE FROM earnapp_history WHERE vm_id IN ($idList)");
        $conn->query("DELETE FROM vms WHERE id IN ($idList)");
        echo json_encode(['success' => true]);
        exit;

    case 'delete_rdps':
        $ids    = array_map('intval', $input['ids'] ?? []);
        if (empty($ids)) { echo json_encode(['success' => false]); exit; }
        $idList = implode(',', $ids);
        $vids   = [];
        $res    = $conn->query("SELECT id FROM vms WHERE rdp_id IN ($idList)");
        while ($row = $res->fetch_assoc()) $vids[] = $row['id'];
        if ($vids) {
            $vidList = implode(',', $vids);
            $conn->query("DELETE FROM vm_commands WHERE vm_id IN ($vidList)");
            $conn->query("DELETE FROM earnapp_history WHERE vm_id IN ($vidList)");
            $conn->query("DELETE FROM vms WHERE id IN ($vidList)");
        }
        $conn->query("DELETE FROM rdps WHERE id IN ($idList)");
        echo json_encode(['success' => true]);
        exit;

    case 'delete_groups':
        $ids = array_map('intval', isset($input['ids']) ? $input['ids'] : array());
        if (empty($ids)) { echo json_encode(array('success' => false)); exit; }
        if (!$admin) {
            $safeIds = array();
            foreach ($ids as $gid) {
                $chk = $conn->query("SELECT id FROM user_groups WHERE group_id=" . $gid . " AND user_id=" . (int)$uid . " LIMIT 1");
                if ($chk && $chk->num_rows > 0) $safeIds[] = $gid;
            }
            $ids = $safeIds;
        } elseif (!isSuperAdmin()) {
            $tRes = $conn->query("SELECT tenant_id FROM users WHERE id=" . (int)$uid . " LIMIT 1");
            $tRow = $tRes ? $tRes->fetch_assoc() : null;
            $myTenant = ($tRow && $tRow['tenant_id'] !== null) ? (int)$tRow['tenant_id'] : (int)$uid;
            $safeIds = array();
            foreach ($ids as $gid) {
                $chk = $conn->query("SELECT id FROM `groups` WHERE id=" . $gid . " AND tenant_id=" . $myTenant . " LIMIT 1");
                if ($chk && $chk->num_rows > 0) $safeIds[] = $gid;
            }
            $ids = $safeIds;
        }
        if (empty($ids)) { echo json_encode(array('success' => false, 'error' => 'Nothing to delete')); exit; }
        $idList = implode(',', $ids);
        $vids   = array();
        $res    = $conn->query("SELECT v.id FROM vms v JOIN rdps r ON r.id=v.rdp_id WHERE r.group_id IN ($idList)");
        if ($res) { while ($row = $res->fetch_assoc()) $vids[] = $row['id']; }
        if ($vids) {
            $vidList = implode(',', $vids);
            $conn->query("DELETE FROM vm_commands WHERE vm_id IN ($vidList)");
            $conn->query("DELETE FROM earnapp_history WHERE vm_id IN ($vidList)");
            $conn->query("DELETE FROM vms WHERE id IN ($vidList)");
        }
        $conn->query("DELETE FROM rdps WHERE group_id IN ($idList)");
        $conn->query("DELETE FROM `groups` WHERE id IN ($idList)");
        echo json_encode(array('success' => true));
        exit;

    case 'user_list':
        if (!$admin) { echo json_encode(['success' => false, 'error' => 'Admin only']); exit; }
        $res   = $conn->query("SELECT id, username, role, email, is_active, last_login, created_at FROM users ORDER BY created_at DESC");
        $users = [];
        while ($row = $res->fetch_assoc()) $users[] = $row;
        echo json_encode(['success' => true, 'users' => $users]);
        exit;

    case 'user_add':
        if (!isSuperAdmin()) { echo json_encode(['success' => false, 'error' => 'Super Admin only']); exit; }
        $uname = trim($input['username'] ?? '');
        $upass = trim($input['password'] ?? '');
        $urole = in_array($input['role'] ?? '', ['admin','user','super_admin']) ? $input['role'] : 'user';
        $uemail = trim($input['email'] ?? '');
        if (strlen($uname) < 3 || strlen($upass) < 6) { echo json_encode(['success' => false, 'error' => 'Username >= 3 chars, password >= 6 chars']); exit; }
        $chk = $conn->prepare("SELECT id FROM users WHERE username=? LIMIT 1");
        $chk->bind_param("s", $uname);
        $chk->execute();
        $chk->store_result();
        if ($chk->num_rows > 0) { echo json_encode(['success' => false, 'error' => 'Username already taken']); exit; }
        $chk->close();
        $hash = password_hash($upass, PASSWORD_DEFAULT);
        $stmt = $conn->prepare("INSERT INTO users (username, role, email, password, is_active) VALUES (?, ?, ?, ?, 1)");
        $stmt->bind_param("ssss", $uname, $urole, $uemail, $hash);
        $ok   = $stmt->execute();
        echo json_encode(['success' => $ok, 'user_id' => $ok ? $conn->insert_id : null, 'error' => $ok ? null : $stmt->error]);
        exit;

    case 'user_toggle':
        if (!isSuperAdmin()) { echo json_encode(['success' => false, 'error' => 'Super Admin only']); exit; }
        $tuid = (int)($input['user_id'] ?? 0);
        if ($tuid === $uid) { echo json_encode(['success' => false, 'error' => 'Cannot deactivate yourself']); exit; }
        $conn->query("UPDATE users SET is_active = 1 - is_active WHERE id=$tuid");
        echo json_encode(['success' => true]);
        exit;

    case 'user_delete':
        if (!isSuperAdmin()) { echo json_encode(['success' => false, 'error' => 'Super Admin only']); exit; }
        $tuid = (int)($input['user_id'] ?? 0);
        if ($tuid === $uid) { echo json_encode(['success' => false, 'error' => 'Cannot delete yourself']); exit; }
        $checkRole = $conn->query("SELECT role FROM users WHERE id=$tuid LIMIT 1")->fetch_assoc();
        if ($checkRole && $checkRole['role'] === 'super_admin') { echo json_encode(['success' => false, 'error' => 'Cannot delete Super Admin']); exit; }
        $conn->query("DELETE FROM user_groups WHERE user_id=$tuid");
        $conn->query("DELETE FROM users WHERE id=$tuid");
        echo json_encode(['success' => true]);
        exit;

    case 'user_change_password':
        if (!isSuperAdmin()) { echo json_encode(['success' => false, 'error' => 'Super Admin only']); exit; }
        $tuid  = (int)($input['user_id']  ?? 0);
        $upass = trim($input['password']  ?? '');
        if ($tuid <= 0 || strlen($upass) < 6) { echo json_encode(['success' => false, 'error' => 'Invalid']); exit; }
        $hash = password_hash($upass, PASSWORD_DEFAULT);
        $stmt = $conn->prepare("UPDATE users SET password=? WHERE id=?");
        $stmt->bind_param("si", $hash, $tuid);
        echo json_encode(['success' => (bool)$stmt->execute()]);
        exit;

    case 'user_assign_groups':
        if (!isSuperAdmin()) { echo json_encode(['success' => false, 'error' => 'Super Admin only']); exit; }
        $tuid     = (int)($input['user_id']   ?? 0);
        $newGids  = array_map('intval', $input['group_ids'] ?? []);
        if ($tuid <= 0) { echo json_encode(['success' => false]); exit; }
        $conn->query("DELETE FROM user_groups WHERE user_id=$tuid");
        foreach ($newGids as $gid) {
            $conn->query("INSERT IGNORE INTO user_groups (user_id, group_id) VALUES ($tuid, $gid)");
        }
        echo json_encode(['success' => true]);
        exit;

    case 'user_groups_get':
        if (!isSuperAdmin()) { echo json_encode(['success' => false, 'error' => 'Super Admin only']); exit; }
        $tuid = (int)($input['user_id'] ?? $_GET['user_id'] ?? 0);
        $res  = $conn->query("SELECT group_id FROM user_groups WHERE user_id=$tuid");
        $gids = [];
        while ($row = $res->fetch_assoc()) $gids[] = (int)$row['group_id'];
        echo json_encode(['success' => true, 'group_ids' => $gids]);
        exit;

    case 'group_list':
        $res    = $conn->query("SELECT id, name FROM `groups` WHERE id IN ($groupIdList) ORDER BY name");
        $groups = [];
        while ($row = $res->fetch_assoc()) $groups[] = $row;
        echo json_encode(['success' => true, 'groups' => $groups]);
        exit;

    case 'vm_stats':
        $res = $conn->query("
            SELECT
                COUNT(*) AS total,
                SUM(CASE WHEN v.last_heartbeat >= NOW() - INTERVAL 5 MINUTE THEN 1 ELSE 0 END) AS online,
                SUM(CASE WHEN LOWER(v.status)='running' THEN 1 ELSE 0 END) AS running,
                SUM(CASE WHEN LOWER(v.status)='blocked' THEN 1 ELSE 0 END) AS blocked,
                SUM(CASE WHEN LOWER(v.status)='paused' THEN 1 ELSE 0 END) AS paused,
                COALESCE(SUM(v.balance),0) AS total_balance
            FROM vms v
            JOIN rdps r ON r.id=v.rdp_id
            WHERE r.group_id IN ($groupIdList)
        ");
        echo json_encode(['success' => true, 'stats' => $res->fetch_assoc()]);
        exit;

    case 'user_get_permissions':
        if (!isSuperAdmin()) { echo json_encode(array('success' => false, 'error' => 'Super Admin only')); exit; }
        $tuid = (int)(isset($input['user_id']) ? $input['user_id'] : (isset($_GET['user_id']) ? $_GET['user_id'] : 0));
        if ($tuid <= 0) { echo json_encode(array('success' => false, 'error' => 'Invalid user')); exit; }
        $permKeys = array('can_view_groups','can_add_group','can_edit_group','can_delete_group','can_view_rdp','can_add_rdp','can_edit_rdp','can_delete_rdp','can_view_vm','can_add_vm','can_edit_vm','can_delete_vm','can_send_commands','can_view_earnings','can_view_reports','can_view_analytics','can_view_ip','can_view_dashboard','can_view_settings','can_change_password','can_view_tokens');
        $row = $conn->query("SELECT * FROM user_permissions WHERE user_id=" . $tuid . " LIMIT 1")->fetch_assoc();
        $outPerms = array();
        foreach ($permKeys as $pk) { $outPerms[$pk] = $row ? (bool)$row[$pk] : false; }
        echo json_encode(array('success' => true, 'permissions' => $outPerms));
        exit;

    case 'erase_admin_data':
        if (!isSuperAdmin()) { echo json_encode(['success' => false, 'error' => 'Super Admin only']); exit; }
        $tuid = (int)($input['user_id'] ?? 0);
        if ($tuid <= 0) { echo json_encode(['success' => false, 'error' => 'Invalid user']); exit; }

        $roleRes = $conn->query("SELECT role, tenant_id FROM users WHERE id=$tuid LIMIT 1");
        $roleRow  = $roleRes ? $roleRes->fetch_assoc() : null;
        if (!$roleRow) { echo json_encode(['success' => false, 'error' => 'User not found']); exit; }
        if ($roleRow['role'] === 'super_admin') { echo json_encode(['success' => false, 'error' => 'Cannot erase Super Admin data']); exit; }

        if ($roleRow['role'] === 'admin') {
            $tid = ($roleRow['tenant_id'] !== null) ? (int)$roleRow['tenant_id'] : $tuid;
            $gRes = $conn->query("SELECT id FROM `groups` WHERE tenant_id=$tid");
        } else {
            $gRes = $conn->query("SELECT g.id FROM `groups` g JOIN user_groups ug ON ug.group_id=g.id WHERE ug.user_id=$tuid");
        }

        $gids = [];
        if ($gRes) while ($r = $gRes->fetch_assoc()) $gids[] = (int)$r['id'];

        if (!empty($gids)) {
            $gidList = implode(',', $gids);

            $vRes = $conn->query("SELECT v.id FROM vms v JOIN rdps r ON r.id=v.rdp_id WHERE r.group_id IN ($gidList)");
            $vids = [];
            if ($vRes) while ($r = $vRes->fetch_assoc()) $vids[] = (int)$r['id'];

            if (!empty($vids)) {
                $vidList = implode(',', $vids);
                $conn->query("DELETE FROM vm_commands WHERE vm_id IN ($vidList)");
                $conn->query("DELETE FROM earnapp_history WHERE vm_id IN ($vidList)");
                $conn->query("DELETE FROM vms WHERE id IN ($vidList)");
            }

            $conn->query("DELETE FROM rdps WHERE group_id IN ($gidList)");
            $conn->query("DELETE FROM `groups` WHERE id IN ($gidList)");
            $conn->query("DELETE FROM user_groups WHERE group_id IN ($gidList)");
        }

        $conn->query("DELETE FROM user_groups WHERE user_id=$tuid");
        echo json_encode(['success' => true]);
        exit;

    case 'user_save_permissions':
        if (!isSuperAdmin()) { echo json_encode(array('success' => false, 'error' => 'Super Admin only')); exit; }
        $tuid  = (int)(isset($input['user_id']) ? $input['user_id'] : 0);
        $perms = isset($input['permissions']) ? $input['permissions'] : array();
        if ($tuid <= 0) { echo json_encode(array('success' => false, 'error' => 'Invalid user')); exit; }
        $permKeys = array('can_view_groups','can_add_group','can_edit_group','can_delete_group','can_view_rdp','can_add_rdp','can_edit_rdp','can_delete_rdp','can_view_vm','can_add_vm','can_edit_vm','can_delete_vm','can_send_commands','can_view_earnings','can_view_reports','can_view_analytics','can_view_ip','can_view_dashboard','can_view_settings','can_change_password','can_view_tokens');
        $setPairs = array();
        foreach ($permKeys as $pk) { $v = (!empty($perms[$pk])) ? 1 : 0; $setPairs[] = "`" . $pk . "`=" . $v; }
        $exists = $conn->query("SELECT id FROM user_permissions WHERE user_id=" . $tuid . " LIMIT 1")->num_rows > 0;
        if ($exists) {
            $sql = "UPDATE user_permissions SET " . implode(',', $setPairs) . " WHERE user_id=" . $tuid;
        } else {
            $colParts = array(); $valParts = array();
            foreach ($permKeys as $pk) { $colParts[] = "`" . $pk . "`"; $valParts[] = (!empty($perms[$pk])) ? 1 : 0; }
            $sql = "INSERT INTO user_permissions (user_id," . implode(',', $colParts) . ") VALUES (" . $tuid . "," . implode(',', $valParts) . ")";
        }
        $ok = $conn->query($sql);
        echo json_encode(array('success' => (bool)$ok, 'error' => $ok ? null : $conn->error));
        exit;

    case 'clear_agent_log':
        if (!isSuperAdmin()) { echo json_encode(['success' => false, 'error' => 'Super Admin only']); exit; }
        $ok = $conn->query("TRUNCATE TABLE agent_update_log");
        echo json_encode(['success' => (bool)$ok, 'error' => $ok ? null : $conn->error]);
        exit;

    case 'get_agent_ps1':
        if (!isSuperAdmin()) { echo json_encode(['success' => false, 'error' => 'Super Admin only']); exit; }
        $agentPath = __DIR__ . '/../static/agent.ps1';
        if (!file_exists($agentPath)) { echo json_encode(['success' => false, 'error' => 'agent.ps1 not found']); exit; }
        $content = file_get_contents($agentPath);
        $version = 'unknown';
        if (preg_match('/\$AGENT_VERSION\s*=\s*"([^"]+)"/', $content, $m)) $version = $m[1];
        echo json_encode(['success' => true, 'content' => $content, 'version' => $version]);
        exit;

    case 'update_agent_ps1':
        if (!isSuperAdmin()) { echo json_encode(['success' => false, 'error' => 'Super Admin only']); exit; }
        $newContent = isset($input['content']) ? $input['content'] : '';
        if (empty(trim($newContent))) { echo json_encode(['success' => false, 'error' => 'Content cannot be empty']); exit; }
        $agentPath = __DIR__ . '/../static/agent.ps1';

        $oldContent = file_exists($agentPath) ? file_get_contents($agentPath) : '';
        $fromVer = 'unknown';
        if (preg_match('/\$AGENT_VERSION\s*=\s*"([^"]+)"/', $oldContent, $mv)) $fromVer = $mv[1];
        $toVer = 'unknown';
        if (preg_match('/\$AGENT_VERSION\s*=\s*"([^"]+)"/', $newContent, $mv)) $toVer = $mv[1];

        $result = file_put_contents($agentPath, $newContent);
        if ($result === false) { echo json_encode(['success' => false, 'error' => 'Failed to write file']); exit; }

        $pushedBy = $conn->real_escape_string($_SESSION['username'] ?? 'superadmin');
        $fromVerS = $conn->real_escape_string($fromVer);
        $toVerS   = $conn->real_escape_string($toVer);

        $vmCountRes = $conn->query("SELECT COUNT(*) c FROM vms");
        $totalVmCount = $vmCountRes ? (int)$vmCountRes->fetch_assoc()['c'] : 0;

        $conn->query("INSERT INTO agent_push_log (pushed_by, from_version, to_version, total_vms) VALUES ('$pushedBy', '$fromVerS', '$toVerS', $totalVmCount)");
        $pushId = (int)$conn->insert_id;

        $vmRes2 = $conn->query("SELECT v.id, v.unit_id, v.agent_version, r.name AS rdp_nickname, g.name AS group_name FROM vms v LEFT JOIN rdps r ON r.id=v.rdp_id LEFT JOIN `groups` g ON g.id=r.group_id");
        if ($vmRes2) {
            while ($vrow = $vmRes2->fetch_assoc()) {
                $vid   = (int)$vrow['id'];
                $vuid  = $conn->real_escape_string($vrow['unit_id'] ?? '');
                $vrdp  = $conn->real_escape_string($vrow['rdp_nickname'] ?? '');
                $vgrp  = $conn->real_escape_string($vrow['group_name'] ?? '');
                $vver  = $conn->real_escape_string($vrow['agent_version'] ?? '');
                $vstatus = ($vrow['agent_version'] === $toVer) ? 'skipped' : 'pending';
                $conn->query("INSERT INTO agent_push_vm_status (push_id, vm_id, unit_id, rdp_nickname, group_name, version_at_push, status) VALUES ($pushId, $vid, '$vuid', '$vrdp', '$vgrp', '$vver', '$vstatus')");
            }
        }

        echo json_encode(['success' => true, 'push_id' => $pushId, 'from_version' => $fromVer, 'to_version' => $toVer, 'total_vms' => $totalVmCount]);
        exit;

    case 'get_push_status':
        if (!isSuperAdmin()) { echo json_encode(['success' => false, 'error' => 'Super Admin only']); exit; }
        $pushId = (int)($input['push_id'] ?? 0);
        if ($pushId <= 0) { echo json_encode(['success' => false, 'error' => 'Invalid push_id']); exit; }
        $pl = $conn->query("SELECT * FROM agent_push_log WHERE id=$pushId LIMIT 1");
        if (!$pl || $pl->num_rows === 0) { echo json_encode(['success' => false, 'error' => 'Push not found']); exit; }
        $pushRow = $pl->fetch_assoc();
        $vms2 = $conn->query("SELECT * FROM agent_push_vm_status WHERE push_id=$pushId ORDER BY status ASC, unit_id ASC");
        $vmRows = [];
        if ($vms2) while ($r = $vms2->fetch_assoc()) $vmRows[] = $r;
        echo json_encode(['success' => true, 'push' => $pushRow, 'vms' => $vmRows]);
        exit;

    case 'get_all_pushes':
        if (!isSuperAdmin()) { echo json_encode(['success' => false, 'error' => 'Super Admin only']); exit; }
        $pushes = [];
        $pr = $conn->query("SELECT p.*, (SELECT COUNT(*) FROM agent_push_vm_status WHERE push_id=p.id AND status='done') AS done_count, (SELECT COUNT(*) FROM agent_push_vm_status WHERE push_id=p.id AND status='pending') AS pending_count, (SELECT COUNT(*) FROM agent_push_vm_status WHERE push_id=p.id AND status='failed') AS failed_count FROM agent_push_log p ORDER BY p.id DESC LIMIT 20");
        if ($pr) while ($r = $pr->fetch_assoc()) $pushes[] = $r;
        echo json_encode(['success' => true, 'pushes' => $pushes]);
        exit;

    default:
        echo json_encode(['success' => false, 'error' => 'Invalid action: ' . htmlspecialchars($action)]);
        exit;
}

$conn->close();
?>