<#
.SYNOPSIS
    Zentrales Entwicklungsskript für die Krisenvorrat Android-App.

.DESCRIPTION
    Handhabt Build, Deploy und Emulator-Operationen.
    Behandelt bekannte Komplikationen (OneDrive-Locks, Boot-Delays, stderr-Warnungen).

.PARAMETER Action
    Die auszuführende Aktion:
      build           - Debug-APK bauen
      clean           - Build-Verzeichnisse löschen
      clean-build     - Clean + Build in einem Schritt
      emulator-start  - Emulator starten und auf Boot warten
      emulator-stop   - Emulator beenden
      install-emulator - APK auf Emulator installieren
      install-device   - APK auf physisches Gerät installieren
      launch          - App starten (auf dem aktiven Ziel)
      deploy-emulator - Build + Install + Launch auf Emulator
      deploy-device   - Build + Install + Launch auf physisches Gerät
      logcat          - App-Logcat anzeigen (Ctrl+C zum Beenden)
      devices         - Verbundene Geräte auflisten
      screenshot      - Screenshot vom aktiven Gerät speichern

.PARAMETER Target
    Zielgerät: 'emulator' (Standard) oder 'device'.

.EXAMPLE
    & ".github/skills/android-build/android-dev.ps1" -Action build
    & ".github/skills/android-build/android-dev.ps1" -Action deploy-emulator
    & ".github/skills/android-build/android-dev.ps1" -Action logcat -Target device
#>
param(
    [Parameter(Mandatory)]
    [ValidateSet(
        'build', 'clean', 'clean-build',
        'emulator-start', 'emulator-stop',
        'install-emulator', 'install-device',
        'launch',
        'deploy-emulator', 'deploy-device',
        'logcat', 'devices', 'screenshot'
    )]
    [string]$Action,

    [ValidateSet('emulator', 'device')]
    [string]$Target = 'emulator'
)

$ErrorActionPreference = 'Stop'

# --- Konfiguration ---
$SDK_ROOT = "C:\Users\JensR\AppData\Local\Android\Sdk"
$ADB = "$SDK_ROOT\platform-tools\adb.exe"
$EMULATOR = "$SDK_ROOT\emulator\emulator.exe"
$PROJECT_DIR = $PSScriptRoot | Split-Path | Split-Path | Split-Path  # .github/skills/android-build → repo root
$APK_PATH = "$PROJECT_DIR\app\build\outputs\apk\debug\app-debug.apk"
$AVD_NAME = "S24Ultra_API35"
$PACKAGE = "de.krisenvorrat.app"
$ACTIVITY = "$PACKAGE/.MainActivity"
$BOOT_TIMEOUT = 300  # Sekunden (erster Boot eines neuen AVD kann >2min dauern)
$INSTALL_RETRY = 3

$env:ANDROID_HOME = $SDK_ROOT

# --- Hilfsfunktionen ---
function Write-Step { param([string]$msg) Write-Host ">> $msg" -ForegroundColor Cyan }
function Write-Ok { param([string]$msg) Write-Host "OK $msg" -ForegroundColor Green }
function Write-Err { param([string]$msg) Write-Host "ERR $msg" -ForegroundColor Red }
function Write-Warn { param([string]$msg) Write-Host "WARN $msg" -ForegroundColor Yellow }

function Get-AdbTarget {
    if ($Target -eq 'device') { return '-d' }
    return '-e'
}

function Test-DeviceConnected {
    param([string]$type)
    $flag = if ($type -eq 'device') { '-d' } else { '-e' }
    try {
        $result = & $ADB $flag get-state 2>&1 | Out-String
        return ($result.Trim() -eq 'device')
    }
    catch {
        return $false
    }
}

function Invoke-Gradle {
    param([string[]]$Tasks)

    Write-Step "Gradle: $($Tasks -join ' ')"
    Push-Location $PROJECT_DIR
    try {
        $output = & .\gradlew.bat @Tasks 2>&1 | Out-String
        $success = $output -match 'BUILD SUCCESSFUL'
        $failed = $output -match 'BUILD FAILED'

        if ($success) {
            $duration = if ($output -match 'in (\d+[ms]\s?\d*\w*)') { $Matches[0] } else { '' }
            Write-Ok "BUILD SUCCESSFUL $duration"
            return $true
        }
        elseif ($failed) {
            # Fehlerdetails extrahieren
            $errorBlock = ($output -split "`n" | Select-String -Pattern "What went wrong|ERROR:|FAILURE:" -Context 0, 5) -join "`n"
            Write-Err "BUILD FAILED"
            Write-Host $errorBlock -ForegroundColor Red
            return $false
        }
        else {
            Write-Warn "Build-Status unklar. Output prüfen:"
            Write-Host ($output | Select-Object -Last 20)
            return $false
        }
    }
    finally {
        Pop-Location
    }
}

