[CmdletBinding()]
param()

$machine_name = $env:COMPUTERNAME
try {
    $hw_id = (Get-CimInstance -Class Win32_ComputerSystemProduct -ErrorAction Stop).UUID
} catch {
    $hw_id = (Get-WmiObject -Class Win32_ComputerSystemProduct -ErrorAction SilentlyContinue).UUID
}
if (!$hw_id) { $hw_id = "UNKNOWN-HW-ID" }
$node_id = "$machine_name-$hw_id"

Write-Host "Node ID: $node_id"
$md5 = [System.Security.Cryptography.MD5]::Create()
$hash = $md5.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($node_id))
$node_secret = [BitConverter]::ToString($hash).Replace("-", "").ToLower()
Write-Host "Node Secret: $node_secret"

Write-Host "Fetching geolocation..."
$prov = "Unknown"
$city = "Unknown"
$public_ip = "Unknown"

$apis = @(
    @{ url="http://ip-api.com/json?lang=zh-CN"; prov="regionName"; city="city"; ip="query" },
    @{ url="https://ipwhois.app/json/?lang=zh-CN"; prov="region"; city="city"; ip="ip" },
    @{ url="http://ipwho.is/?lang=zh-CN"; prov="region"; city="city"; ip="ip" },
    @{ url="https://ipinfo.io/json"; prov="region"; city="city"; ip="ip" },
    @{ url="https://freeipapi.com/api/json"; prov="regionName"; city="cityName"; ip="ipAddress" }
)

foreach ($api in $apis) {
    try {
        $geo = Invoke-RestMethod -Uri $api.url -TimeoutSec 3 -ErrorAction Stop
        $t_prov = $geo.($api.prov)
        $t_city = $geo.($api.city)
        $t_ip = $geo.($api.ip)
        
        # Check if the API returned valid data and not 'Unknown' or empty
        if (![string]::IsNullOrWhiteSpace($t_ip) -and ![string]::IsNullOrWhiteSpace($t_prov) -and -not ($t_prov -match "Unknown|-")) {
            $prov = $t_prov
            $city = $t_city
            $public_ip = $t_ip
            break # Exit loop once we get a valid geolocation
        }
    } catch {
        # Silently continue to the next API on failure
    }
}
Write-Host "Location: $prov, $city ($public_ip)"

$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
$proxy_user = "n_" + (-join ((1..8) | ForEach-Object { $chars[(Get-Random -Maximum $chars.Length)] }))
$proxy_pass = -join ((1..16) | ForEach-Object { $chars[(Get-Random -Maximum $chars.Length)] })

Write-Host "Generating config files..."

$agent_json = @{
    control_url = "https://api.zxiaoming.com"
    node_id = $node_id
    node_secret = $node_secret
    province = $prov
    city = $city
    public_ip = $public_ip
    proxy_user = $proxy_user
    proxy_pass = $proxy_pass
    frp_server_id = "frp-test-001"
    interval = 30
    timeout = 10
}
$utf8NoBom = New-Object System.Text.UTF8Encoding $False
[System.IO.File]::WriteAllText("proxy-agent.json", ($agent_json | ConvertTo-Json -Depth 5), $utf8NoBom)

$frpc_toml = @"
serverAddr = "124.70.180.22"
serverPort = 7000
loginFailExit = false
transport.heartbeatInterval = 30
transport.heartbeatTimeout = 90

auth.method = "token"
auth.token = "ai-agent-frps-1000-frp-server-token"

[[proxies]]
name = "socks5-$node_id"
type = "tcp"
localIP = "127.0.0.1"
localPort = 1080
remotePort = 0
metadatas.node_id = "$node_id"
metadatas.province = "$prov"
metadatas.city = "$city"

[[proxies]]
name = "http-proxy-$node_id"
type = "tcp"
localIP = "127.0.0.1"
localPort = 3128
remotePort = 0
metadatas.node_id = "$node_id"
metadatas.province = "$prov"
metadatas.city = "$city"
"@
[System.IO.File]::WriteAllText("frpc.toml", $frpc_toml, $utf8NoBom)

Write-Host "Killing old background processes if running..."
Stop-Process -Name "proxy-agent", "frpc", "gost" -Force -ErrorAction SilentlyContinue

Write-Host "Starting processes in background (Hidden)..."
# Clear proxies just in case
$env:HTTP_PROXY=""
$env:HTTPS_PROXY=""

# Start the apps hiding the command window
Start-Process -FilePath ".\proxy-agent.exe" -ArgumentList "-config proxy-agent.json" -WindowStyle Hidden -RedirectStandardOutput "proxy-agent.log" -RedirectStandardError "proxy-agent-error.log"
Start-Process -FilePath ".\frpc.exe" -ArgumentList "-c frpc.toml" -WindowStyle Hidden -RedirectStandardOutput "frpc.log" -RedirectStandardError "frpc-error.log"

$http_listen = "http://$proxy_user`:$proxy_pass@:3128"
$socks_listen = "socks5://$proxy_user`:$proxy_pass@:1080"
Start-Process -FilePath ".\gost.exe" -ArgumentList "-L", $http_listen, "-L", $socks_listen -WindowStyle Hidden -RedirectStandardOutput "gost.log" -RedirectStandardError "gost-error.log"

Write-Host ""
Write-Host "Done! AI-Network node is running." -ForegroundColor Green
Write-Host "Use .\monitor-node.ps1 to view logs and status." -ForegroundColor Yellow

