#Requires -Version 5.1
<#
.SYNOPSIS
  Push bootstrap script to Hetzner and run first-time production install.
.PREREQUISITES
  1. Hetzner CPX31 (Ubuntu 24.04) with your SSH key
  2. Copy production.local.example.ps1 → production.local.ps1 and fill ServerIp
  3. Code on GitHub (main), OR use -UseLocalCode to upload from this PC
#>
param(
    [string]$ServerIp = "",
    [string]$Domain = "erp.cnpsolutions.co.bw",
    [string]$MarketingDomain = "cnpsolutions.co.bw",
    [string]$DbPassword = "",
    [string]$SshUser = "root",
    [string]$SshKeyPathOverride = "",
    [switch]$UseLocalCode,
    [switch]$Resume
)

$ErrorActionPreference = "Stop"
$RepoRoot = Split-Path (Split-Path $PSScriptRoot -Parent) -Parent
$LocalConfig = Join-Path $PSScriptRoot "production.local.ps1"

if (Test-Path $LocalConfig) {
    . $LocalConfig
    Write-Host "Loaded $LocalConfig" -ForegroundColor Gray
}
if ($SshKeyPathOverride) {
    $SshKeyPath = $SshKeyPathOverride
}

if (-not $ServerIp) {
    Write-Host "ERROR: Set ServerIp in deploy\hetzner\production.local.ps1" -ForegroundColor Red
    Write-Host "  Copy production.local.example.ps1 → production.local.ps1"
    exit 1
}
if (-not $DbPassword) {
    Write-Host "ERROR: Set DbPassword in production.local.ps1" -ForegroundColor Red
    exit 1
}

if (-not $SshKeyPath) {
    $defaultKey = Join-Path $env:USERPROFILE ".ssh\id_ed25519_hetzner"
    if (Test-Path $defaultKey) { $SshKeyPath = $defaultKey }
}
$sshArgs = @()
$scpArgs = @()
$sshKeepAlive = @(
    "-o", "ServerAliveInterval=30",
    "-o", "ServerAliveCountMax=120",
    "-o", "TCPKeepAlive=yes"
)
if ($SshKeyPath -and (Test-Path $SshKeyPath)) {
    $sshArgs = @("-i", $SshKeyPath, "-o", "IdentitiesOnly=yes") + $sshKeepAlive
    $scpArgs = @("-i", $SshKeyPath, "-o", "IdentitiesOnly=yes") + $sshKeepAlive
    Write-Host "Using SSH key: $SshKeyPath" -ForegroundColor Gray
} else {
    $sshArgs = $sshKeepAlive
    $scpArgs = $sshKeepAlive
}

$Bootstrap = Join-Path $PSScriptRoot "bootstrap-production.sh"
if (-not (Test-Path $Bootstrap)) {
    Write-Host "Missing bootstrap-production.sh" -ForegroundColor Red
    exit 1
}

Write-Host "`nCNPERP production bootstrap -> ${SshUser}@${ServerIp}" -ForegroundColor Cyan
Write-Host "Domain: $Domain$(if ($Resume) { ' (resume — skip apt, pip + services only)' })`n"

if ($SshKeyPath) {
    Write-Host "If your key has a passphrase, you will be prompted during SSH/SCP." -ForegroundColor Yellow
    Write-Host "Optional (type passphrase once): ssh-add `"$SshKeyPath`"`n" -ForegroundColor Gray
}

