<#
.SYNOPSIS
    ROA2WEB - Unified Starter Script for Windows (equivalent to start.sh)

.DESCRIPTION
    Orchestrates startup of all ROA2WEB services on Windows:
    1. SSH Tunnels (if needed for environment)
    2. Unified Backend (port 8000)
    3. Unified Frontend (port 3000) - optional for development

    This is the Windows equivalent of the Linux start.sh script.

.PARAMETER Environment
    Target environment: prod or test
    - prod: Uses SSH tunnel to Oracle
    - test: Direct connection (no tunnel needed)

.PARAMETER Action
    Action to perform: start or stop

.PARAMETER SkipFrontend
    Skip starting the frontend (useful for production where IIS serves static files)

.EXAMPLE
    .\start.ps1 prod
    Start all services in production mode

.EXAMPLE
    .\start.ps1 test
    Start all services in test mode

.EXAMPLE
    .\start.ps1 prod stop
    Stop all services

.NOTES
    Author: ROA2WEB Team
    Version: 1.0
#>

param(
    [Parameter(Position=0)]
    [ValidateSet("prod", "production", "test")]
    [string]$Environment = "prod",

    [Parameter(Position=1)]
    [ValidateSet("start", "stop")]
    [string]$Action = "start",

    [switch]$SkipFrontend
)

$ErrorActionPreference = "Stop"

# =============================================================================
# CONFIGURATION
# =============================================================================

$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path

# Normalize environment name
if ($Environment -eq "production") { $Environment = "prod" }

$Config = @{
    prod = @{
        Name = "PROD"
        EnvFile = ".env.prod"
        NeedsTunnel = $true
        LogDir = Join-Path $ScriptDir "logs"
    }
    test = @{
        Name = "TEST"
        EnvFile = ".env.test"
        NeedsTunnel = $false
        LogDir = $env:TEMP
    }
}

$Env = $Config[$Environment]
$BackendDir = Join-Path $ScriptDir "backend"
$BackendLog = Join-Path $Env.LogDir "backend-stderr.log"
$FrontendLog = Join-Path $Env.LogDir "frontend.log"
$VenvPath = Join-Path $BackendDir "venv"
$VenvPython = Join-Path $VenvPath "Scripts\python.exe"
$TunnelScript = Join-Path $ScriptDir "deployment\windows\scripts\ssh-tunnel.ps1"

# PID tracking files
$PidDir = Join-Path $env:TEMP "roa2web_pids"
if (-not (Test-Path $PidDir)) {
    New-Item -ItemType Directory -Path $PidDir -Force | Out-Null
}
$BackendPidFile = Join-Path $PidDir "backend.pid"
$FrontendPidFile = Join-Path $PidDir "frontend.pid"

# =============================================================================
# HELPER FUNCTIONS
# =============================================================================

function Write-Header {
    Write-Host ""
    Write-Host "============================================" -ForegroundColor Blue
    Write-Host "  ROA2WEB Unified Starter (Windows)" -ForegroundColor Blue
    Write-Host "  Environment: $($Env.Name)" -ForegroundColor Cyan
    Write-Host "============================================" -ForegroundColor Blue
    Write-Host ""
}

function Write-Step {
    param([string]$Message)
    Write-Host "[UNIFIED-$($Env.Name)] $Message" -ForegroundColor Cyan
}

function Write-Success {
    param([string]$Message)
    Write-Host "[SUCCESS] $Message" -ForegroundColor Green
}

function Write-Warning {
    param([string]$Message)
    Write-Host "[WARNING] $Message" -ForegroundColor Yellow
}

function Write-Error {
    param([string]$Message)
    Write-Host "[ERROR] $Message" -ForegroundColor Red
}

function Test-PortOpen {
    param([int]$Port)
    try {
        $tcpClient = New-Object System.Net.Sockets.TcpClient
        $tcpClient.Connect("127.0.0.1", $Port)
        $tcpClient.Close()
        return $true
    } catch {
        return $false
    }
}

function Stop-ProcessByPidFile {
    param([string]$PidFile, [string]$Name)

    if (Test-Path $PidFile) {
        $pid = Get-Content $PidFile -ErrorAction SilentlyContinue
        if ($pid) {
            $process = Get-Process -Id $pid -ErrorAction SilentlyContinue
            if ($process) {
                Write-Step "Stopping $Name (PID: $pid)..."
                Stop-Process -Id $pid -Force -ErrorAction SilentlyContinue
                Start-Sleep -Seconds 1
            }
        }
        Remove-Item $PidFile -Force -ErrorAction SilentlyContinue
    }
}

