#Requires -Version 5.1
# SilverMetal WinPE pre-config collector (WinForms UI). Runs in WinPE under the
# ADK WinPE-NetFx + WinPE-PowerShell optional components. ASCII body only (WinPE
# PowerShell 5.1 mis-parses smart quotes / em-dashes). On Finish it generates the
# answer file and launches legacy Setup; on Cancel / error it exits 1 so the
# wrapping Start-Collector.cmd falls back to the default autounattend.xml.

try {
    Add-Type -AssemblyName System.Windows.Forms, System.Drawing

    # Validation helpers + answer-file generator live next to this script under X:\sm\.
    . (Join-Path $PSScriptRoot 'Test-SmInput.ps1')
    . (Join-Path $PSScriptRoot 'New-SmAnswerFile.ps1')

    # --- palette ---------------------------------------------------------------
    $colBg     = [Drawing.Color]::FromArgb(18, 18, 22)
    $colPanel  = [Drawing.Color]::FromArgb(28, 28, 34)
    $colText   = [Drawing.Color]::FromArgb(232, 232, 238)
    $colMuted  = [Drawing.Color]::FromArgb(150, 150, 162)
    $colAccent = [Drawing.Color]::FromArgb(96, 200, 170)
    $colError  = [Drawing.Color]::FromArgb(236, 110, 110)
    $colField  = [Drawing.Color]::FromArgb(40, 40, 48)

    $fontBase  = New-Object Drawing.Font('Segoe UI', 11)
    $fontTitle = New-Object Drawing.Font('Segoe UI Semibold', 26, [Drawing.FontStyle]::Bold)
    $fontLabel = New-Object Drawing.Font('Segoe UI', 10)

    # --- form ------------------------------------------------------------------
    $form = New-Object Windows.Forms.Form
    $form.Text            = 'SilverMetal Setup'
    $form.WindowState     = 'Maximized'
    $form.FormBorderStyle = 'None'
    $form.BackColor       = $colBg
    $form.ForeColor       = $colText
    $form.Font            = $fontBase
    $form.KeyPreview      = $true

    # Helpers to build consistent controls.
    function New-Label([string]$text, [int]$x, [int]$y, [int]$w = 220) {
        $l = New-Object Windows.Forms.Label
        $l.Text = $text; $l.AutoSize = $false
        $l.Location = New-Object Drawing.Point($x, $y)
        $l.Size = New-Object Drawing.Size($w, 24)
        $l.ForeColor = $colMuted; $l.Font = $fontLabel
        $form.Controls.Add($l); $l
    }
    function New-Field([int]$x, [int]$y, [int]$w = 360, [bool]$mask = $false) {
        $t = New-Object Windows.Forms.TextBox
        $t.Location = New-Object Drawing.Point($x, $y)
        $t.Size = New-Object Drawing.Size($w, 28)
        $t.BackColor = $colField; $t.ForeColor = $colText
        $t.BorderStyle = 'FixedSingle'; $t.Font = $fontBase
        if ($mask) { $t.UseSystemPasswordChar = $true }
        $form.Controls.Add($t); $t
    }

    # Title + subtitle (left rail).
    $title = New-Object Windows.Forms.Label
    $title.Text = 'SilverMetal'
    $title.Font = $fontTitle; $title.ForeColor = $colAccent
    $title.AutoSize = $true
    $title.Location = New-Object Drawing.Point(80, 70)
    $form.Controls.Add($title)

    $subtitle = New-Object Windows.Forms.Label
    $subtitle.Text = 'Pre-install configuration. Set your account, machine and security options before Windows installs.'
    $subtitle.Font = $fontLabel; $subtitle.ForeColor = $colMuted
    $subtitle.AutoSize = $false
    $subtitle.Location = New-Object Drawing.Point(82, 120)
    $subtitle.Size = New-Object Drawing.Size(640, 24)
    $form.Controls.Add($subtitle)

    # --- left column fields ----------------------------------------------------
    $colX = 80; $fldX = 80; $y = 180; $rowH = 64

    New-Label 'Display name' $colX $y | Out-Null
    $txtDisplay = New-Field $fldX ($y + 26)
    $y += $rowH

    New-Label 'Username' $colX $y | Out-Null
    $txtUser = New-Field $fldX ($y + 26)
    $y += $rowH

    New-Label 'Password' $colX $y | Out-Null
    $txtPass = New-Field $fldX ($y + 26) 360 $true
    $y += $rowH

    New-Label 'Confirm password' $colX $y | Out-Null
    $txtPassC = New-Field $fldX ($y + 26) 360 $true
    $y += $rowH

    New-Label 'Computer name' $colX $y | Out-Null
    $txtComputer = New-Field $fldX ($y + 26)
    $y += $rowH

    # --- right column: flavour + BitLocker -------------------------------------
    $rX = 540; $rY = 180

    $grpFlavour = New-Object Windows.Forms.GroupBox
    $grpFlavour.Text = 'Flavour'
    $grpFlavour.ForeColor = $colMuted
    $grpFlavour.Location = New-Object Drawing.Point($rX, $rY)
    $grpFlavour.Size = New-Object Drawing.Size(360, 220)
    $form.Controls.Add($grpFlavour)

    # 'essentials' is the always-on baseline role (no flavour manifest), not a selectable
    # flavour -- the four below are the real flavours; essentials apps ship with every one.
    $flavours = @('developer', 'journalist', 'daily-driver', 'privacy-max')
    $radioFlavours = @()
    $fy = 32
    foreach ($f in $flavours) {
        $rb = New-Object Windows.Forms.RadioButton
        $rb.Text = $f; $rb.ForeColor = $colText; $rb.Font = $fontBase
        $rb.Location = New-Object Drawing.Point(20, $fy)
        $rb.Size = New-Object Drawing.Size(320, 28)
        $rb.Tag = $f
        if ($f -eq 'daily-driver') { $rb.Checked = $true }
        $grpFlavour.Controls.Add($rb)
        $radioFlavours += $rb
        $fy += 36
    }

    $chkBitLocker = New-Object Windows.Forms.CheckBox
    $chkBitLocker.Text = 'Enable BitLocker (TPM + PIN)'
    $chkBitLocker.ForeColor = $colText; $chkBitLocker.Font = $fontBase
    $chkBitLocker.AutoSize = $true
    $chkBitLocker.Location = New-Object Drawing.Point($rX, ($rY + 240))
    $form.Controls.Add($chkBitLocker)

    $lblPin = New-Label 'BitLocker PIN' $rX ($rY + 280) | Out-Null
    $lblPin = $form.Controls[$form.Controls.Count - 1]
    $txtPin = New-Field ($rX) ($rY + 306) 360 $true
    $lblPinC = New-Label 'Confirm PIN' $rX ($rY + 348) | Out-Null
    $lblPinC = $form.Controls[$form.Controls.Count - 1]
    $txtPinC = New-Field ($rX) ($rY + 374) 360 $true

    # PIN fields disabled until BitLocker is checked.
    $setPinEnabled = {
        $on = $chkBitLocker.Checked
        $txtPin.Enabled = $on; $txtPinC.Enabled = $on
        $fg = if ($on) { $colMuted } else { [Drawing.Color]::FromArgb(90, 90, 98) }
        $lblPin.ForeColor = $fg; $lblPinC.ForeColor = $fg
    }
    $chkBitLocker.Add_CheckedChanged($setPinEnabled)
    & $setPinEnabled

    # --- status line -----------------------------------------------------------
    $lblStatus = New-Object Windows.Forms.Label
    $lblStatus.Text = ''
    $lblStatus.ForeColor = $colError; $lblStatus.Font = $fontBase
    $lblStatus.AutoSize = $false
    $lblStatus.Location = New-Object Drawing.Point(80, ($y + 8))
    $lblStatus.Size = New-Object Drawing.Size(820, 28)
    $form.Controls.Add($lblStatus)

    # --- buttons ---------------------------------------------------------------
    function Style-Button($b, $primary) {
        $b.FlatStyle = 'Flat'; $b.Font = $fontBase
        $b.Size = New-Object Drawing.Size(150, 40)
        $b.FlatAppearance.BorderSize = 1
        if ($primary) {
            $b.BackColor = $colAccent; $b.ForeColor = $colBg
            $b.FlatAppearance.BorderColor = $colAccent
        } else {
            $b.BackColor = $colPanel; $b.ForeColor = $colText
            $b.FlatAppearance.BorderColor = $colMuted
        }
    }

    $btnDefaults = New-Object Windows.Forms.Button
    $btnDefaults.Text = 'Use defaults'
    Style-Button $btnDefaults $false
    $btnDefaults.Location = New-Object Drawing.Point(80, ($y + 48))
    $form.Controls.Add($btnDefaults)

    $btnCancel = New-Object Windows.Forms.Button
    $btnCancel.Text = 'Cancel'
    Style-Button $btnCancel $false
    $btnCancel.Location = New-Object Drawing.Point(580, ($y + 120))
    $form.Controls.Add($btnCancel)

    $btnFinish = New-Object Windows.Forms.Button
    $btnFinish.Text = 'Finish'
    Style-Button $btnFinish $true
    $btnFinish.Location = New-Object Drawing.Point(750, ($y + 120))
    $form.Controls.Add($btnFinish)

    # --- behaviour -------------------------------------------------------------
    $btnDefaults.Add_Click({
        $txtDisplay.Text  = 'SilverMetal User'
        $txtUser.Text     = 'silver'
        $txtComputer.Text = 'SILVER-PC'
        # Leave passwords blank on purpose: the user must set them.
        $txtPass.Text = ''; $txtPassC.Text = ''
        foreach ($rb in $radioFlavours) { $rb.Checked = ($rb.Tag -eq 'daily-driver') }
        $chkBitLocker.Checked = $false
        $txtPin.Text = ''; $txtPinC.Text = ''
        $lblStatus.ForeColor = $colMuted
        $lblStatus.Text = 'Defaults applied. Set a password to continue.'
    })

    $btnCancel.Add_Click({ [Environment]::Exit(1) })
    $form.Add_KeyDown({ if ($_.KeyCode -eq 'Escape') { [Environment]::Exit(1) } })

    $btnFinish.Add_Click({
        $lblStatus.ForeColor = $colError

        $rUser = Test-SmUsername $txtUser.Text
        if (-not $rUser.Ok) { $lblStatus.Text = $rUser.Message; return }

        $rPass = Test-SmPassword $txtPass.Text $txtPassC.Text
        if (-not $rPass.Ok) { $lblStatus.Text = $rPass.Message; return }

        $rComp = Test-SmComputerName $txtComputer.Text
        if (-not $rComp.Ok) { $lblStatus.Text = $rComp.Message; return }

        $blEnabled = $chkBitLocker.Checked
        $pin = ''
        if ($blEnabled) {
            $rPin = Test-SmPin $txtPin.Text $txtPinC.Text
            if (-not $rPin.Ok) { $lblStatus.Text = $rPin.Message; return }
            $pin = $txtPin.Text
        }

        $flavour = 'daily-driver'
        foreach ($rb in $radioFlavours) { if ($rb.Checked) { $flavour = [string]$rb.Tag } }

        $display = if ([string]::IsNullOrWhiteSpace($txtDisplay.Text)) { $txtUser.Text } else { $txtDisplay.Text }

        $lblStatus.ForeColor = $colAccent
        $lblStatus.Text = 'Generating answer file and starting Windows Setup...'
        $form.Refresh()

        $xml = New-SmAnswerFile -DisplayName $display -Username $txtUser.Text -Password $txtPass.Text `
            -ComputerName $txtComputer.Text -Flavour $flavour `
            -BitLockerEnable $blEnabled -BitLockerPin $pin

        Set-Content -Path 'X:\sm\unattend.generated.xml' -Value $xml -Encoding UTF8

        try { [void][xml](Get-Content 'X:\sm\unattend.generated.xml' -Raw) }
        catch { [Environment]::Exit(1) }   # bad XML -> fall back to default answer file

        $setup = if (Test-Path 'X:\sources\setup.exe') { 'X:\sources\setup.exe' } else { 'X:\setup.exe' }
        Start-Process -FilePath $setup -ArgumentList '/unattend:X:\sm\unattend.generated.xml' -Wait
        [Environment]::Exit(0)
    })

    [void]$form.ShowDialog()
    # If the form closes without Finish/Cancel handling exiting, treat as cancel.
    [Environment]::Exit(1)
}
catch {
    # Any failure (e.g. WinForms can't load in WinPE) -> log it where Start-Collector.cmd
    # can show it on the console, then exit 1 so the wrapper falls back to the default answer file.
    try { ($_ | Out-String) | Set-Content 'X:\sm\collector-error.txt' -Encoding ASCII } catch {}
    Write-Host ('Collector error: ' + ($_ | Out-String))
    [Environment]::Exit(1)
}