# Test SSH (no BatchMode - allows passphrase prompt for encrypted keys)
ssh @sshArgs -o ConnectTimeout=15 -o StrictHostKeyChecking=accept-new "${SshUser}@${ServerIp}" "echo SSH OK"
if ($LASTEXITCODE -ne 0) {
    Write-Host "SSH failed. Check:" -ForegroundColor Red
    Write-Host "  1. Server was created with your SSH key selected in Hetzner" -ForegroundColor Red
    Write-Host "  2. Manual test: ssh -i `"$SshKeyPath`" -o IdentitiesOnly=yes ${SshUser}@${ServerIp}" -ForegroundColor Red
    exit 1
}

# Upload bootstrap (+ optional resume helper)
scp @scpArgs $Bootstrap "${SshUser}@${ServerIp}:/tmp/cnperp-bootstrap.sh"
$ResumeScript = Join-Path $PSScriptRoot "resume-bootstrap.sh"
if ($Resume -and (Test-Path $ResumeScript)) {
    scp @scpArgs $ResumeScript "${SshUser}@${ServerIp}:/tmp/cnperp-resume.sh"
}
$InitSchema = Join-Path $PSScriptRoot "init-db-schema.sh"
if (Test-Path $InitSchema) {
    scp @scpArgs $InitSchema "${SshUser}@${ServerIp}:/tmp/cnperp-init-db-schema.sh"
}

$envExports = @(
    "export CNPERP_DOMAIN='$Domain'",
    "export CNPERP_MARKETING_DOMAIN='$MarketingDomain'",
    "export CNPERP_DB_PASSWORD='$DbPassword'"
)
if ($SecretKey) { $envExports += "export CNPERP_SECRET_KEY='$SecretKey'" }
if ($LicenseAdminSecret) { $envExports += "export CNPERP_LICENSE_ADMIN_SECRET='$LicenseAdminSecret'" }
if ($GitHubToken) { $envExports += "export GITHUB_TOKEN='$GitHubToken'" }

$extractCmd = ""
if ($UseLocalCode) {
    & (Join-Path $PSScriptRoot "_write-requirements-utf8.ps1")
    Write-Host "Packaging app from working tree (includes uncommitted files)..." -ForegroundColor Cyan
    $archive = Join-Path $env:TEMP "cnperp-deploy-$(Get-Date -Format 'yyyyMMddHHmmss').tar.gz"
    if (Test-Path $archive) { Remove-Item -Force $archive }
    $tarExcludes = @(
        ".git", ".venv", "venv", "venv_wsl", "__pycache__", "node_modules",
        ".cursor", "terminals", "agent-transcripts", "tmp", "uploads", "backups",
        "Cdevbackup", "Cdevcnperp-pythontest_custom_backups", "test_custom_backups",
        "app/static/receipts", "reports", "htmlcov", ".pytest_cache", ".tox",
        "*.pdf", "*.db", "*.sqlite", "*.sqlite3", "*.log", "*.backup",
        "CNP Solutions logo.jpg", "deploy/hetzner/production.local.ps1",
        "test_out.txt", "test_out2.txt", "test_out3.txt", "test_out4.txt",
        "test_out5.txt", "test_out6.txt", "test_out7.txt", "test_error.txt",
        "test_login_output.txt", "test_login_output2.txt", "tmp_process_list.txt"
    )
    $tarArgs = @("-czf", $archive, "-C", $RepoRoot)
    foreach ($ex in $tarExcludes) { $tarArgs += "--exclude=$ex" }
    $tarArgs += "."
    & tar @tarArgs
    if ($LASTEXITCODE -ne 0) {
        Write-Host "tar failed. Install tar (Windows 10+) or run from Git Bash." -ForegroundColor Red
        exit 1
    }
    $sizeMb = [math]::Round((Get-Item $archive).Length / 1MB, 1)
    Write-Host "Archive size: ${sizeMb} MB" -ForegroundColor Gray
    if ($sizeMb -gt 55) {
        Write-Host "ERROR: Archive is too large (${sizeMb} MB). Add tar excludes in Start-HetznerProduction.ps1." -ForegroundColor Red
        exit 1
    }
    scp @scpArgs $archive "${SshUser}@${ServerIp}:/tmp/cnperp-deploy.tar.gz"
    $ReqFile = Join-Path $RepoRoot "requirements.txt"
    scp @scpArgs $ReqFile "${SshUser}@${ServerIp}:/tmp/cnperp-requirements.txt"
    $RunMigrations = Join-Path $PSScriptRoot "run-migrations.sh"
    if (Test-Path $RunMigrations) {
        scp @scpArgs $RunMigrations "${SshUser}@${ServerIp}:/tmp/cnperp-run-migrations.sh"
    }
    $envExports += "export SKIP_GIT_CLONE=1"
    $extractAfterTar = @(
        'cp /tmp/cnperp-requirements.txt /opt/cnperp/requirements.txt'
        'mkdir -p /opt/cnperp/deploy/hetzner'
        'cp /tmp/cnperp-run-migrations.sh /opt/cnperp/deploy/hetzner/run-migrations.sh 2>/dev/null || true'
        'cp /tmp/cnperp-init-db-schema.sh /opt/cnperp/deploy/hetzner/init-db-schema.sh 2>/dev/null || true'
        'chmod +x /opt/cnperp/deploy/hetzner/run-migrations.sh /opt/cnperp/deploy/hetzner/init-db-schema.sh 2>/dev/null || true'
        'chown -R cnperp:cnperp /opt/cnperp'
    ) -join '; '
    $extractCmd = "rm -rf /opt/cnperp; mkdir -p /opt/cnperp; tar --warning=no-unknown-keyword -xzf /tmp/cnperp-deploy.tar.gz -C /opt/cnperp 2>/dev/null; $extractAfterTar"
}

$envLine = ($envExports -join "; ")

if ($extractCmd) {
    Write-Host "Extracting on server..." -ForegroundColor Cyan
    $prevEa = $ErrorActionPreference
    $ErrorActionPreference = "Continue"
    $extractOut = ssh @sshArgs "${SshUser}@${ServerIp}" "${envLine}; ${extractCmd}; echo EXTRACT_OK" 2>&1
    $ErrorActionPreference = $prevEa
    $extractOut | Where-Object { $_ -match 'tar:' -and $_ -notmatch 'Ignoring unknown' } | ForEach-Object { Write-Host $_ -ForegroundColor Yellow }
    if ($LASTEXITCODE -ne 0 -or ($extractOut -join "`n") -notmatch 'EXTRACT_OK') {
        Write-Host "Extract failed (SSH exit $LASTEXITCODE)." -ForegroundColor Red
        exit 1
    }
}

