# Vendoo 1.41.2 – grafischer Zero-Edit-Installationsassistent
$ErrorActionPreference = 'Stop'
$VendooDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$SetupScript = Join-Path $VendooDir 'setup.ps1'
$EnvFile = Join-Path $VendooDir '.env'
$EnvExample = Join-Path $VendooDir '.env.example'
$ModeFile = Join-Path $VendooDir '.vendoo-install-mode'

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
[System.Windows.Forms.Application]::EnableVisualStyles()

function Write-Utf8NoBom([string]$Path, [string]$Content) {
    $utf8 = New-Object System.Text.UTF8Encoding($false)
    [System.IO.File]::WriteAllText($Path, $Content, $utf8)
}

function Ensure-EnvFile {
    if (-not (Test-Path -LiteralPath $EnvFile)) {
        if (-not (Test-Path -LiteralPath $EnvExample)) { throw '.env.example fehlt.' }
        Copy-Item -LiteralPath $EnvExample -Destination $EnvFile
    }
}

function Get-EnvValue([string]$Key) {
    if (-not (Test-Path -LiteralPath $EnvFile)) { return '' }
    $line = Get-Content -LiteralPath $EnvFile | Where-Object { $_ -match ('^' + [regex]::Escape($Key) + '=') } | Select-Object -Last 1
    if (-not $line) { return '' }
    return ($line -replace ('^' + [regex]::Escape($Key) + '='), '').Trim()
}

function Set-EnvValue([string]$Key, [string]$Value) {
    if ($Value -match "[\r\n]") { throw "Ungültiger mehrzeiliger Wert für $Key." }
    Ensure-EnvFile
    $content = Get-Content -LiteralPath $EnvFile -Raw
    $escaped = [regex]::Escape($Key)
    if ($content -match "(?m)^$escaped=") {
        $content = [regex]::Replace($content, "(?m)^$escaped=.*$", "$Key=$Value")
    } else {
        $content = $content.TrimEnd() + "`r`n$Key=$Value`r`n"
    }
    Write-Utf8NoBom -Path $EnvFile -Content $content
}

function New-SecureToken {
    $bytes = New-Object byte[] 32
    $rng = [System.Security.Cryptography.RandomNumberGenerator]::Create()
    try { $rng.GetBytes($bytes) } finally { $rng.Dispose() }
    return (($bytes | ForEach-Object { $_.ToString('x2') }) -join '')
}

function Test-Port([string]$Text) {
    $port = 0
    return [int]::TryParse($Text, [ref]$port) -and $port -ge 1024 -and $port -le 65535
}

function Set-Configuration([string]$Target, [string]$Access, [int]$Port, [string]$PublicUrl, [bool]$FluxEnabled) {
    Ensure-EnvFile
    $token = Get-EnvValue 'VENDOO_SETUP_TOKEN'
    if ([string]::IsNullOrWhiteSpace($token)) {
        $token = New-SecureToken
        Set-EnvValue 'VENDOO_SETUP_TOKEN' $token
    }

    Set-EnvValue 'PORT' ([string]$Port)
    Set-EnvValue 'VENDOO_HOST_PORT' ([string]$Port)
    Set-EnvValue 'VENDOO_REQUIRE_SETUP_TOKEN' 'true'
    Set-EnvValue 'VENDOO_COOKIE_SAMESITE' 'lax'
    Set-EnvValue 'LOCAL_IMAGE_ENABLED' ($(if ($FluxEnabled) { 'true' } else { 'false' }))

    if ($Target -eq 'windows-local') {
        Set-EnvValue 'VENDOO_BIND_HOST' ($(if ($Access -eq 'LAN') { '0.0.0.0' } else { '127.0.0.1' }))
        Set-EnvValue 'VENDOO_PUBLISH_ADDRESS' '127.0.0.1'
        Set-EnvValue 'VENDOO_COOKIE_SECURE' 'auto'
        Set-EnvValue 'VENDOO_TRUST_PROXY' 'false'
        Set-EnvValue 'LOCAL_IMAGE_URL' 'http://127.0.0.1:8188'
    } else {
        Set-EnvValue 'VENDOO_BIND_HOST' '0.0.0.0'
        Set-EnvValue 'VENDOO_PUBLISH_ADDRESS' ($(if ($Access -eq 'LAN') { '0.0.0.0' } else { '127.0.0.1' }))
        Set-EnvValue 'VENDOO_COOKIE_SECURE' 'auto'
        Set-EnvValue 'VENDOO_TRUST_PROXY' 'false'
        Set-EnvValue 'LOCAL_IMAGE_URL' 'http://host.docker.internal:8188'
    }

    Set-EnvValue 'PUBLIC_BASE_URL' ($(if ([string]::IsNullOrWhiteSpace($PublicUrl)) { '' } else { $PublicUrl.Trim().TrimEnd('/') }))

    Write-Utf8NoBom -Path $ModeFile -Content ($Target + "`n")
    try { [System.Windows.Forms.Clipboard]::SetText($token) } catch {}
    return $token
}