# =============================================================================
# STOP SERVICES
# =============================================================================

function Stop-AllServices {
    Write-Header
    Write-Step "Stopping all services..."
    Write-Host ""

    # Stop Backend
    Write-Step "1. Stopping Backend..."
    Stop-ProcessByPidFile $BackendPidFile "Backend"

    # Also kill any uvicorn processes
    Get-Process -Name "python" -ErrorAction SilentlyContinue |
        Where-Object { $_.CommandLine -like "*uvicorn*main:app*" } |
        ForEach-Object {
            Write-Step "  Killing uvicorn process (PID: $($_.Id))..."
            Stop-Process -Id $_.Id -Force -ErrorAction SilentlyContinue
        }

    if (Test-PortOpen 8000) {
        Write-Warning "Port 8000 still in use, force killing..."
        $netstat = netstat -ano | Select-String ":8000" | Select-String "LISTENING"
        if ($netstat) {
            $pid = ($netstat -split '\s+')[-1]
            Stop-Process -Id $pid -Force -ErrorAction SilentlyContinue
        }
    }

    # Stop Frontend
    Write-Step "2. Stopping Frontend..."
    Stop-ProcessByPidFile $FrontendPidFile "Frontend"

    Get-Process -Name "node" -ErrorAction SilentlyContinue |
        Where-Object { $_.CommandLine -like "*vite*" } |
        ForEach-Object {
            Write-Step "  Killing Vite process (PID: $($_.Id))..."
            Stop-Process -Id $_.Id -Force -ErrorAction SilentlyContinue
        }

    # Stop SSH Tunnels
    Write-Step "3. Stopping SSH Tunnels..."
    if (Test-Path $TunnelScript) {
        & $TunnelScript stop
    }

    Write-Host ""
    Write-Success "All services stopped."
    exit 0
}

# =============================================================================
# START SERVICES
# =============================================================================