if ($Resume) {
    $envExports += "export SKIP_SYSTEM_SETUP=1"
    $envExports += "export SKIP_GIT_CLONE=1"
    $envExports += "export RESUME_PIP_ONLY=1"
    $envLine = ($envExports -join "; ")
}
Write-Host $(if ($Resume) { "Resuming bootstrap on server (pip + .env + services)..." } else { "Running bootstrap on server (pip install may take 10-15 minutes)..." }) -ForegroundColor Cyan
$bootstrapRunner = if ($Resume -and (Test-Path $ResumeScript)) {
    "sed -i 's/\r$//' /tmp/cnperp-bootstrap.sh /tmp/cnperp-resume.sh; bash /tmp/cnperp-resume.sh"
} else {
    "sed -i 's/\r$//' /tmp/cnperp-bootstrap.sh; bash /tmp/cnperp-bootstrap.sh"
}
$bootstrapCmd = "${envLine}; ${bootstrapRunner}"
$prevEa = $ErrorActionPreference
$ErrorActionPreference = "Continue"
ssh @sshArgs "${SshUser}@${ServerIp}" $bootstrapCmd 2>&1 | ForEach-Object { Write-Host $_ }
$bootExit = $LASTEXITCODE
$ErrorActionPreference = $prevEa
if ($bootExit -ne 0) {
    Write-Host "`nBootstrap failed or SSH disconnected (exit $bootExit)." -ForegroundColor Red
    Write-Host "Check on server: ssh root@${ServerIp} 'tail -80 /tmp/cnperp-bootstrap.log 2>/dev/null; journalctl -u cnperp -n 40 --no-pager'"
    exit 1
}

Write-Host "`nDone. Point DNS A record 'erp' for $Domain to $ServerIp" -ForegroundColor Green
Write-Host "  Landing: https://$Domain/" -ForegroundColor Green
Write-Host "  Setup:   https://$Domain/setup" -ForegroundColor Green
