#Requires -RunAsAdministrator
<#
.SYNOPSIS
    Run this on the DEVELOPMENT machine to create a deployment zip for a fresh server.
#>

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

$dotnet      = "C:\dotnet\dotnet.exe"
$projectDir  = "C:\velapanel.com\VelaPanel"
$publishDir  = "C:\velapanel.com\publish"
$setupDir    = "C:\velapanel.com\setup"
$outputRoot  = "C:\velapanel.com"

Write-Host ""
Write-Host "==================================================" -ForegroundColor Cyan
Write-Host "  VelaPanel Deployment Packager" -ForegroundColor Cyan
Write-Host "==================================================" -ForegroundColor Cyan
Write-Host ""

# Step 0: Stop any process locking the publish folder (VelaPanel.exe or dotnet hosting VelaPanel.dll)
Write-Host "[0/4] Stopping panel process if running..." -ForegroundColor Yellow
$stopped = $false

# Case 1: self-contained exe (production / target server)
$panelProc = Get-Process -Name "VelaPanel" -ErrorAction SilentlyContinue
if ($panelProc) {
    $panelProc | Stop-Process -Force
    $stopped = $true
}

# Case 2: dev machine — panel runs as "dotnet VelaPanel.dll"
$dotnetProcs = Get-Process -Name "dotnet" -ErrorAction SilentlyContinue | Where-Object {
    try { $_.Modules | Where-Object { $_.FileName -like "*$publishDir*" } } catch { $false }
}
if ($dotnetProcs) {
    $dotnetProcs | Stop-Process -Force
    $stopped = $true
}

if ($stopped) { Start-Sleep -Seconds 3; Write-Host "      Stopped." -ForegroundColor Green }
else { Write-Host "      Panel not running." -ForegroundColor Gray }

# Step 1: Rebuild
Write-Host "[1/4] Building self-contained release..." -ForegroundColor Yellow
& $dotnet publish $projectDir -c Release -o $publishDir --self-contained true -r win-x64 --nologo
if ($LASTEXITCODE -ne 0) { throw "Build failed. Fix errors above then retry." }
Write-Host "      Build successful." -ForegroundColor Green

# Step 2: Copy management scripts into the package so the server always ships with
#         the latest setup / update / rollback tooling — no manual copying needed.
Write-Host "[2/4] Copying management scripts..." -ForegroundColor Yellow

# 2a. Fresh-install scripts -> publish\setup\
$destSetup = Join-Path $publishDir "setup"
if (-not (Test-Path $destSetup)) { New-Item -ItemType Directory -Path $destSetup | Out-Null }
Copy-Item (Join-Path $setupDir "setup-server.ps1") $destSetup -Force
Copy-Item (Join-Path $setupDir "README-DEPLOY.md") $destSetup -Force

# 2b. Update / rollback scripts -> publish root (setup-server + deploy-update lift these
#     to C:\velapanel.com\ root so they run from the documented location and survive the
#     publish swap). build-and-deploy.ps1 is intentionally NOT shipped — prod never builds.
foreach ($s in @("deploy-update.ps1", "rollback-update.ps1")) {
    $src = Join-Path $outputRoot $s
    if (Test-Path $src) { Copy-Item $src $publishDir -Force }
    else { Write-Warning "  $s not found at $src — skipping." }
}

# 2c. tools\ folder (healthcheck.ps1, reset-panel-admin.ps1, ...) -> publish\tools\
$srcTools  = Join-Path $outputRoot "tools"
$destTools = Join-Path $publishDir "tools"
if (Test-Path $srcTools) {
    if (-not (Test-Path $destTools)) { New-Item -ItemType Directory -Path $destTools | Out-Null }
    Copy-Item (Join-Path $srcTools "*") $destTools -Recurse -Force
    Write-Host "      tools\ folder copied." -ForegroundColor Green
} else {
    Write-Warning "  tools\ folder not found at $srcTools — skipping."
}
Write-Host "      Management scripts copied (setup + update + rollback + tools)." -ForegroundColor Green

