<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);

header('Content-Type: application/json');

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

if (!isset($conn) || $conn->connect_error) {
    echo json_encode(['success' => false, 'error' => 'Database connection failed']);
    exit;
}

date_default_timezone_set('Asia/Kolkata');

$input = json_decode(file_get_contents('php://input'), true);
if (json_last_error() !== JSON_ERROR_NONE) {
    $input = [];
}
$action = $_GET['action'] ?? ($input['action'] ?? '');

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

switch ($action) {

    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 'vm_ping':
        $vmId = (int)($input['vm_id'] ?? 0);

        if ($vmId > 0) {
            $stmt = $conn->prepare("UPDATE vms SET last_heartbeat = UTC_TIMESTAMP() WHERE id = ?");
            $stmt->bind_param("i", $vmId);
            $stmt->execute();
        }

        echo json_encode(['success' => true]);
        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
            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'][] = [
                        'id'         => (int)$row['v_id'],
                        'name'       => $row['unit_id'],
                        'current_ip' => $row['current_ip'],
                        'last_seen'  => $row['last_heartbeat'],
                        'balance'    => $row['balance'],
                        'traffic'    => $row['traffic'],
                        'status'     => $row['status'],
                    ];
                }
            }
        }

        $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 'fetch_command':
        $vmId = (int)($_GET['vm_id'] ?? 0);
    
        if ($vmId <= 0) {
            echo json_encode(null);
            exit;
        }
    
        // Raw debug
        $r = $conn->query("SELECT id, command FROM vm_commands WHERE vm_id = $vmId AND status = 'pending' LIMIT 1");
        $row = $r ? $r->fetch_assoc() : null;
        
        if (!$row) {
            echo json_encode(['debug' => 'no row found', 'vmId' => $vmId]);
            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 'register':
            $groupName  = trim($input['group_name']   ?? '');
            $rdpName    = trim($input['rdp_nickname'] ?? '');
            $unitId     = trim($input['unit_id']      ?? '');
            $assignedIp = $input['assigned_ip']       ?? null;
        
            if (strlen($groupName) < 2 || strlen($unitId) < 2 || $unitId === 'DefaultUnit' || $groupName === 'Default') {
                echo json_encode(['success' => false, 'error' => 'Invalid input']);
                exit;
            }
        
            $g = $conn->query("SELECT id FROM groups WHERE name='".$conn->real_escape_string($groupName)."' LIMIT 1")->fetch_assoc();
            if (!$g) {
                $conn->query("INSERT INTO groups (name) VALUES ('".$conn->real_escape_string($groupName)."')");
                $gId = $conn->insert_id;
        } else {
            $gId = $g['id'];
        }
    
        $r = $conn->query("SELECT id FROM rdps WHERE name='".$conn->real_escape_string($rdpName)."' AND group_id=$gId LIMIT 1")->fetch_assoc();
        if (!$r) {
            $conn->query("INSERT INTO rdps (name, group_id) VALUES ('".$conn->real_escape_string($rdpName)."', $gId)");
            $rId = $conn->insert_id;
        } else {
            $rId = $r['id'];
        }
    
        $stmt = $conn->prepare("
            INSERT INTO vms (unit_id, rdp_id, current_ip, status, last_heartbeat)
            VALUES (?, ?, ?, 'Offline', NULL)
            ON DUPLICATE KEY UPDATE
                current_ip     = VALUES(current_ip),
                last_heartbeat = UTC_TIMESTAMP()
        ");
        $stmt->bind_param("sis", $unitId, $rId, $assignedIp);
        $stmt->execute();
    
        $vmId = $conn->insert_id ?: $conn->query("SELECT id FROM vms WHERE unit_id='".$conn->real_escape_string($unitId)."' AND rdp_id=$rId LIMIT 1")->fetch_assoc()['id'];
    
        echo json_encode(['success' => true, 'vm_id' => (int)$vmId]);
        exit;

    case 'delete_vms':
        $ids = $input['ids'] ?? [];

        if (!is_array($ids) || empty($ids)) {
            echo json_encode(['success' => false]);
            exit;
        }

        $idList = implode(',', array_map('intval', $ids));
        $conn->query("DELETE FROM vms WHERE id IN ($idList)");

        echo json_encode(['success' => true]);
        exit;


    case 'delete_rdps':
        $ids = $input['ids'] ?? [];

        if (!is_array($ids) || empty($ids)) {
            echo json_encode(['success' => false]);
            exit;
        }

        $idList = implode(',', array_map('intval', $ids));
        $conn->query("DELETE FROM vms WHERE rdp_id IN ($idList)");
        $conn->query("DELETE FROM rdps WHERE id IN ($idList)");

        echo json_encode(['success' => true]);
        exit;


    case 'delete_vm_commands':
        $ids = $input['ids'] ?? [];

        if (!is_array($ids) || empty($ids)) {
            echo json_encode(['success' => false]);
            exit;
        }

        $idList = implode(',', array_map('intval', $ids));
        $conn->query("DELETE FROM vm_commands WHERE id IN ($idList)");

        echo json_encode(['success' => true]);
        exit;


    case 'delete_groups':
        $ids = $input['ids'] ?? [];

        if (!is_array($ids) || empty($ids)) {
            echo json_encode(['success' => false]);
            exit;
        }

        $idList = implode(',', array_map('intval', $ids));
        $conn->query("DELETE FROM vms WHERE rdp_id IN (SELECT id FROM rdps WHERE group_id IN ($idList))");
        $conn->query("DELETE FROM rdps WHERE group_id IN ($idList)");
        $conn->query("DELETE FROM groups WHERE id IN ($idList)");

        echo json_encode(['success' => true]);
        exit;


    case 'heartbeat':
        if (empty($input['vm_id'])) {
            echo json_encode(['success' => false]);
            exit;
        }

        $vmId = (int)$input['vm_id'];
        $ip   = $input['ip_address'] ?? null;

        $stmt = $conn->prepare("
            UPDATE vms
            SET last_heartbeat = UTC_TIMESTAMP(),
                current_ip     = ?
            WHERE id = ?
        ");
        $ipVal = $ip ?? '';
        $stmt->bind_param("si", $ipVal, $vmId);
        $stmt->execute();

        echo json_encode(['success' => true]);
        exit;


    case 'ack_command':
        $id    = (int)($_GET['id']    ?? 0);
        $vm_id = (int)($_GET['vm_id'] ?? 0);

        if ($id <= 0 || $vm_id <= 0) {
            echo json_encode(['ok' => false]);
            exit;
        }

        $stmt = $conn->prepare("UPDATE vm_commands SET status='done', completed_at=UTC_TIMESTAMP() WHERE id=? AND vm_id=?");
        $stmt->bind_param("ii", $id, $vm_id);
        $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';
        $stmt->bind_param("ssi", $success, $input['message'], $input['command_id']);
        $stmt->execute();

        echo json_encode(['ok' => true]);
        exit;


    case 'add_group':
        $stmt = $conn->prepare("INSERT INTO groups (name) VALUES (?)");
        $stmt->bind_param("s", $input['name']);
        $stmt->execute();

        echo json_encode(['success' => true]);
        exit;


    case 'add_rdp':
        $stmt = $conn->prepare("INSERT INTO rdps (name, group_id) VALUES (?, ?)");
        $stmt->bind_param("si", $input['name'], $input['group_id']);
        $stmt->execute();

        echo json_encode(['success' => true]);
        exit;


    case 'add_vm':
        $rdpId  = (int)($input['rdp_id']  ?? 0);
        $vmName = trim($input['unit_id']  ?? '');
    
        if ($rdpId <= 0 || $vmName === '') {
            echo json_encode(['success' => false, 'error' => 'Input missing']);
            exit;
        }
    
        $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
        ");
        if (!$r_res || $r_res->num_rows === 0) {
            echo json_encode(['success' => false, 'error' => 'RDP not found']);
            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(['success' => false, 'error' => 'VM already exists']);
            exit;
        }
    
        $stmt = $conn->prepare("
            INSERT INTO vms (unit_id, rdp_id, group_id, group_name, rdp_nickname, status, last_heartbeat) 
            VALUES (?, ?, ?, ?, ?, 'Offline', NULL)
        ");
        $stmt->bind_param("siiss", $vmName, $rdpId, $groupId, $groupName, $rdpName);
        $ok = $stmt->execute();
    
        echo json_encode(['success' => $ok, 'vm_id' => $ok ? $conn->insert_id : null, 'error' => $ok ? null : $stmt->error]);
        exit;


    case 'send_all_by_unit':
        $cmd = strtolower(trim($input['command'] ?? ''));

        if ($cmd === '') {
            echo json_encode(['success' => false]);
            exit;
        }

        $stmt = $conn->prepare("
            INSERT INTO vm_commands (vm_id, command, status, created_at)
            SELECT id, ?, 'pending', UTC_TIMESTAMP() FROM vms WHERE unit_id IS NOT NULL
        ");
        $stmt->bind_param("s", $cmd);
        $stmt->execute();

        echo json_encode(['success' => $stmt->affected_rows > 0]);
        exit;


    case 'send_global_command':
        $cmd = 'fetch_balance_global';

        $stmt = $conn->prepare("
            INSERT INTO vm_commands (vm_id, command, status, created_at)
            SELECT id, ?, 'pending', UTC_TIMESTAMP() FROM vms WHERE unit_id IS NOT NULL
        ");
        $stmt->bind_param("s", $cmd);
        $stmt->execute();

        echo json_encode(['success' => $stmt->affected_rows > 0]);
        exit;


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

$conn->close();