function Start-AllServices {
    Write-Header
    Write-Step "Starting ROA2WEB Ultrathin Monolith..."
    Write-Host ""

    # Ensure log directory exists
    if (-not (Test-Path $Env.LogDir)) {
        New-Item -ItemType Directory -Path $Env.LogDir -Force | Out-Null
    }

    # -------------------------------------------------------------------------
    # Step 1: SSH Tunnels
    # -------------------------------------------------------------------------
    Write-Step "1. Checking SSH Tunnels..."

    if (Test-Path $TunnelScript) {
        if ($Env.NeedsTunnel) {
            & $TunnelScript start
            Write-Success "SSH Tunnels started"
            Start-Sleep -Seconds 2
        } else {
            Write-Success "$($Env.Name) uses direct connection - no tunnel needed"
        }
    } else {
        Write-Warning "SSH tunnel script not found: $TunnelScript"
    }

    # -------------------------------------------------------------------------
    # Step 2: Backend
    # -------------------------------------------------------------------------
    Write-Step "2. Starting Unified Backend on port 8000..."

    if (Test-PortOpen 8000) {
        Write-Warning "Port 8000 already in use - Backend may be running"
    } else {
        # Check venv exists
        if (-not (Test-Path $VenvPython)) {
            Write-Step "Creating Python virtual environment..."
            & python -m venv $VenvPath
        }

        # Check env file
        $envFilePath = Join-Path $BackendDir $Env.EnvFile
        if (-not (Test-Path $envFilePath)) {
            Write-Error "$($Env.EnvFile) not found at $envFilePath"
            exit 1
        }

        # Copy env file to active .env
        Write-Step "Using $($Env.Name) environment ($($Env.EnvFile))..."
        Copy-Item -Path $envFilePath -Destination (Join-Path $BackendDir ".env") -Force

        # Start backend
        Write-Step "Starting unified backend..."
        $backendProcess = Start-Process -FilePath $VenvPython `
            -ArgumentList "-m", "uvicorn", "main:app", "--host", "127.0.0.1", "--port", "8000", "--workers", "1" `
            -WorkingDirectory $BackendDir `
            -WindowStyle Hidden `
            -RedirectStandardError $BackendLog `
            -PassThru

        $backendProcess.Id | Out-File -FilePath $BackendPidFile -NoNewline

        # Wait for backend to start
        Write-Step "Waiting for Backend to initialize..."
        $maxWait = 45
        $elapsed = 0
        while ($elapsed -lt $maxWait) {
            if (Test-PortOpen 8000) {
                Write-Success "Unified Backend started on http://localhost:8000"
                break
            }
            Start-Sleep -Seconds 1
            $elapsed++
            if ($elapsed % 5 -eq 0) {
                Write-Step "  Still initializing... ($elapsed/${maxWait}s)"
            }
        }

        if (-not (Test-PortOpen 8000)) {
            Write-Error "Backend failed to start - check $BackendLog"
            Get-Content $BackendLog -Tail 30
            Stop-AllServices
        }
    }

    # -------------------------------------------------------------------------
    # Step 3: Frontend (optional)
    # -------------------------------------------------------------------------
    if (-not $SkipFrontend) {
        Write-Step "3. Starting Unified Frontend on port 3000..."

        if (Test-PortOpen 3000) {
            Write-Warning "Port 3000 already in use - Frontend may be running"
        } else {
            # Check node_modules
            $nodeModules = Join-Path $ScriptDir "node_modules"
            if (-not (Test-Path $nodeModules)) {
                Write-Step "Installing Frontend dependencies..."
                Push-Location $ScriptDir
                & npm install
                Pop-Location
            }

            # Start frontend
            Write-Step "Starting Vite development server..."
            $frontendProcess = Start-Process -FilePath "cmd.exe" `
                -ArgumentList "/c", "npm", "run", "dev" `
                -WorkingDirectory $ScriptDir `
                -WindowStyle Hidden `
                -RedirectStandardOutput $FrontendLog `
                -PassThru

            $frontendProcess.Id | Out-File -FilePath $FrontendPidFile -NoNewline

            # Wait for frontend
            Write-Step "Waiting for Vite to initialize..."
            $maxWait = 15
            $elapsed = 0
            while ($elapsed -lt $maxWait) {
                if (Test-PortOpen 3000) {
                    Write-Success "Unified Frontend started on http://localhost:3000"
                    break
                }
                Start-Sleep -Seconds 2
                $elapsed += 2
            }

            if (-not (Test-PortOpen 3000)) {
                Write-Error "Frontend failed to start - check $FrontendLog"
                Get-Content $FrontendLog
            }
        }
    } else {
        Write-Step "3. Skipping Frontend (use IIS for static files)"
    }

    # -------------------------------------------------------------------------
    # Summary
    # -------------------------------------------------------------------------
    Write-Host ""
    Write-Success "ROA2WEB Ultrathin Monolith ($($Env.Name)) is now running!"
    Write-Host ""
    Write-Host "Services:" -ForegroundColor Blue
    if ($Env.NeedsTunnel) {
        Write-Host "  * SSH Tunnel:          Active (Oracle DB connection)"
    } else {
        Write-Host "  * Oracle Connection:   Direct (no SSH tunnel needed)"
    }
    Write-Host "  * Unified Backend:     http://localhost:8000"
    Write-Host "    +-- Reports API:     http://localhost:8000/api/reports/*"
    Write-Host "    +-- Data Entry:      http://localhost:8000/api/data-entry/*"
    Write-Host "    +-- Telegram:        http://localhost:8000/api/telegram/*"
    if (-not $SkipFrontend) {
        Write-Host "  * Unified Frontend:    http://localhost:3000"
    }
    Write-Host ""
    Write-Host "API Documentation:" -ForegroundColor Blue
    Write-Host "  * API Docs:            http://localhost:8000/docs"
    Write-Host "  * Health Check:        http://localhost:8000/health"
    Write-Host ""
    Write-Host "Log Files:" -ForegroundColor Blue
    Write-Host "  * Backend:             $BackendLog"
    if (-not $SkipFrontend) {
        Write-Host "  * Frontend:            $FrontendLog"
    }
    Write-Host ""
    Write-Host "To stop services: .\start.ps1 $Environment stop" -ForegroundColor Yellow
    Write-Host ""
}

# =============================================================================
# MAIN
# =============================================================================

switch ($Action) {
    "start" { Start-AllServices }
    "stop"  { Stop-AllServices }
}
