param (
    [string]$BackendUrl = "https://bdma.co.in/earnapp",
    [int]$VMId = 0,
    [string]$Group = "Default",
    [string]$UnitId = "DefaultUnit",
    [string]$RdpNickname = "UnknownRDP"
)

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
[System.Net.ServicePointManager]::DnsRefreshTimeout = 0

$remoteUrl = "https://bdma.co.in/earnapp/static/latest.ps1"
$localPath = $MyInvocation.MyCommand.Path
$tempPath  = "$env:TEMP\agent_new.ps1"

try {
    $wc = New-Object System.Net.WebClient
    $wc.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) UpdateAgent/1.0")
    $wc.DownloadFile($remoteUrl, $tempPath)

    if ((Test-Path $tempPath) -and ((Get-FileHash $tempPath -Algorithm SHA256).Hash -ne (Get-FileHash $localPath -Algorithm SHA256).Hash)) {
        Start-Sleep -Seconds 2
        Copy-Item $tempPath $localPath -Force
        Remove-Item $tempPath -Force -ErrorAction SilentlyContinue
        schtasks /end /tn SinnerWatchdogAgent 2>$null
        Start-Sleep -Seconds 2
        schtasks /run /tn SinnerWatchdogAgent 2>$null
        exit 0
    }
}
catch {}
finally {
    if (Test-Path $tempPath) { Remove-Item $tempPath -Force -ErrorAction SilentlyContinue }
}

$HeartbeatInterval   = 60
$StatsSyncInterval   = 300
$CommandPollInterval = 10

$LogPath    = "$env:APPDATA\SinnerWatchdog\agent.log"
$ConfigPath = "$env:APPDATA\SinnerWatchdog\vm_id.txt"

function Write-Log {
    param($msg)
    $ts = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    if (!(Test-Path (Split-Path $LogPath))) {
        New-Item -ItemType Directory -Path (Split-Path $LogPath) -Force | Out-Null
    }
    "[$ts] $msg" | Out-File $LogPath -Append -Encoding utf8
}

function Get-PublicIP {
    try { (Invoke-RestMethod "https://api.ipify.org?format=json" -TimeoutSec 8).ip }
    catch {
        try { (Invoke-RestMethod "https://ifconfig.me/ip" -TimeoutSec 8).Trim() }
        catch { "0.0.0.0" }
    }
}

function Invoke-RestMethodWithRetry {
    param(
        [string]$Uri,
        [string]$Method = "GET",
        [string]$ContentType = "application/json",
        [string]$Body = "",
        [int]$TimeoutSec = 15,
        [int]$MaxRetries = 3
    )
    for ($i = 0; $i -lt $MaxRetries; $i++) {
        try {
            if ($Method -eq "GET") {
                return Invoke-RestMethod -Uri $Uri -Method GET -TimeoutSec $TimeoutSec
            } else {
                return Invoke-RestMethod -Uri $Uri -Method $Method -ContentType $ContentType -Body $Body -TimeoutSec $TimeoutSec
            }
        }
        catch {
            if ($i -eq $MaxRetries - 1) { throw }
            Start-Sleep -Seconds (5 * ($i + 1))
        }
    }
}

$CurrentVmId = $VMId

if ($CurrentVmId -eq 0) {
    if (Test-Path $ConfigPath) {
        $CurrentVmId = [int](Get-Content $ConfigPath -Raw).Trim()
    }
}

if ($CurrentVmId -eq 0) {
    try {
        $body = @{
            group_name   = $Group
            unit_id      = $UnitId
            rdp_nickname = $RdpNickname
            assigned_ip  = (Get-PublicIP)
        } | ConvertTo-Json

        $resp = Invoke-RestMethodWithRetry "$BackendUrl/api/vm/register.php" -Method Post -Body $body
        if ($resp.vm_id -and $resp.vm_id -gt 0) {
            $CurrentVmId = $resp.vm_id
            $CurrentVmId | Out-File $ConfigPath -Force
            Write-Log "Registered - VM ID: $CurrentVmId"
        }
    }
    catch {
        Write-Log "Registration failed: $($_.Exception.Message)"
    }
}

if ($CurrentVmId -eq 0) {
    Write-Log "Could not get VM ID. Exiting."
    exit 1
}

$lastHeartbeat = Get-Date 0
$lastStats     = Get-Date 0
$lastCommand   = Get-Date 0

while ($true) {
    $now = Get-Date

    if (($now - $lastCommand).TotalSeconds -ge $CommandPollInterval) {
        try {
            $cmd = Invoke-RestMethodWithRetry "$BackendUrl/pages/api.php?action=fetch_command&vm_id=$CurrentVmId"
            if ($cmd -and $cmd.action) {
                if ($cmd.action -eq "restart_vm") {
                    Write-Log "Restart command received"
                    Invoke-RestMethodWithRetry "$BackendUrl/pages/api.php?action=ack_command&id=$($cmd.id)&vm_id=$CurrentVmId"
                    Start-Process "shutdown.exe" -ArgumentList "/r /t 5 /f" -WindowStyle Hidden
                }
            }
        }
        catch {
            Write-Log "Command poll failed: $($_.Exception.Message)"
        }
        $lastCommand = $now
    }

    if (($now - $lastHeartbeat).TotalSeconds -ge $HeartbeatInterval) {
        try {
            $body = @{
                action     = "heartbeat"
                vm_id      = $CurrentVmId
                ip_address = (Get-PublicIP)
            } | ConvertTo-Json
            Invoke-RestMethodWithRetry "$BackendUrl/save_data.php" -Method Post -Body $body
            Write-Log "Heartbeat sent"
        }
        catch {
            Write-Log "Heartbeat failed: $($_.Exception.Message)"
        }
        $lastHeartbeat = $now
    }

    if (($now - $lastStats).TotalSeconds -ge $StatsSyncInterval) {
        try {
            $body = @{
                vm_id        = $CurrentVmId
                unit_id      = $UnitId
                group_name   = $Group
                rdp_nickname = $RdpNickname
                ip_address   = (Get-PublicIP)
                balance      = 0
                traffic      = "0B"
                status       = "Running"
            } | ConvertTo-Json
            Invoke-RestMethodWithRetry "$BackendUrl/save_data.php" -Method Post -Body $body
            Write-Log "Stats sync sent"
        }
        catch {
            Write-Log "Stats sync failed: $($_.Exception.Message)"
        }
        $lastStats = $now
    }

    Start-Sleep -Seconds 5
}