# Pyramid Release Script
# Usage: .\scripts\release.ps1
# Builds Windows + Android, creates Gitea release, uploads artifacts.

Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"

# Always run from the project root, regardless of where the script was called from.
Set-Location (Split-Path $PSScriptRoot -Parent)

# ── Config ────────────────────────────────────────────────────────────────────
$GiteaBase  = "http://192.168.178.71:3000"
$GiteaRepo  = "steggi/pyramid"
$GiteaToken = "bb522f9646c6856c9ab58bef0151ac36a9ce1d57"
$Headers    = @{ Authorization = "token $GiteaToken"; "Content-Type" = "application/json" }

# ── Read and Update version from pubspec.yaml ─────────────────────────────────
$pubspecPath = "pubspec.yaml"
$pubspecLines = @(Get-Content $pubspecPath)
$versionIndex = -1
for ($i = 0; $i -lt $pubspecLines.Count; $i++) {
    if ($pubspecLines[$i] -match "^version:") {
        $versionIndex = $i
        break
    }
}
if ($versionIndex -lt 0) { Write-Error "version not found in pubspec.yaml"; exit 1 }

$currentVersionFull = ($pubspecLines[$versionIndex] -split ":")[1].Trim()
$currentVersion = $currentVersionFull.Split("+")[0]
$currentBuild = 0
if ($currentVersionFull -match "\+") {
    $currentBuild = [int]$currentVersionFull.Split("+")[1]
}

$vParts = $currentVersion.Split(".")
$major = [int]$vParts[0]
$minor = [int]$vParts[1]
$patch = [int]$vParts[2]
$nextPatch = "$major.$minor.$($patch + 1)"
$nextBuild = $currentBuild + 1

Write-Host ""
Write-Host "  Aktuelle Version : $currentVersion (Build $currentBuild)" -ForegroundColor Cyan
$newVersionInput = Read-Host "  Neue Version eingeben (Leer lassen für $nextPatch)"
if ([string]::IsNullOrWhiteSpace($newVersionInput)) {
    $newVersion = $nextPatch
} else {
    $newVersion = $newVersionInput.Trim().TrimStart("v")
}

$newVersionFull = "$newVersion+$nextBuild"
if ($newVersionFull -ne $currentVersionFull) {
    $pubspecLines[$versionIndex] = "version: $newVersionFull"
    Set-Content -Path $pubspecPath -Value $pubspecLines
    Write-Host "  pubspec.yaml auf $newVersionFull aktualisiert." -ForegroundColor Green
}

$version = $newVersion
$tag     = "v$version"

Write-Host ""
Write-Host "  Pyramid Release Builder" -ForegroundColor Cyan
Write-Host "  Version : $tag" -ForegroundColor White
Write-Host ""

# ── Check for existing release ────────────────────────────────────────────────
try {
    $existing = Invoke-RestMethod "$GiteaBase/api/v1/repos/$GiteaRepo/releases/tags/$tag" `
        -Headers $Headers -Method Get -ErrorAction Stop
    Write-Host "  [!] Release $tag existiert bereits auf Gitea." -ForegroundColor Yellow
    $overwrite = Read-Host "  Überschreiben? (j/N)"
    if ($overwrite -notmatch "^[jJ]$") { Write-Host "  Abgebrochen."; exit 0 }
    # Delete existing release
    Invoke-RestMethod "$GiteaBase/api/v1/repos/$GiteaRepo/releases/$($existing.id)" `
        -Headers $Headers -Method Delete | Out-Null
    Write-Host "  Alter Release gelöscht." -ForegroundColor Gray
} catch {
    # 404 = release doesn't exist, that's fine
}

# ── Release notes ─────────────────────────────────────────────────────────────
Write-Host "  Release-Notizen (leer lassen = Changelog aus Git-Commits):" -ForegroundColor Cyan
$notes = Read-Host "  > "
if ([string]::IsNullOrWhiteSpace($notes)) {
    # Auto-generate from git log since last tag.
    # git describe exits non-zero when no tags exist; catch the error explicitly
    # because $ErrorActionPreference = "Stop" would otherwise abort the script.
    $lastTag = $null
    try { $lastTag = git describe --tags --abbrev=0 HEAD^ 2>$null } catch {}
    if ($lastTag) {
        $notes = git log "$lastTag..HEAD" --pretty=format:"- %s" 2>$null | Out-String
    } else {
        $notes = git log --pretty=format:"- %s" -20 2>$null | Out-String
    }
    Write-Host "  (Commits als Release-Notizen verwendet)" -ForegroundColor Gray
}

# ── Build Windows ─────────────────────────────────────────────────────────────
Write-Host ""
Write-Host "  [1/4] Windows Build..." -ForegroundColor Cyan
flutter build windows --release
if ($LASTEXITCODE -ne 0) { Write-Error "Windows build fehlgeschlagen"; exit 1 }

$winSrc = "build\windows\x64\runner\Release"
$winZip = "build\pyramid-windows-$tag.zip"
if (Test-Path $winZip) { Remove-Item $winZip -Force }
Compress-Archive -Path "$winSrc\*" -DestinationPath $winZip
Write-Host "  Windows ZIP: $winZip" -ForegroundColor Green

