#Requires -Version 5.1
<#
.SYNOPSIS
    ERP dev environment startup script
.EXAMPLE
    .\dev.ps1              # Start backend + frontend
    .\dev.ps1 -Stop        # Stop all
    .\dev.ps1 -Restart     # Restart all
    .\dev.ps1 -Status      # Show port status
#>

param(
    [switch]$Stop,
    [switch]$Restart,
    [switch]$Status
)

$BackendPort  = 3000
$FrontendPort = 5174
$LogDir       = ".logs"

# --- environment variables ---
$env:ERP__DATABASE__URL            = "postgres://postgres:123123@localhost:5432/erp"
$env:ERP__JWT__SECRET              = "dev-secret-key-change-in-prod"
$env:ERP__AUTH__SUPER_ADMIN_PASSWORD = "Admin@2026"
$env:ERP__REDIS__URL               = "redis://localhost:6379"
$env:ERP__WECHAT__APPID            = "wx20f4ef9cc2ec66c5"
$env:ERP__WECHAT__SECRET           = "52679a563af519590e882c4b8d846f7b"
$env:ERP__WECHAT__DEV_MODE          = "false"
$env:ERP__HEALTH__AES_KEY          = "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2"
$env:ERP__HEALTH__HMAC_KEY         = "f6e5d4c3b2a1f6e5d4c3b2a1f6e5d4c3b2a1f6e5d4c3b2a1f6e5d4c3b2a1f6e5"
$env:ERP__RATE_LIMIT__FAIL_CLOSE   = "false"

# --- find PID using port ---
function Find-PortPid([int]$Port) {
    try {
        $c = Get-NetTCPConnection -LocalPort $Port -State Listen -ErrorAction Stop
        return $c[0].OwningProcess
    } catch { return $null }
}

# --- kill process on port ---
function Stop-PortProcess([int]$Port, [string]$Label) {
    $procId = Find-PortPid $Port
    if ($null -ne $procId) {
        try { $pName = (Get-Process -Id $procId -ErrorAction SilentlyContinue).ProcessName } catch { $pName = "?" }
        Write-Host ("  {0,-10} port {1} used by PID {2} ({3}), killing..." -f $Label,$Port,$procId,$pName) -ForegroundColor Yellow -NoNewline
        try {
            Stop-Process -Id $procId -Force -ErrorAction Stop
            $w = 0
            while (($w -lt 5) -and (Find-PortPid $Port)) { Start-Sleep -Seconds 1; $w++ }
            if (Find-PortPid $Port) { Write-Host " still in use" -ForegroundColor Red }
            else { Write-Host " done" -ForegroundColor Green }
        } catch { Write-Host " failed" -ForegroundColor Red }
    } else {
        Write-Host ("  {0,-10} port {1} free" -f $Label,$Port) -ForegroundColor Green
    }
}

# --- wait for port ---
function Wait-PortReady([int]$Port, [int]$TimeoutSeconds = 60) {
    $sw = [System.Diagnostics.Stopwatch]::StartNew()
    while ($sw.ElapsedMilliseconds -lt ($TimeoutSeconds * 1000)) {
        if (Find-PortPid $Port) { return $true }
        Start-Sleep -Milliseconds 500
    }
    return $false
}

# --- stop all ---
function Stop-Services {
    Write-Host ""
    Write-Host "Stopping..." -ForegroundColor Cyan
    Write-Host "--------------------------------------------------" -ForegroundColor DarkGray

    foreach ($svc in @("backend","frontend")) {
        $pidFile = Join-Path $LogDir "$svc.pid"
        if (Test-Path $pidFile) {
            $svcId = Get-Content $pidFile -ErrorAction SilentlyContinue
            if ($svcId -and (Get-Process -Id $svcId -ErrorAction SilentlyContinue)) {
                $label = if ($svc -eq "backend") { "Backend" } else { "Frontend" }
                Write-Host "  Stopping $label (PID $svcId)..." -ForegroundColor Cyan -NoNewline
                Stop-Process -Id $svcId -Force -ErrorAction SilentlyContinue
                Write-Host " done" -ForegroundColor Green
            }
            Remove-Item $pidFile -Force -ErrorAction SilentlyContinue
        }
    }
    Stop-PortProcess $BackendPort  "Backend"
    Stop-PortProcess $FrontendPort "Frontend"
    Write-Host ""
    Write-Host "Stopped." -ForegroundColor Green
}

# --- show status ---
function Show-Status {
    Write-Host ""
    Write-Host "Status:" -ForegroundColor Cyan
    Write-Host "--------------------------------------------------" -ForegroundColor DarkGray

    $bp = Find-PortPid $BackendPort
    if ($null -ne $bp) {
        Write-Host "  " -NoNewline; Write-Host "+" -ForegroundColor Green -NoNewline
        Write-Host " Backend  port $BackendPort  PID $bp"
        Write-Host "    http://localhost:$BackendPort/api/v1/health" -ForegroundColor Cyan
    } else {
        Write-Host "  " -NoNewline; Write-Host "-" -ForegroundColor Red -NoNewline
        Write-Host " Backend  port $BackendPort  stopped"
    }

    $fp = Find-PortPid $FrontendPort
    if ($null -ne $fp) {
        Write-Host "  " -NoNewline; Write-Host "+" -ForegroundColor Green -NoNewline
        Write-Host " Frontend port $FrontendPort  PID $fp"
        Write-Host "    http://localhost:$FrontendPort" -ForegroundColor Cyan
    } else {
        Write-Host "  " -NoNewline; Write-Host "-" -ForegroundColor Red -NoNewline
        Write-Host " Frontend port $FrontendPort  stopped"
    }
    Write-Host ""
}