# Step 3: Sanitise appsettings.json
Write-Host "[3/4] Sanitising appsettings.json for distribution..." -ForegroundColor Yellow
$appSettings = Join-Path $publishDir "appsettings.json"
if (Test-Path $appSettings) {
    $json = Get-Content $appSettings -Raw | ConvertFrom-Json

    if ($null -ne $json.Seeding) {
        $json.Seeding.AdminPassword = "CHANGE-THIS-NOW-Admin1!"
    }
    if ($null -ne $json.Database) {
        $json.Database.MySqlConnectionString    = "server=localhost;user=root;password=;"
        $json.Database.MsSqlConnectionString    = "Server=localhost;Integrated Security=true;"
        $json.Database.PostgreSqlConnectionString = "Host=localhost;Port=5432;Database=postgres;Username=postgres;Password="
        $json.Database.MongoDbConnectionString  = "mongodb://localhost:27017"
    }
    if ($null -ne $json.Acme) {
        $json.Acme.AccountEmail = "admin@example.com"
    }

    $json | ConvertTo-Json -Depth 10 | Set-Content $appSettings -Encoding UTF8
    Write-Host "      appsettings.json sanitised." -ForegroundColor Green
} else {
    Write-Warning "appsettings.json not found in publish folder - skipping."
}

# Step 3b: Remove large installer folders that the Software Installer may have downloaded
Write-Host "[3b] Cleaning up installer cache from publish folder..." -ForegroundColor Yellow
$installerPatterns = @("SQLEXPR*", "mysql-installer*", "php-*-Win32*", "node-v*-x64*", "VC_redist*", "ndp*", "dotnet-hosting*")
foreach ($pattern in $installerPatterns) {
    Get-ChildItem -Path $publishDir -Filter $pattern -ErrorAction SilentlyContinue | ForEach-Object {
        Remove-Item $_.FullName -Recurse -Force
        Write-Host "      Removed: $($_.Name)" -ForegroundColor Gray
    }
}
Write-Host "      Installer cache cleaned." -ForegroundColor Green

# Step 4: Create zip — use .NET ZipFile directly (faster, no file-lock issues)
Write-Host "[4/4] Creating deployment zip..." -ForegroundColor Yellow
$timestamp = Get-Date -Format "yyyyMMdd-HHmm"
$zipPath   = Join-Path $outputRoot "VelaPanel-Deploy-$timestamp.zip"

if (Test-Path $zipPath) { Remove-Item $zipPath -Force }

Add-Type -Assembly "System.IO.Compression.FileSystem"
[System.IO.Compression.ZipFile]::CreateFromDirectory($publishDir, $zipPath,
    [System.IO.Compression.CompressionLevel]::Fastest, $false)

if (-not (Test-Path $zipPath)) { throw "Zip file was not created." }
$sizeMB = [math]::Round((Get-Item $zipPath).Length / 1MB, 1)
Write-Host "      Zip created: $zipPath ($sizeMB MB)" -ForegroundColor Green

# Restart local panel after packaging (dev machine uses C:\dotnet\dotnet.exe — .NET 8)
if ($stopped) {
    Write-Host "      Restarting local VelaPanel..." -ForegroundColor Gray
    Start-Process "C:\dotnet\dotnet.exe" -ArgumentList (Join-Path $publishDir "VelaPanel.dll") -WorkingDirectory $publishDir -WindowStyle Hidden
}

Write-Host ""
Write-Host "==================================================" -ForegroundColor Cyan
Write-Host "  DONE" -ForegroundColor Cyan
Write-Host "==================================================" -ForegroundColor Cyan
Write-Host ""
Write-Host "  File : $zipPath"
Write-Host "  Size : $sizeMB MB"
Write-Host ""
Write-Host "  On the fresh server:"
Write-Host "    1. Extract zip to C:\velapanel.com\publish\"
Write-Host "    2. PowerShell (Admin): .\setup\setup-server.ps1"
Write-Host ""