# ── Build Android ─────────────────────────────────────────────────────────────
Write-Host ""
Write-Host "  [2/4] Android Build (split per ABI)..." -ForegroundColor Cyan
flutter build apk --release --split-per-abi
if ($LASTEXITCODE -ne 0) { Write-Error "Android build fehlgeschlagen"; exit 1 }

# Order matters: arm64-v8a is uploaded first so app versions that still pick
# the first APK asset (pre-ABI-aware updater) get the variant that fits
# practically every real device.
$abiBuilds = @(
    @{ Abi = "arm64-v8a";   Desc = "64-bit ARM — praktisch jedes Smartphone der letzten ~8 Jahre. Im Zweifel diese Datei." },
    @{ Abi = "armeabi-v7a"; Desc = "32-bit ARM — sehr alte Geräte" },
    @{ Abi = "x86_64";      Desc = "Emulatoren / x86-Geräte" }
)
$apkFiles = @()
foreach ($b in $abiBuilds) {
    $abi = $b.Abi
    $src = "build\app\outputs\flutter-apk\app-$abi-release.apk"
    if (-not (Test-Path $src)) { Write-Error "APK fehlt: $src"; exit 1 }
    $dst = "build\pyramid-android-$abi-$tag.apk"
    Copy-Item $src $dst -Force
    $apkFiles += @{ Path = $dst; Name = "pyramid-android-$abi-$tag.apk"; Desc = $b.Desc }
    $sizeMb = [math]::Round((Get-Item $dst).Length / 1MB, 1)
    Write-Host "  Android APK ($abi, $sizeMb MB): $dst" -ForegroundColor Green
}

# Append a download guide to the release notes so every asset is explained.
$downloadGuide = "`n`n## Downloads`n`n| Datei | Für welches Gerät? |`n|---|---|`n"
foreach ($f in $apkFiles) {
    $downloadGuide += "| ``$($f.Name)`` | $($f.Desc) |`n"
}
$downloadGuide += "| ``pyramid-windows-$tag.zip`` | Windows 10/11 |`n"
$downloadGuide += "`n*Die App lädt beim automatischen Update selbst die passende Variante.*"
$notes = $notes.Trim() + $downloadGuide

# ── Git tag ───────────────────────────────────────────────────────────────────
Write-Host ""
Write-Host "  [3/4] Git Tag $tag..." -ForegroundColor Cyan
git tag -f $tag
# Token in die Push-URL einbetten, damit keine interaktive Passwort-Abfrage nötig ist
$pushUrl = $GiteaBase -replace "http://", "http://steggi:$GiteaToken@"
& git push "$pushUrl/steggi/pyramid.git" $tag --force
if ($LASTEXITCODE -ne 0) {
    Write-Host "  [!] Tag-Push fehlgeschlagen (Release wird trotzdem erstellt)." -ForegroundColor Yellow
} else {
    Write-Host "  Tag gepusht." -ForegroundColor Green
}

# ── Create Gitea release ──────────────────────────────────────────────────────
Write-Host ""
Write-Host "  [4/4] Gitea Release erstellen..." -ForegroundColor Cyan

$body = @{
    tag_name         = $tag
    name             = "Pyramid $tag"
    body             = $notes.Trim()
    draft            = $false
    prerelease       = $false
    target_commitish = "master"
} | ConvertTo-Json -Compress

$release = Invoke-RestMethod "$GiteaBase/api/v1/repos/$GiteaRepo/releases" `
    -Headers $Headers -Method Post -Body $body
$releaseId = $release.id
Write-Host "  Release ID: $releaseId" -ForegroundColor Gray

# ── Upload artifacts ──────────────────────────────────────────────────────────
function Upload-Asset($filePath, $fileName) {
    # curl.exe (built into Windows 10+) handles large binary uploads reliably.
    $uri = "$GiteaBase/api/v1/repos/$GiteaRepo/releases/$releaseId/assets?name=$fileName"
    $result = & curl.exe -s --fail -w "%{http_code}" `
        -X POST $uri `
        -H "Authorization: token $GiteaToken" `
        -F "attachment=@`"$filePath`""
    if ($LASTEXITCODE -ne 0) {
        Write-Error "Upload fehlgeschlagen ($result): $fileName"
    }
    Write-Host "  Hochgeladen: $fileName" -ForegroundColor Green
}

# APKs first (arm64-v8a leads — see comment at $abiBuilds), then Windows.
foreach ($f in $apkFiles) {
    Upload-Asset $f.Path $f.Name
}
Upload-Asset $winZip "pyramid-windows-$tag.zip"

# ── Done ──────────────────────────────────────────────────────────────────────
Write-Host ""
Write-Host "  Release $tag erfolgreich erstellt!" -ForegroundColor Green
Write-Host "  $GiteaBase/$GiteaRepo/releases/tag/$tag" -ForegroundColor Cyan
Write-Host ""