# --- start all ---
function Start-Services {
    New-Item -ItemType Directory -Path $LogDir -Force | Out-Null

    Write-Host ""
    Write-Host "==================================================" -ForegroundColor Cyan
    Write-Host "       ERP Dev Environment Startup" -ForegroundColor Cyan
    Write-Host "==================================================" -ForegroundColor Cyan
    Write-Host ""

    # 1. clean ports (包括 Vite 可能递增到的所有端口)
    Write-Host "[1/3] Checking ports..." -ForegroundColor Cyan
    Write-Host "--------------------------------------------------" -ForegroundColor DarkGray
    Stop-PortProcess $BackendPort  "Backend"
    # 清理所有可能的 Vite 端口 (5174-5189)
    foreach ($p in ($FrontendPort..($FrontendPort + 15))) {
        Stop-PortProcess $p "Vite:$p"
    }
    Write-Host ""

    # 2. backend
    Write-Host "[2/3] Starting backend (Axum :$BackendPort)..." -ForegroundColor Cyan
    Write-Host "--------------------------------------------------" -ForegroundColor DarkGray

    $backendLog = Join-Path $LogDir "backend.log"
    $backendErr = Join-Path $LogDir "backend.err"

    $backendDir = Join-Path $PSScriptRoot "crates\erp-server"
    $proc = Start-Process -FilePath "cargo" -ArgumentList "run","-p","erp-server" `
        -WorkingDirectory $backendDir `
        -RedirectStandardOutput $backendLog -RedirectStandardError $backendErr `
        -WindowStyle Hidden -PassThru

    Write-Host "  PID: $($proc.Id)  log: $backendLog" -ForegroundColor DarkGray
    Write-Host "  Compiling & starting..." -NoNewline

    if (Wait-PortReady $BackendPort 180) {
        Write-Host " ready" -ForegroundColor Green
    } else {
        Write-Host " timeout (check $backendLog)" -ForegroundColor Yellow
    }
    Write-Host ""

    # 3. frontend
    Write-Host "[3/3] Starting frontend (Vite :$FrontendPort)..." -ForegroundColor Cyan
    Write-Host "--------------------------------------------------" -ForegroundColor DarkGray

    $webDir = Join-Path $PSScriptRoot "apps\web"
    if (-not (Test-Path (Join-Path $webDir "node_modules"))) {
        Write-Host "  Installing deps..." -ForegroundColor Yellow
        Push-Location $webDir
        pnpm install 2>&1 | ForEach-Object { Write-Host "  $_" }
        Pop-Location
    }

    $frontendLog = Join-Path $LogDir "frontend.log"
    $frontendErr = Join-Path $LogDir "frontend.err"

    $proc = Start-Process -FilePath "cmd.exe" `
        -ArgumentList "/c","cd /d `"$webDir`" && pnpm dev -- --strictPort" `
        -RedirectStandardOutput $frontendLog -RedirectStandardError $frontendErr `
        -WindowStyle Hidden -PassThru

    Write-Host "  PID: $($proc.Id)  log: $frontendLog" -ForegroundColor DarkGray
    Write-Host "  Starting..." -NoNewline

    if (Wait-PortReady $FrontendPort 30) {
        Write-Host " ready" -ForegroundColor Green
    } else {
        Write-Host " timeout" -ForegroundColor Red
    }
    Write-Host ""

    # save PIDs (use port-based PID, not Start-Process PID which may be cmd.exe wrapper)
    $bp = Find-PortPid $BackendPort
    $fp = Find-PortPid $FrontendPort
    if ($bp) { $bp | Set-Content (Join-Path $LogDir "backend.pid") }
    if ($fp) { $fp | Set-Content (Join-Path $LogDir "frontend.pid") }

    # done
    Write-Host "==================================================" -ForegroundColor Green
    Write-Host "       All services started!" -ForegroundColor Green
    Write-Host "==================================================" -ForegroundColor Green
    Write-Host ""
    Write-Host "  Frontend:  http://localhost:$FrontendPort" -ForegroundColor Cyan
    Write-Host "  Backend:   http://localhost:$BackendPort/api/v1" -ForegroundColor Cyan
    Write-Host "  Health:    http://localhost:$BackendPort/api/v1/health" -ForegroundColor Cyan
    Write-Host ""
    Write-Host "  Stop:    .\dev.ps1 -Stop"    -ForegroundColor DarkGray
    Write-Host "  Restart: .\dev.ps1 -Restart" -ForegroundColor DarkGray
    Write-Host "  Status:  .\dev.ps1 -Status"  -ForegroundColor DarkGray
    Write-Host ""
}

# --- entry ---
if ($Stop) {
    Stop-Services
} elseif ($Restart) {
    Stop-Services; Start-Sleep -Seconds 1; Start-Services
} elseif ($Status) {
    Show-Status
} else {
    Start-Services
}
