[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)] })

# Load existing config to preserve credentials across restarts
if (Test-Path "proxy-agent.json") {
    Write-Host "Found existing proxy-agent.json, preserving Node ID and credentials..."
    try {
        $existing = Get-Content "proxy-agent.json" -Raw | ConvertFrom-Json
        if ($existing.node_id) { $node_id = $existing.node_id }
        if ($existing.node_secret) { $node_secret = $existing.node_secret }
        if ($existing.proxy_user) { $proxy_user = $existing.proxy_user }
        if ($existing.proxy_pass) { $proxy_pass = $existing.proxy_pass }
    } catch {
        Write-Host "  [warn] Could not parse existing config, using fresh values."
    }
}

Write-Host "Generating config files..."

# Note: frp_server_id is intentionally omitted — proxy-node resolves it
# dynamically by calling GET /api/node/select-frps on startup.
# frpc.toml is also generated by proxy-node, not by this script.
$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
    interval = 30
    timeout = 10
    max_connections = 500
}
$utf8NoBom = New-Object System.Text.UTF8Encoding $False
[System.IO.File]::WriteAllText("proxy-agent.json", ($agent_json | ConvertTo-Json -Depth 5), $utf8NoBom)

Write-Host "Killing old background processes if running..."
Stop-Process -Name "proxy-node", "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=""

# proxy-node handles everything: HTTP proxy + SOCKS5 proxy + FRPS selection + frpc + heartbeat
Write-Host "Starting proxy-node (HTTP + SOCKS5 proxy + FRPS selection + frpc + heartbeat)..."
Start-Process -FilePath ".\proxy-node.exe" -WindowStyle Hidden -RedirectStandardOutput "proxy-node.log" -RedirectStandardError "proxy-node-error.log"

Write-Host ""
Write-Host "Done! AI-Network node is running." -ForegroundColor Green
Write-Host "proxy-node now manages frpc automatically (supervised child process)." -ForegroundColor Yellow
Write-Host "Use .\monitor-node.ps1 to view logs and status." -ForegroundColor Yellow
