#Requires -RunAsAdministrator
$ErrorActionPreference = 'Stop'
$host.UI.RawUI.WindowTitle = 'ConnectDesk Agent Installer'

Write-Host ''
Write-Host 'ConnectDesk Windows Agent v1.4' -ForegroundColor Cyan
Write-Host 'The Agent will only be installed after successful server registration.'
Write-Host ''

$defaultServer = 'https://demo.ckaravias.com'
$serverInput = Read-Host "ConnectDesk server URL [$defaultServer]"
$server = $(if ([string]::IsNullOrWhiteSpace($serverInput)) { $defaultServer } else { $serverInput }).Trim().TrimEnd('/')
$code = (Read-Host 'UNUSED login/pairing code generated under Admin > Login Codes').Trim().ToUpperInvariant()
$computerName = (Read-Host 'Computer name').Trim()

if ([string]::IsNullOrWhiteSpace($server) -or [string]::IsNullOrWhiteSpace($code) -or [string]::IsNullOrWhiteSpace($computerName)) {
    Write-Host 'All values are required.' -ForegroundColor Red
    Read-Host 'Press Enter to close'
    exit 1
}

if ($code -match '^CD-[A-Z0-9]+$') {
    Write-Host ''
    Write-Host 'The value entered looks like a DEVICE CODE, not a login/pairing code.' -ForegroundColor Red
    Write-Host 'Open Admin > Login Codes, generate a new unused code, and run this installer again.' -ForegroundColor Yellow
    Read-Host 'Press Enter to close'
    exit 2
}

$endpoint = "$server/api/agent/register.php"
$body = @{
    login_code      = $code
    computer_name   = $computerName
    agent_version   = '1.4.0'
    operating_system= [System.Environment]::OSVersion.VersionString
    local_ip        = ''
}

Write-Host ''
Write-Host 'Validating pairing code with the ConnectDesk server...' -ForegroundColor Cyan
try {
    $response = Invoke-RestMethod -Uri $endpoint -Method Post -Body $body -ContentType 'application/x-www-form-urlencoded' -Headers @{ Accept='application/json'; 'User-Agent'='ConnectDesk-Installer/1.4' } -TimeoutSec 35
} catch {
    $detail = $_.Exception.Message
    try {
        $stream = $_.Exception.Response.GetResponseStream()
        if ($stream) {
            $reader = New-Object System.IO.StreamReader($stream)
            $raw = $reader.ReadToEnd()
            if ($raw) {
                $parsed = $raw | ConvertFrom-Json
                switch ($parsed.error) {
                    'invalid_or_expired_code' { $detail = 'The code is invalid, expired, disabled, already used, or has reached its usage limit.' }
                    'device_code_not_login_code' { $detail = 'A device code was entered. Generate a new unused code under Admin > Login Codes.' }
                    'login_code_and_computer_name_required' { $detail = 'The server did not receive the login code or computer name.' }
                    default { $detail = $raw }
                }
            }
        }
    } catch {}
    Write-Host ''
    Write-Host "Registration failed: $detail" -ForegroundColor Red
    Write-Host 'Nothing was installed.' -ForegroundColor Yellow
    Read-Host 'Press Enter to close'
    exit 3
}

if (-not $response.ok -or [string]::IsNullOrWhiteSpace([string]$response.agent_token)) {
    Write-Host 'Registration was rejected by the server. Nothing was installed.' -ForegroundColor Red
    Read-Host 'Press Enter to close'
    exit 4
}

$destination = Join-Path $env:ProgramData 'ConnectDesk'
$startup = [Environment]::GetFolderPath('CommonStartup')
$shortcutPath = Join-Path $startup 'ConnectDesk Agent.lnk'

New-Item -ItemType Directory -Path $destination -Force | Out-Null
Copy-Item -LiteralPath (Join-Path $PSScriptRoot 'ConnectDesk-Agent.exe') -Destination (Join-Path $destination 'ConnectDesk-Agent.exe') -Force
New-Item -ItemType Directory -Path (Join-Path $destination 'logs') -Force | Out-Null

$config = @(
    "server_url=$server"
    "login_code="
    "computer_name=$computerName"
    "agent_token=$($response.agent_token)"
    "device_code=$($response.device_code)"
) -join "`r`n"
[System.IO.File]::WriteAllText((Join-Path $destination 'agent.conf'), $config + "`r`n", [System.Text.UTF8Encoding]::new($false))

$wsh = New-Object -ComObject WScript.Shell
$shortcut = $wsh.CreateShortcut($shortcutPath)
$shortcut.TargetPath = Join-Path $destination 'ConnectDesk-Agent.exe'
$shortcut.WorkingDirectory = $destination
$shortcut.Description = 'ConnectDesk Windows Agent'
$shortcut.Save()

# Visible shortcuts so the installation can be found easily.
$commonPrograms = [Environment]::GetFolderPath('CommonPrograms')
$programFolder = Join-Path $commonPrograms 'ConnectDesk'
New-Item -ItemType Directory -Path $programFolder -Force | Out-Null
foreach ($linkPath in @((Join-Path $programFolder 'ConnectDesk Agent.lnk'), (Join-Path ([Environment]::GetFolderPath('CommonDesktopDirectory')) 'ConnectDesk Agent.lnk'))) {
    $link = $wsh.CreateShortcut($linkPath)
    $link.TargetPath = Join-Path $destination 'ConnectDesk-Agent.exe'
    $link.WorkingDirectory = $destination
    $link.Description = 'ConnectDesk Windows Agent'
    $link.Save()
}

# A status shortcut opens the installation folder and log file.
$statusBat = Join-Path $destination 'Agent-Status.bat'
$statusContent = '@echo off' + "`r`n" + 'echo ConnectDesk Agent installation: %ProgramData%\ConnectDesk' + "`r`n" + 'echo.' + "`r`n" + 'if exist "%ProgramData%\ConnectDesk\agent.log" type "%ProgramData%\ConnectDesk\agent.log"' + "`r`n" + 'echo.' + "`r`n" + 'pause' + "`r`n"
[System.IO.File]::WriteAllText($statusBat, $statusContent, [System.Text.Encoding]::ASCII)
$statusLink = $wsh.CreateShortcut((Join-Path $programFolder 'Agent Status and Log.lnk'))
$statusLink.TargetPath = $statusBat
$statusLink.WorkingDirectory = $destination
$statusLink.Save()

Start-Process -FilePath (Join-Path $destination 'ConnectDesk-Agent.exe') -WorkingDirectory $destination

Write-Host ''
Write-Host 'ConnectDesk Agent registered and installed successfully.' -ForegroundColor Green
Write-Host "Device code: $($response.device_code)"
Write-Host "Installed in: $destination"
Write-Host 'The computer should appear online in the administrator panel within a few seconds.'
Read-Host 'Press Enter to close'
