#!/usr/bin/env pwsh
<#
.SYNOPSIS
    Interactive CNPERP application update
.DESCRIPTION
    Shows what will change, asks for confirmation, then pulls, updates
    dependencies, runs migrations, and restarts. Safe to run manually
    from any directory — all paths are resolved dynamically.
.PARAMETER Branch
    Branch to pull from (default: main)
.PARAMETER SkipBackup
    Skip pre-update database backup
.PARAMETER SkipRestart
    Don't restart the service after updating
.EXAMPLE
    .\update_app.ps1
    .\update_app.ps1 -Branch release/1.1 -SkipRestart
#>

param(
    [string]$Branch      = "main",
    [switch]$SkipBackup  = $false,
    [switch]$SkipRestart = $false
)

$ErrorActionPreference = "Stop"

# ── Dynamic paths ────────────────────────────────────────────────────────
$AppRoot       = Split-Path -Parent $PSScriptRoot
$VenvPy        = Join-Path $AppRoot ".venv\Scripts\python.exe"
$VersionFile   = Join-Path $AppRoot "version.txt"
$MigrationsDir = Join-Path $AppRoot "migrations"

Set-Location $AppRoot

function Get-Version { if (Test-Path $VersionFile) { (Get-Content $VersionFile -Raw).Trim() } else { "unknown" } }
function Write-Step  { param([string]$s) Write-Host "`n$s" -ForegroundColor Cyan }
function Write-OK    { param([string]$s) Write-Host "  OK  $s" -ForegroundColor Green }
function Write-Warn  { param([string]$s) Write-Host "  WARN  $s" -ForegroundColor Yellow }
function Write-Fail  { param([string]$s) Write-Host "  FAIL  $s" -ForegroundColor Red }

Write-Host "`n================================================" -ForegroundColor Cyan
Write-Host "  CNPERP Application Update" -ForegroundColor Cyan
Write-Host "  App    : $AppRoot" -ForegroundColor Gray
Write-Host "  Version: $(Get-Version)" -ForegroundColor Gray
Write-Host "  Branch : $Branch" -ForegroundColor Gray
Write-Host "================================================`n" -ForegroundColor Cyan

if (-not (Test-Path ".git")) {
    Write-Fail "Not a git repository at $AppRoot"
    exit 1
}

try {
    # ── Pre-update backup ────────────────────────────────────────────────
    if (-not $SkipBackup) {
        Write-Step "1/5  Creating pre-update backup..."
        try {
            & $VenvPy -c @"
from app.services.backup_service import BackupService
from app.core.database import SessionLocal
db = SessionLocal()
try:
    BackupService(db).create_backup('pre_update')
    print('  Backup created.')
finally:
    db.close()
"@
            Write-OK "Backup done."
        } catch { Write-Warn "Backup failed — continuing anyway." }
    }

    # ── Stash and fetch ──────────────────────────────────────────────────
    Write-Step "2/5  Fetching from origin/$Branch..."
    git stash push -m "Update stash $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" | Out-Null
    git fetch origin 2>&1 | Out-Null

    # ── Show pending commits ─────────────────────────────────────────────
    $pending = @(git log "HEAD..origin/$Branch" --oneline --no-color 2>&1 | Where-Object { $_ -match '\S' })
    if ($pending.Count -eq 0) {
        Write-OK "Already on latest — nothing to pull."
        exit 0
    }

    Write-Host "`n  $($pending.Count) commit(s) will be pulled:`n" -ForegroundColor Yellow
    $pending | ForEach-Object { Write-Host "    + $_" -ForegroundColor Gray }

    Write-Host "`n  Continue? [Y/N] " -ForegroundColor Yellow -NoNewline
    if ((Read-Host) -notmatch '^[Yy]') {
        Write-Warn "Cancelled by user."
        exit 0
    }

    # ── Pull ─────────────────────────────────────────────────────────────
    Write-Step "3/5  Pulling code..."
    $pull = git pull origin $Branch 2>&1
    if ($LASTEXITCODE -ne 0) { throw "git pull failed: $pull" }
    Write-OK "Code updated."

    # ── Dependencies ─────────────────────────────────────────────────────
    Write-Step "4/5  Updating Python dependencies..."
    & $VenvPy -m pip install -r (Join-Path $AppRoot "requirements.txt") --upgrade --quiet
    if ($LASTEXITCODE -ne 0) { throw "pip install failed" }
    Write-OK "Dependencies up to date."

    # ── Migrations ───────────────────────────────────────────────────────
    Write-Step "4b   Running pending migrations..."
    if (Test-Path $MigrationsDir) {
        $scripts = Get-ChildItem -Path $MigrationsDir -Filter "*.py" |
                   Where-Object { $_.Name -notmatch "^__" } | Sort-Object Name
        foreach ($s in $scripts) {
            Write-Host "  Running $($s.Name) ..." -NoNewline
            & $VenvPy $s.FullName 2>&1 | Out-Null
            if ($LASTEXITCODE -ne 0) { Write-Host " WARN" -ForegroundColor Yellow }
            else                      { Write-Host " OK"   -ForegroundColor Green  }
        }
    } else { Write-Warn "No migrations directory." }

    # ── Restart ──────────────────────────────────────────────────────────
    if (-not $SkipRestart) {
        Write-Step "5/5  Restarting application..."
        $svc = Get-Service -Name "CNPERP" -ErrorAction SilentlyContinue
        if ($svc) {
            Restart-Service -Name "CNPERP" -Force
            Start-Sleep -Seconds 3
            Write-OK "Service 'CNPERP' restarted. Status: $((Get-Service CNPERP).Status)"
        } else {
            Write-Warn "Windows service 'CNPERP' not found."
            Write-Host "  Restart manually:" -ForegroundColor Gray
            Write-Host "    uvicorn app.main:app --host 0.0.0.0 --port 8010" -ForegroundColor Gray
        }
    }

    # ── Summary ──────────────────────────────────────────────────────────
    Write-Host "`n================================================" -ForegroundColor Green
    Write-Host "  Update complete!" -ForegroundColor Green
    Write-Host "  Version : $(Get-Version)" -ForegroundColor Gray
    Write-Host "  Commit  : $(git log -1 --pretty=format:'%h — %s')" -ForegroundColor Gray
    Write-Host "================================================`n" -ForegroundColor Green

} catch {
    Write-Fail $_.Exception.Message
    Write-Host "`n  Rollback: git reset --hard HEAD@{1}" -ForegroundColor Yellow
    exit 1
}