function Remove-BuildDirs {
    Write-Step "Build-Verzeichnisse löschen"
    $dirs = @("$PROJECT_DIR\app\build", "$PROJECT_DIR\build")
    foreach ($d in $dirs) {
        if (Test-Path $d) {
            Remove-Item $d -Recurse -Force -ErrorAction SilentlyContinue
            if (Test-Path $d) {
                Write-Warn "Konnte $d nicht vollständig löschen (OneDrive-Lock?). Versuche erneut..."
                Start-Sleep -Seconds 2
                Remove-Item $d -Recurse -Force -ErrorAction SilentlyContinue
            }
        }
    }
    Write-Ok "Build-Verzeichnisse bereinigt"
}

function Start-Emulator {
    # Prüfe ob Emulator bereits läuft
    if (Test-DeviceConnected 'emulator') {
        Write-Ok "Emulator läuft bereits"
        return $true
    }

    Write-Step "Emulator starten: $AVD_NAME"
    Start-Process -FilePath $EMULATOR -ArgumentList "-avd $AVD_NAME -gpu auto" -WindowStyle Normal
    Write-Step "Warte auf ADB-Verbindung..."
    & $ADB wait-for-device

    Write-Step "Warte auf Boot (max ${BOOT_TIMEOUT}s)..."
    $elapsed = 0
    do {
        Start-Sleep -Seconds 5
        $elapsed += 5
        $boot = (& $ADB -e shell getprop sys.boot_completed 2>$null | Out-String).Trim()
        if ($elapsed % 15 -eq 0) { Write-Host "  ... ${elapsed}s" -ForegroundColor DarkGray }
    } while ($boot -ne "1" -and $elapsed -lt $BOOT_TIMEOUT)

    if ($boot -ne "1") {
        Write-Err "Emulator-Boot Timeout nach ${BOOT_TIMEOUT}s"
        return $false
    }

    # Extra-Pause für PackageManager-Initialisierung
    Write-Step "Warte 5s auf PackageManager..."
    Start-Sleep -Seconds 5

    Write-Ok "Emulator gebootet nach ${elapsed} Sekunden"
    return $true
}

function Install-Apk {
    param([string]$targetType)

    if (-not (Test-Path $APK_PATH)) {
        Write-Err "APK nicht gefunden: $APK_PATH"
        Write-Err "Bitte zuerst bauen: -Action build"
        return $false
    }

    $flags = Get-AdbTarget
    $apkSize = [math]::Round((Get-Item $APK_PATH).Length / 1MB, 1)
    Write-Step "APK installieren ${apkSize} MB auf $targetType"

    for ($attempt = 1; $attempt -le $INSTALL_RETRY; $attempt++) {
        $result = & $ADB $flags install -r $APK_PATH 2>&1 | Out-String
        if ($result -match 'Success') {
            Write-Ok "APK installiert"
            return $true
        }
        if ($attempt -lt $INSTALL_RETRY) {
            Write-Warn "Install fehlgeschlagen (Versuch $attempt/$INSTALL_RETRY). Warte 5s..."
            Start-Sleep -Seconds 5
        }
    }

    Write-Err "APK-Installation fehlgeschlagen nach $INSTALL_RETRY Versuchen:"
    Write-Host $result -ForegroundColor Red
    return $false
}

function Start-App {
    $flags = Get-AdbTarget
    Write-Step "App starten: $ACTIVITY"
    $result = & $ADB $flags shell am start -n $ACTIVITY 2>&1 | Out-String
    if ($result -match 'Error|Exception') {
        Write-Err "App-Start fehlgeschlagen:"
        Write-Host $result -ForegroundColor Red
        return $false
    }
    Write-Ok "App gestartet"
    return $true
}