$form = New-Object System.Windows.Forms.Form
$form.Text = 'Vendoo 1.41.2 – Installation'
$form.StartPosition = 'CenterScreen'
$form.Size = New-Object System.Drawing.Size(720, 620)
$form.MinimumSize = New-Object System.Drawing.Size(720, 620)
$form.Font = New-Object System.Drawing.Font('Segoe UI', 10)
$form.BackColor = [System.Drawing.Color]::FromArgb(246, 248, 247)

$title = New-Object System.Windows.Forms.Label
$title.Text = 'Vendoo installieren'
$title.Font = New-Object System.Drawing.Font('Segoe UI Semibold', 22)
$title.AutoSize = $true
$title.Location = New-Object System.Drawing.Point(34, 24)
$form.Controls.Add($title)

$sub = New-Object System.Windows.Forms.Label
$sub.Text = 'Alle Pflichtwerte werden geprüft und automatisch gespeichert. Es müssen keine Dateien bearbeitet werden.'
$sub.AutoSize = $false
$sub.Size = New-Object System.Drawing.Size(640, 48)
$sub.Location = New-Object System.Drawing.Point(38, 72)
$sub.ForeColor = [System.Drawing.Color]::FromArgb(70, 80, 76)
$form.Controls.Add($sub)

function Add-Label([string]$Text, [int]$Y) {
    $l = New-Object System.Windows.Forms.Label
    $l.Text = $Text
    $l.AutoSize = $true
    $l.Location = New-Object System.Drawing.Point(40, $Y)
    $form.Controls.Add($l)
    return $l
}

Add-Label 'Installationsart' 132 | Out-Null
$target = New-Object System.Windows.Forms.ComboBox
$target.DropDownStyle = 'DropDownList'
$target.Items.AddRange(@('Lokal auf diesem Windows-PC', 'Docker Desktop auf diesem Windows-PC'))
$target.SelectedIndex = 0
$target.Location = New-Object System.Drawing.Point(40, 158)
$target.Size = New-Object System.Drawing.Size(620, 34)
$form.Controls.Add($target)

Add-Label 'Erreichbarkeit' 208 | Out-Null
$access = New-Object System.Windows.Forms.ComboBox
$access.DropDownStyle = 'DropDownList'
$access.Items.AddRange(@('Nur auf diesem PC (empfohlen)', 'Im privaten LAN erreichbar'))
$access.SelectedIndex = 0
$access.Location = New-Object System.Drawing.Point(40, 234)
$access.Size = New-Object System.Drawing.Size(620, 34)
$form.Controls.Add($access)

Add-Label 'Port' 284 | Out-Null
$portBox = New-Object System.Windows.Forms.NumericUpDown
$portBox.Minimum = 1024
$portBox.Maximum = 65535
$portBox.Value = 8124
$portBox.Location = New-Object System.Drawing.Point(40, 310)
$portBox.Size = New-Object System.Drawing.Size(160, 34)
$form.Controls.Add($portBox)

Add-Label 'Öffentliche/LAN-Basisadresse (optional)' 358 | Out-Null
$publicUrl = New-Object System.Windows.Forms.TextBox
$publicUrl.Location = New-Object System.Drawing.Point(40, 384)
$publicUrl.Size = New-Object System.Drawing.Size(620, 34)
$form.Controls.Add($publicUrl)

$flux = New-Object System.Windows.Forms.CheckBox
$flux.Text = 'Lokales FLUX Studio aktivieren (ComfyUI bleibt ein getrennter Dienst)'
$flux.AutoSize = $true
$flux.Location = New-Object System.Drawing.Point(40, 438)
$form.Controls.Add($flux)

