[CmdletBinding()]
param(
    [Parameter(Mandatory)][string]$Server,
    [ValidateRange(1,65535)][int]$ApiPort = 443,
    [ValidateRange(1,65535)][int]$RelayPort = 7443,
    [Parameter(Mandatory)][string]$ApplicationKey,
    [string]$UnattendedPassword,
    [string]$ServiceName = 'LRM REMOTE DSK Client',
    [string]$InstallDirectory = "$env:ProgramFiles\LRM REMOTE DSK\Client",
    [switch]$Silent
)

$ErrorActionPreference = 'Stop'
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = [Security.Principal.WindowsPrincipal]::new($identity)
if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { throw 'Administrator privileges are required.' }
function Protect-MachineValue([string]$Value) { [Convert]::ToBase64String([Security.Cryptography.ProtectedData]::Protect([Text.Encoding]::UTF8.GetBytes($Value), $null, [Security.Cryptography.DataProtectionScope]::LocalMachine)) }
function Hash-Password([string]$Value) { if ([string]::IsNullOrEmpty($Value)) { return $null }; $salt = [Security.Cryptography.RandomNumberGenerator]::GetBytes(16); $derive = [Security.Cryptography.Rfc2898DeriveBytes]::new($Value, $salt, 210000, [Security.Cryptography.HashAlgorithmName]::SHA256); "pbkdf2-sha256`$210000`$$([Convert]::ToBase64String($salt))`$$([Convert]::ToBase64String($derive.GetBytes(32)))" }

$clientExe = Join-Path $PSScriptRoot 'LRM-REMOTE-DSK-Client.exe'
if (-not (Test-Path -LiteralPath $clientExe)) { throw 'Unified Client executable is missing from the deployment package.' }
New-Item -ItemType Directory -Force -Path $InstallDirectory | Out-Null
$service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($service) { Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue }
Copy-Item -LiteralPath $clientExe -Destination $InstallDirectory -Force
Get-ChildItem -LiteralPath $PSScriptRoot -Filter '*.json' | Copy-Item -Destination $InstallDirectory -Force

$settingsDirectory = Join-Path $env:ProgramData 'LRM\RemoteDsk'; New-Item -ItemType Directory -Force -Path $settingsDirectory | Out-Null
$serverUrl = [UriBuilder]::new($(if ($Server -match '^https?://') { $Server } else { "https://$Server" })); $serverUrl.Port = $ApiPort
$settings = @{ ServerUrl = $serverUrl.Uri.ToString().TrimEnd('/'); RelayPort = $RelayPort; ProtectedApplicationKey = Protect-MachineValue $ApplicationKey; UnattendedEnabled = -not [string]::IsNullOrEmpty($UnattendedPassword); PasswordHash = Hash-Password $UnattendedPassword }
$settings | ConvertTo-Json -Depth 4 | Set-Content -LiteralPath (Join-Path $settingsDirectory 'client-service.settings.json') -Encoding UTF8

$installedService = Join-Path $InstallDirectory 'LRM-REMOTE-DSK-Client.exe'
$serviceCommand = "`"$installedService`" --service"
if (-not $service) { & sc.exe create $ServiceName binPath= $serviceCommand start= auto DisplayName= 'LRM REMOTE DSK Client' | Out-Null }
else { & sc.exe config $ServiceName binPath= $serviceCommand start= auto DisplayName= 'LRM REMOTE DSK Client' | Out-Null }
& sc.exe failure $ServiceName reset= 86400 actions= restart/5000/restart/15000/restart/60000 | Out-Null
Start-Service -Name $ServiceName
$shortcutPath = Join-Path $env:ProgramData 'Microsoft\Windows\Start Menu\Programs\LRM REMOTE DSK.lnk'
$shell = New-Object -ComObject WScript.Shell; $shortcut = $shell.CreateShortcut($shortcutPath); $shortcut.TargetPath = Join-Path $InstallDirectory 'LRM-REMOTE-DSK-Client.exe'; $shortcut.WorkingDirectory = $InstallDirectory; $shortcut.Save()
if (-not $Silent) { Write-Host 'LRM REMOTE DSK unified Client installed as application and service.' -ForegroundColor Green }
