param(
    [string]$ServerHost = "116.62.17.81",
    [int]$Port = 9444,
    [string]$Username = "wkc",
    [string]$Password = "wkc@0825",
    [string]$RemoteRoot = "/volume1/webapp/ccdi",
    [switch]$DryRun
)

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

$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$repoRoot = (Resolve-Path (Join-Path $scriptDir "..")).Path
$stageRoot = Join-Path $repoRoot ".deploy\\ccdi-package"

if ($DryRun) {
    Write-Host "[DryRun] 一键部署参数预览"
    Write-Host "Host: $ServerHost"
    Write-Host "Port: $Port"
    Write-Host "Username: $Username"
    Write-Host "RemoteRoot: $RemoteRoot"
    exit 0
}

function Ensure-Command {
    param([string]$CommandName)
    if (-not (Get-Command $CommandName -ErrorAction SilentlyContinue)) {
        throw "缺少命令: $CommandName"
    }
}

function Reset-Directory {
    param([string]$Path)
    if (Test-Path $Path) {
        Get-ChildItem -LiteralPath $Path -Recurse -Force -ErrorAction SilentlyContinue | ForEach-Object {
            $_.Attributes = $_.Attributes `
                -band (-bnot [System.IO.FileAttributes]::ReadOnly) `
                -band (-bnot [System.IO.FileAttributes]::Hidden) `
                -band (-bnot [System.IO.FileAttributes]::System)
        }
        $rootItem = Get-Item -LiteralPath $Path -Force
        $rootItem.Attributes = $rootItem.Attributes `
            -band (-bnot [System.IO.FileAttributes]::ReadOnly) `
            -band (-bnot [System.IO.FileAttributes]::Hidden) `
            -band (-bnot [System.IO.FileAttributes]::System)
        Remove-Item -LiteralPath $Path -Recurse -Force
    }
    New-Item -ItemType Directory -Path $Path | Out-Null
}

function Copy-ItemSafe {
    param(
        [string]$Source,
        [string]$Destination
    )
    Copy-Item -Path $Source -Destination $Destination -Recurse -Force
}

Write-Host "[1/5] 检查本地环境"
Ensure-Command "mvn"
Ensure-Command "npm"
Ensure-Command "python"

Write-Host "[2/5] 打包后端"
Push-Location $repoRoot
try {
    mvn clean package -DskipTests
    if ($LASTEXITCODE -ne 0) {
        throw "后端打包失败"
    }
} finally {
    Pop-Location
}

Write-Host "[3/5] 打包前端"
Push-Location (Join-Path $repoRoot "ruoyi-ui")
try {
    npm run build:prod
    if ($LASTEXITCODE -ne 0) {
        throw "前端打包失败"
    }
} finally {
    Pop-Location
}

Write-Host "[4/5] 组装部署目录"
Reset-Directory $stageRoot
New-Item -ItemType Directory -Path (Join-Path $stageRoot "backend") | Out-Null
New-Item -ItemType Directory -Path (Join-Path $stageRoot "frontend") | Out-Null

Copy-ItemSafe (Join-Path $repoRoot "docker") (Join-Path $stageRoot "docker")
Copy-ItemSafe (Join-Path $repoRoot "lsfx-mock-server") (Join-Path $stageRoot "lsfx-mock-server")
Copy-ItemSafe (Join-Path $repoRoot "ruoyi-ui\\dist") (Join-Path $stageRoot "frontend\\dist")
Copy-ItemSafe (Join-Path $repoRoot "docker-compose.yml") (Join-Path $stageRoot "docker-compose.yml")
Copy-ItemSafe (Join-Path $repoRoot ".env.example") (Join-Path $stageRoot ".env.example")
Copy-ItemSafe (Join-Path $repoRoot "ruoyi-admin\\target\\ruoyi-admin.jar") (Join-Path $stageRoot "backend\\ruoyi-admin.jar")
python (Join-Path $scriptDir "render_nas_env.py") `
    --template (Join-Path $repoRoot ".env.example") `
    --output (Join-Path $stageRoot ".env")
if ($LASTEXITCODE -ne 0) {
    throw "生成 NAS 部署 .env 失败"
}

Write-Host "[5/5] 上传并远端部署"
$paramikoCheck = @'
import importlib.util
import sys
sys.exit(0 if importlib.util.find_spec("paramiko") else 1)
'@
$paramikoCheck | python -
if ($LASTEXITCODE -ne 0) {
    python -m pip install --user paramiko
    if ($LASTEXITCODE -ne 0) {
        throw "安装 paramiko 失败"
    }
}

python (Join-Path $scriptDir "remote-deploy.py") `
    --host $ServerHost `
    --port $Port `
    --username $Username `
    --password $Password `
    --local-root $stageRoot `
    --remote-root $RemoteRoot

if ($LASTEXITCODE -ne 0) {
    throw "远端部署失败"
}