# --- Aktionen ---
switch ($Action) {

    'build' {
        $ok = Invoke-Gradle @('assembleDebug')
        if ($ok -and (Test-Path $APK_PATH)) {
            $size = [math]::Round((Get-Item $APK_PATH).Length / 1MB, 2)
            Write-Ok "APK: $APK_PATH - ${size} MB"
        }
        exit ([int](-not $ok))
    }

    'clean' {
        Remove-BuildDirs
        exit 0
    }

    'clean-build' {
        Remove-BuildDirs
        $ok = Invoke-Gradle @('assembleDebug')
        if ($ok -and (Test-Path $APK_PATH)) {
            $size = [math]::Round((Get-Item $APK_PATH).Length / 1MB, 2)
            Write-Ok "APK: $APK_PATH - ${size} MB"
        }
        exit ([int](-not $ok))
    }

    'emulator-start' {
        $ok = Start-Emulator
        exit ([int](-not $ok))
    }

    'emulator-stop' {
        Write-Step "Emulator beenden"
        & $ADB emu kill 2>$null
        Write-Ok "Emulator gestoppt"
        exit 0
    }

    'install-emulator' {
        $Target = 'emulator'
        if (-not (Test-DeviceConnected 'emulator')) {
            Write-Err "Kein Emulator verbunden. Starte mit: -Action emulator-start"
            exit 1
        }
        $ok = Install-Apk 'emulator'
        exit ([int](-not $ok))
    }

    'install-device' {
        $Target = 'device'
        if (-not (Test-DeviceConnected 'device')) {
            Write-Err "Kein physisches Gerät verbunden. USB-Debugging prüfen."
            exit 1
        }
        $ok = Install-Apk 'device'
        exit ([int](-not $ok))
    }

    'launch' {
        $ok = Start-App
        exit ([int](-not $ok))
    }

    'deploy-emulator' {
        $Target = 'emulator'
        $ok = Start-Emulator
        if (-not $ok) { exit 1 }

        $ok = Invoke-Gradle @('assembleDebug')
        if (-not $ok) { exit 1 }

        $ok = Install-Apk 'emulator'
        if (-not $ok) { exit 1 }

        $ok = Start-App
        exit ([int](-not $ok))
    }

    'deploy-device' {
        $Target = 'device'
        if (-not (Test-DeviceConnected 'device')) {
            Write-Err "Kein physisches Gerät verbunden."
            exit 1
        }

        $ok = Invoke-Gradle @('assembleDebug')
        if (-not $ok) { exit 1 }

        $ok = Install-Apk 'device'
        if (-not $ok) { exit 1 }

        $ok = Start-App
        exit ([int](-not $ok))
    }

    'logcat' {
        $flags = Get-AdbTarget
        Write-Step "Logcat für $PACKAGE (Ctrl+C zum Beenden)"
        $pid = & $ADB $flags shell pidof $PACKAGE 2>$null
        if ($pid) {
            & $ADB $flags logcat --pid=$pid -v time
        }
        else {
            Write-Warn "App läuft nicht. Zeige alle Logs mit Tag-Filter..."
            & $ADB $flags logcat -v time *:W
        }
    }

    'devices' {
        Write-Step "Verbundene Geräte"
        & $ADB devices -l
    }

    'screenshot' {
        $flags = Get-AdbTarget
        $tmpDir = "$PROJECT_DIR\tmp"
        if (-not (Test-Path $tmpDir)) { New-Item -ItemType Directory -Path $tmpDir -Force | Out-Null }
        $timestamp = Get-Date -Format "yyyyMMdd-HHmmss"
        $filename = "screenshot-$timestamp.png"
        Write-Step "Screenshot: $filename"
        $screenshotPath = "$tmpDir\$filename"
        & $ADB $flags shell screencap -p "/sdcard/$filename"
        $ErrorActionPreference = 'Continue'
        $pullResult = & $ADB $flags pull "/sdcard/$filename" $screenshotPath 2>&1 | Out-String
        & $ADB $flags shell rm "/sdcard/$filename" 2>&1 | Out-Null
        $ErrorActionPreference = 'Stop'
        if (Test-Path $screenshotPath) {
            Write-Ok "Gespeichert: tmp\$filename"
        }
        else {
            Write-Err "Screenshot fehlgeschlagen"
        }
    }
}
