param(
    [switch]$SelfTest
)

$ErrorActionPreference = "Stop"

$Root = Split-Path -Parent $MyInvocation.MyCommand.Path
$BatchExe = Join-Path $Root "dist\StratoLogBatch.exe"
$RunLog = Join-Path $Root "strato_batch_run.log"
$ReportTxt = Join-Path $Root "strato_batch_report.txt"
$ReportJson = Join-Path $Root "strato_batch_report.json"
$DiagnoseTxt = Join-Path $Root "strato_erkennung_pruefung.txt"
$DiagnoseCmd = Join-Path $Root "diagnose_starten.cmd"
$MorningCheck = Join-Path $Root "strato_morgenlauf_pruefung.txt"

function Show-StratoFailure {
    param(
        [string]$Title,
        [string]$Message
    )
    Add-Type -AssemblyName System.Windows.Forms
    Add-Type -AssemblyName System.Drawing

    $form = New-Object System.Windows.Forms.Form
    $form.Text = $Title
    $form.StartPosition = "CenterScreen"
    $form.Size = New-Object System.Drawing.Size(680, 560)
    $form.MinimumSize = New-Object System.Drawing.Size(520, 360)
    $form.TopMost = $true

    $icon = New-Object System.Windows.Forms.PictureBox
    $icon.Image = [System.Drawing.SystemIcons]::Error.ToBitmap()
    $icon.SizeMode = "CenterImage"
    $icon.Location = New-Object System.Drawing.Point(16, 18)
    $icon.Size = New-Object System.Drawing.Size(40, 40)
    $form.Controls.Add($icon)

    $intro = New-Object System.Windows.Forms.Label
    $intro.Text = "Der STRATO-Loglauf braucht Aufmerksamkeit. Der komplette Text kann kopiert werden."
    $intro.AutoSize = $false
    $intro.Location = New-Object System.Drawing.Point(66, 18)
    $intro.Size = New-Object System.Drawing.Size(580, 40)
    $intro.Anchor = [System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Left -bor [System.Windows.Forms.AnchorStyles]::Right
    $form.Controls.Add($intro)

    $textBox = New-Object System.Windows.Forms.TextBox
    $textBox.Multiline = $true
    $textBox.ReadOnly = $true
    $textBox.ScrollBars = "Both"
    $textBox.WordWrap = $false
    $textBox.Text = $Message
    $textBox.Location = New-Object System.Drawing.Point(16, 68)
    $textBox.Size = New-Object System.Drawing.Size(630, 390)
    $textBox.Anchor = [System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Bottom -bor [System.Windows.Forms.AnchorStyles]::Left -bor [System.Windows.Forms.AnchorStyles]::Right
    $form.Controls.Add($textBox)

    $copyButton = New-Object System.Windows.Forms.Button
    $copyButton.Text = "Text kopieren"
    $copyButton.Size = New-Object System.Drawing.Size(130, 32)
    $copyButton.Location = New-Object System.Drawing.Point(384, 474)
    $copyButton.Anchor = [System.Windows.Forms.AnchorStyles]::Bottom -bor [System.Windows.Forms.AnchorStyles]::Right
    $copyButton.Add_Click({
        try {
            [System.Windows.Forms.Clipboard]::SetText($Message)
            $copyButton.Text = "Kopiert"
        }
        catch {
            $textBox.SelectAll()
            $textBox.Copy()
            $copyButton.Text = "Markiert"
        }
    })
    $form.Controls.Add($copyButton)

    $okButton = New-Object System.Windows.Forms.Button
    $okButton.Text = "OK"
    $okButton.Size = New-Object System.Drawing.Size(90, 32)
    $okButton.Location = New-Object System.Drawing.Point(556, 474)
    $okButton.Anchor = [System.Windows.Forms.AnchorStyles]::Bottom -bor [System.Windows.Forms.AnchorStyles]::Right
    $okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
    $form.AcceptButton = $okButton
    $form.CancelButton = $okButton
    $form.Controls.Add($okButton)

    [void]$form.ShowDialog()
    $form.Dispose()
}

function Get-LastLines {
    param(
        [string]$Path,
        [int]$Count = 20
    )
    if (-not (Test-Path -LiteralPath $Path)) {
        return "(Datei nicht vorhanden: $Path)"
    }
    return (Get-Content -LiteralPath $Path -Tail $Count -ErrorAction SilentlyContinue) -join [Environment]::NewLine
}

function Get-SupportHint {
    return @(
        "Bitte pruefen oder weitergeben:",
        "Logdatei: $RunLog",
        "Morgenlauf-Pruefung: $MorningCheck",
        "Erkennungspruefung: $DiagnoseTxt",
        "Diagnose starten: $DiagnoseCmd"
    ) -join [Environment]::NewLine
}

try {
    if (-not (Test-Path -LiteralPath $BatchExe)) {
        throw "Batch-EXE nicht gefunden: $BatchExe"
    }

    if ($SelfTest) {
        "OK: $BatchExe"
        "OK: $Root"
        exit 0
    }

    $process = Start-Process `
        -FilePath $BatchExe `
        -WorkingDirectory $Root `
        -ArgumentList @("--root", $Root, "--scheduled-task") `
        -WindowStyle Hidden `
        -PassThru `
        -Wait

    $exitCode = [int]$process.ExitCode
    if ($exitCode -ne 0) {
        $details = Get-LastLines -Path $RunLog -Count 30
        Show-StratoFailure `
            -Title "STRATO Log Batch fehlgeschlagen" `
            -Message "Der STRATO-Loglauf wurde mit Exitcode $exitCode beendet.`n`n$(Get-SupportHint)`n`nLetzte Logzeilen aus strato_batch_run.log:`n$details"
        exit $exitCode
    }

    if (Test-Path -LiteralPath $ReportJson) {
        $report = Get-Content -LiteralPath $ReportJson -Raw | ConvertFrom-Json
        $errors = @($report | Where-Object { $_.status -eq "error" })
        if ($errors.Count -gt 0) {
            $summary = ($errors | ForEach-Object { "$($_.package): $($_.detail)" }) -join [Environment]::NewLine
            Show-StratoFailure `
                -Title "STRATO Log Batch mit Fehlern" `
                -Message "Der STRATO-Loglauf hat Fehler gemeldet:`n`n$summary`n`n$(Get-SupportHint)`n`nReport:`n$ReportTxt"
            exit 2
        }
    }

    exit 0
}
catch {
    $details = Get-LastLines -Path $RunLog -Count 20
    Show-StratoFailure `
        -Title "STRATO Log Batch konnte nicht starten" `
        -Message "$($_.Exception.Message)`n`n$(Get-SupportHint)`n`nLetzte Logzeilen aus strato_batch_run.log:`n$details"
    exit 1
}