$hint = New-Object System.Windows.Forms.Label
$hint.Text = 'AI- und Marktplatz-Schlüssel werden später bequem unter Vendoo → Einstellungen eingetragen.'
$hint.AutoSize = $false
$hint.Size = New-Object System.Drawing.Size(620, 42)
$hint.Location = New-Object System.Drawing.Point(40, 474)
$hint.ForeColor = [System.Drawing.Color]::FromArgb(70, 80, 76)
$form.Controls.Add($hint)

$install = New-Object System.Windows.Forms.Button
$install.Text = 'Installieren'
$install.Size = New-Object System.Drawing.Size(180, 44)
$install.Location = New-Object System.Drawing.Point(480, 520)
$install.BackColor = [System.Drawing.Color]::FromArgb(32, 112, 78)
$install.ForeColor = [System.Drawing.Color]::White
$install.FlatStyle = 'Flat'
$form.Controls.Add($install)

$advanced = New-Object System.Windows.Forms.Button
$advanced.Text = 'Konsolenmenü'
$advanced.Size = New-Object System.Drawing.Size(150, 44)
$advanced.Location = New-Object System.Drawing.Point(40, 520)
$form.Controls.Add($advanced)

$cancel = New-Object System.Windows.Forms.Button
$cancel.Text = 'Abbrechen'
$cancel.Size = New-Object System.Drawing.Size(130, 44)
$cancel.Location = New-Object System.Drawing.Point(330, 520)
$form.Controls.Add($cancel)

$target.Add_SelectedIndexChanged({
    if ($target.SelectedIndex -eq 1) {
        $hint.Text = 'Docker Desktop muss gestartet sein. AI- und Marktplatz-Schlüssel werden später in Vendoo gepflegt.'
    } else {
        $hint.Text = 'AI- und Marktplatz-Schlüssel werden später bequem unter Vendoo → Einstellungen eingetragen.'
    }
})

$advanced.Add_Click({
    $form.Hide()
    Start-Process powershell.exe -ArgumentList @('-NoLogo','-NoProfile','-ExecutionPolicy','Bypass','-File',('"' + $SetupScript + '"'),'menu') -Wait
    $form.Close()
})

$cancel.Add_Click({ $form.Close() })

$install.Add_Click({
    try {
        $install.Enabled = $false
        $targetMode = if ($target.SelectedIndex -eq 1) { 'docker' } else { 'windows-local' }
        $accessMode = if ($access.SelectedIndex -eq 1) { 'LAN' } else { 'LOCAL' }
        $url = $publicUrl.Text.Trim()
        if ($url -and $url -notmatch '^https?://') { throw 'Die Basisadresse muss mit http:// oder https:// beginnen.' }
        if ($accessMode -eq 'LAN' -and [string]::IsNullOrWhiteSpace($url)) {
            $answer = [System.Windows.Forms.MessageBox]::Show('Für QR-Uploads ist später eine LAN-Adresse sinnvoll. Trotzdem ohne Basisadresse fortfahren?', 'LAN-Adresse fehlt', 'YesNo', 'Warning')
            if ($answer -ne 'Yes') { return }
        }
        $token = Set-Configuration -Target $targetMode -Access $accessMode -Port ([int]$portBox.Value) -PublicUrl $url -FluxEnabled $flux.Checked
        [System.Windows.Forms.MessageBox]::Show("Die Konfiguration ist gespeichert. Der Erst-Admin-Code wurde in die Zwischenablage kopiert.`r`n`r`n$token`r`n`r`nBewahre ihn bis zur ersten Anmeldung sicher auf.", 'Vendoo vorbereitet', 'OK', 'Information') | Out-Null
        $form.Hide()
        $command = if ($targetMode -eq 'docker') { 'install-docker' } else { 'install-local' }
        $proc = Start-Process powershell.exe -ArgumentList @('-NoLogo','-NoProfile','-ExecutionPolicy','Bypass','-File',('"' + $SetupScript + '"'),$command) -Wait -PassThru
        if ($proc.ExitCode -eq 0) {
            Start-Process ("http://127.0.0.1:{0}/login.html" -f [int]$portBox.Value)
        } else {
            [System.Windows.Forms.MessageBox]::Show("Die Installation wurde mit Exit-Code $($proc.ExitCode) beendet. Das Konsolenfenster enthält die Details.", 'Installation nicht abgeschlossen', 'OK', 'Error') | Out-Null
        }
        $form.Close()
    } catch {
        [System.Windows.Forms.MessageBox]::Show($_.Exception.Message, 'Eingabe prüfen', 'OK', 'Warning') | Out-Null
    } finally {
        $install.Enabled = $true
    }
})

[void]$form.ShowDialog()
