<#
.SYNOPSIS
    ROA2WEB - Interactive Build & Publish Console

.DESCRIPTION
    Build deployment packages locally and transfer to Windows Server:
    - Build locally (Frontend, Backend, Telegram Bot, or All)
    - Transfer via Windows Share (LAN) or SSH/SCP (remote)
    - Auto-detect best transfer method
    - Interactive menu or command-line operation
    - Server auto-deploys when new package detected

.PARAMETER NonInteractive
    Run in non-interactive mode with specific action

.PARAMETER Action
    Action to perform in non-interactive mode:
    - Build: Build and publish package
    - TestConnections: Test Windows Share and SSH connectivity
    - Configure: Edit configuration (interactive only)
    - ViewConfig: Display current configuration

.PARAMETER Component
    Component to build (All, Frontend, Backend)

.PARAMETER TransferMethod
    Transfer method (Auto, WindowsShare, SSH)

.PARAMETER ConfigFile
    Path to configuration file (default: deploy-config.json)

.EXAMPLE
    .\Publish-And-Deploy.ps1
    Launch interactive menu

.EXAMPLE
    .\Publish-And-Deploy.ps1 -NonInteractive -Action Build -Component All
    Build all components and publish (auto-detect transfer method)

.EXAMPLE
    .\Publish-And-Deploy.ps1 -NonInteractive -Action Build -Component Frontend -TransferMethod SSH
    Build frontend and publish via SSH

.EXAMPLE
    .\Publish-And-Deploy.ps1 -NonInteractive -Action Build -Component DataEntryApp
    Build Data Entry App (frontend + backend) and publish

.NOTES
    Author: ROA2WEB Team
    Version: 1.1 (Added Data Entry App support)
    Requires: PowerShell 5.1+, SSH key configured for remote access
#>

[CmdletBinding()]
param(
    [switch]$NonInteractive,

    [ValidateSet("Build", "TestConnections", "ViewConfig")]
    [string]$Action = "",

    [ValidateSet("All", "Frontend", "Backend")]
    [string]$Component = "",

    [ValidateSet("Auto", "WindowsShare", "SSH")]
    [string]$TransferMethod = "",

    [string]$ConfigFile = ""
)

$ErrorActionPreference = "Stop"

# =============================================================================
# CONFIGURATION LOADING
# =============================================================================

$script:ConfigFilePath = if ($ConfigFile) {
    $ConfigFile
} else {
    Join-Path $PSScriptRoot "deploy-config.json"
}

function Load-Configuration {
    Write-Host "`nLoading configuration from: $script:ConfigFilePath" -ForegroundColor Gray

    if (-not (Test-Path $script:ConfigFilePath)) {
        Write-Host "[ERROR] Configuration file not found: $script:ConfigFilePath" -ForegroundColor Red
        Write-Host "Creating default configuration..." -ForegroundColor Yellow

        $defaultConfig = @{
            server = @{
                host = "10.0.20.36"
                sshPort = 22122
                sshUser = "Administrator"
                sshKeyPath = "~/.ssh/roa2web_deploy"
                windowsShare = "\\10.0.20.36\ROA2WEB-Deploy"
                deployPath = "C:\ROA2WEB-Deploy"
            }
            build = @{
                defaultComponent = "All"
                outputPath = "../deploy-package"
            }
            transfer = @{
                defaultMethod = "Auto"
                scpRemotePath = "/cygdrive/c/ROA2WEB-Deploy"
                retryAttempts = 3
                timeout = 300
            }
            deployment = @{
                autoDeployEnabled = $true
                checkIntervalMinutes = 5
            }
        }

        $defaultConfig | ConvertTo-Json -Depth 10 | Set-Content -Path $script:ConfigFilePath
        Write-Host "Default configuration created. Please review and edit as needed." -ForegroundColor Green
    }

    try {
        $script:Config = Get-Content -Path $script:ConfigFilePath -Raw | ConvertFrom-Json
        Write-Host "[OK] Configuration loaded successfully" -ForegroundColor Green
        return $true
    } catch {
        Write-Host "[ERROR] Failed to load configuration: $_" -ForegroundColor Red
        return $false
    }
}

function Save-Configuration {
    try {
        $script:Config | ConvertTo-Json -Depth 10 | Set-Content -Path $script:ConfigFilePath
        Write-Host "[OK] Configuration saved successfully" -ForegroundColor Green
        return $true
    } catch {
        Write-Host "[ERROR] Failed to save configuration: $_" -ForegroundColor Red
        return $false
    }
}

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

function Write-Step {
    param([string]$Message)
    Write-Host "`n[*] $Message" -ForegroundColor Cyan
}

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

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

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

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

function Resolve-FullPath {
    param([string]$Path)

    # Resolve relative paths from the parent of the scripts directory
    # This matches the resolution logic in Build-ROA2WEB.ps1
    $scriptDir = Split-Path -Parent $PSScriptRoot
    $fullPath = Join-Path $scriptDir $Path
    $fullPath = [System.IO.Path]::GetFullPath($fullPath)

    return $fullPath
}

function Wait-ForKeyPress {
    Write-Host "`nPress any key to continue..." -ForegroundColor Gray
    $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}

# =============================================================================
# CONNECTION TESTING
# =============================================================================

function Test-WindowsShare {
    Write-Step "Testing Windows Share access..."

    $sharePath = $script:Config.server.windowsShare
    Write-Info "Share: $sharePath"

    try {
        if (Test-Path $sharePath) {
            Write-Success "Windows Share is accessible"

            # Try to write test file
            $testFile = Join-Path $sharePath ".test-$(Get-Date -Format 'yyyyMMddHHmmss')"
            "test" | Out-File -FilePath $testFile -Force

            if (Test-Path $testFile) {
                Remove-Item -Path $testFile -Force
                Write-Success "Write permissions verified"
                return $true
            } else {
                Write-Warning "Share is readable but write test failed"
                return $false
            }
        } else {
            Write-Error "Windows Share is not accessible"
            Write-Info "Ensure network share is configured and accessible"
            return $false
        }
    } catch {
        Write-Error "Failed to access Windows Share: $_"
        return $false
    }
}

function Test-SSHConnection {
    Write-Step "Testing SSH connection..."

    $serverHost = $script:Config.server.host
    $port = $script:Config.server.sshPort
    $user = $script:Config.server.sshUser
    $keyPath = $script:Config.server.sshKeyPath

    Write-Info "Host: ${serverHost}:${port}"
    Write-Info "User: $user"
    Write-Info "Key:  $keyPath"

    # Expand tilde in key path (support both Unix / and Windows \ styles)
    if ($keyPath -like "~/*" -or $keyPath -like "~\*") {
        $keyPath = $keyPath -replace "^~", $env:USERPROFILE
    }

    if (-not (Test-Path $keyPath)) {
        Write-Error "SSH key not found: $keyPath"
        return $false
    }

    try {
        # Test SSH connection
        $sshTest = ssh -i "$keyPath" -p $port -o ConnectTimeout=10 -o StrictHostKeyChecking=no "${user}@${serverHost}" "echo 'Connection successful'" 2>&1

        if ($LASTEXITCODE -eq 0 -and $sshTest -like "*Connection successful*") {
            Write-Success "SSH connection established"
            return $true
        } else {
            Write-Error "SSH connection failed"
            Write-Info "Output: $sshTest"
            return $false
        }
    } catch {
        Write-Error "Failed to test SSH connection: $_"
        return $false
    }
}

function Test-AllConnections {
    Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan
    Write-Host "  Connection Testing" -ForegroundColor Cyan
    Write-Host ("=" * 70) -ForegroundColor Cyan

    $shareOk = Test-WindowsShare
    $sshOk = Test-SSHConnection

    Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan
    Write-Host "  Test Results" -ForegroundColor Cyan
    Write-Host ("=" * 70) -ForegroundColor Cyan
    Write-Host "`n  Windows Share: " -NoNewline
    if ($shareOk) {
        Write-Host "[OK] Available" -ForegroundColor Green
    } else {
        Write-Host "[X] Not Available" -ForegroundColor Red
    }

    Write-Host "  SSH Connection: " -NoNewline
    if ($sshOk) {
        Write-Host "[OK] Available" -ForegroundColor Green
    } else {
        Write-Host "[X] Not Available" -ForegroundColor Red
    }

    Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan

    return @{
        WindowsShare = $shareOk
        SSH = $sshOk
    }
}

# =============================================================================
# BUILD & TRANSFER FUNCTIONS
# =============================================================================

function Invoke-Build {
    param(
        [Parameter(Mandatory)]
        [ValidateSet("All", "Frontend", "Backend")]
        [string]$Component
    )

    Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan
    Write-Host "  Building Component: $Component" -ForegroundColor Cyan
    Write-Host ("=" * 70) -ForegroundColor Cyan

    $buildScript = Join-Path $PSScriptRoot "Build-ROA2WEB.ps1"

    if (-not (Test-Path $buildScript)) {
        Write-Error "Build script not found: $buildScript"
        return $false
    }

    try {
        $outputPath = $script:Config.build.outputPath

        # Resolve the output path using the same logic as Build-ROA2WEB.ps1
        $resolvedOutputPath = if ([System.IO.Path]::IsPathRooted($outputPath)) {
            $outputPath
        } else {
            Resolve-FullPath -Path $outputPath
        }

        Write-Step "Building deployment package..."
        & $buildScript -Component $Component -OutputPath $outputPath

        if ($LASTEXITCODE -ne 0) {
            throw "Build script returned error code: $LASTEXITCODE"
        }

        if (-not (Test-Path $resolvedOutputPath)) {
            throw "Build output not found: $resolvedOutputPath"
        }

        Write-Success "Build completed successfully"
        return $true
    } catch {
        Write-Error "Build failed: $_"
        return $false
    }
}

function Copy-ViaWindowsShare {
    param([string]$SourcePath)

    Write-Step "Transferring via Windows Share..."

    $sharePath = $script:Config.server.windowsShare
    $timestamp = Get-Date -Format "yyyyMMdd-HHmmss"
    $deployFolder = "deploy-$timestamp"
    $destPath = Join-Path $sharePath $deployFolder

    try {
        Write-Info "Destination: $destPath"

        Copy-Item -Path $SourcePath -Destination $destPath -Recurse -Force

        if (Test-Path $destPath) {
            Write-Success "Files transferred successfully"
            Write-Success "Server will auto-deploy within $($script:Config.deployment.checkIntervalMinutes) minutes"
            return $true
        } else {
            Write-Error "Transfer failed - destination folder not found"
            return $false
        }
    } catch {
        Write-Error "Windows Share transfer failed: $_"
        return $false
    }
}

function Copy-ViaSSH {
    param([string]$SourcePath)

    Write-Step "Transferring via SSH/SCP..."

    $serverHost = $script:Config.server.host
    $port = $script:Config.server.sshPort
    $user = $script:Config.server.sshUser
    $keyPath = $script:Config.server.sshKeyPath
    $remotePath = $script:Config.transfer.scpRemotePath
    $timestamp = Get-Date -Format "yyyyMMdd-HHmmss"
    $deployFolder = "deploy-$timestamp"

    # Expand tilde in key path (support both Unix / and Windows \ styles)
    if ($keyPath -like "~/*" -or $keyPath -like "~\*") {
        $keyPath = $keyPath -replace "^~", $env:USERPROFILE
    }

    try {
        Write-Info "Host: ${serverHost}:${port}"
        Write-Info "Destination: ${remotePath}/${deployFolder}"

        # Create remote directory
        Write-Info "Creating remote directory..."
        $createDir = ssh -i "$keyPath" -p $port "${user}@${serverHost}" "mkdir -p '${remotePath}/${deployFolder}'" 2>&1

        if ($LASTEXITCODE -ne 0) {
            throw "Failed to create remote directory: $createDir"
        }

        # Transfer files via SCP
        Write-Info "Transferring files (this may take a few minutes)..."
        $scpResult = scp -i "$keyPath" -P $port -r "${SourcePath}/*" "${user}@${serverHost}:${remotePath}/${deployFolder}/" 2>&1

        if ($LASTEXITCODE -ne 0) {
            throw "SCP transfer failed: $scpResult"
        }

        Write-Success "Files transferred successfully"
        Write-Success "Server will auto-deploy within $($script:Config.deployment.checkIntervalMinutes) minutes"
        return $true
    } catch {
        Write-Error "SSH transfer failed: $_"
        return $false
    }
}

function Invoke-Transfer {
    param(
        [Parameter(Mandatory)]
        [ValidateSet("Auto", "WindowsShare", "SSH")]
        [string]$Method,

        [Parameter(Mandatory)]
        [string]$SourcePath
    )

    Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan
    Write-Host "  Transfer Method: $Method" -ForegroundColor Cyan
    Write-Host ("=" * 70) -ForegroundColor Cyan

    if ($Method -eq "Auto") {
        Write-Info "Auto-detecting best transfer method..."

        # Try Windows Share first (faster for LAN)
        Write-Info "Checking Windows Share availability..."
        if (Test-Path $script:Config.server.windowsShare) {
            Write-Success "Windows Share accessible - using Windows Share"
            return Copy-ViaWindowsShare -SourcePath $SourcePath
        } else {
            Write-Warning "Windows Share not accessible - falling back to SSH"
            return Copy-ViaSSH -SourcePath $SourcePath
        }
    } elseif ($Method -eq "WindowsShare") {
        return Copy-ViaWindowsShare -SourcePath $SourcePath
    } else {
        return Copy-ViaSSH -SourcePath $SourcePath
    }
}

# =============================================================================
# CONFIGURATION MANAGEMENT
# =============================================================================

function Show-CurrentConfig {
    Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan
    Write-Host "  Current Configuration" -ForegroundColor Cyan
    Write-Host ("=" * 70) -ForegroundColor Cyan
    Write-Host ""
    Write-Host "  Server Settings:" -ForegroundColor Yellow
    Write-Host "    Host:              $($script:Config.server.host)" -ForegroundColor Gray
    Write-Host "    SSH Port:          $($script:Config.server.sshPort)" -ForegroundColor Gray
    Write-Host "    SSH User:          $($script:Config.server.sshUser)" -ForegroundColor Gray
    Write-Host "    SSH Key:           $($script:Config.server.sshKeyPath)" -ForegroundColor Gray
    Write-Host "    Windows Share:     $($script:Config.server.windowsShare)" -ForegroundColor Gray
    Write-Host "    Deploy Path:       $($script:Config.server.deployPath)" -ForegroundColor Gray
    Write-Host ""
    Write-Host "  Build Settings:" -ForegroundColor Yellow
    Write-Host "    Default Component: $($script:Config.build.defaultComponent)" -ForegroundColor Gray
    Write-Host "    Output Path:       $($script:Config.build.outputPath)" -ForegroundColor Gray
    Write-Host ""
    Write-Host "  Transfer Settings:" -ForegroundColor Yellow
    Write-Host "    Default Method:    $($script:Config.transfer.defaultMethod)" -ForegroundColor Gray
    Write-Host "    SCP Remote Path:   $($script:Config.transfer.scpRemotePath)" -ForegroundColor Gray
    Write-Host "    Retry Attempts:    $($script:Config.transfer.retryAttempts)" -ForegroundColor Gray
    Write-Host "    Timeout (sec):     $($script:Config.transfer.timeout)" -ForegroundColor Gray
    Write-Host ""
    Write-Host "  Deployment Settings:" -ForegroundColor Yellow
    Write-Host "    Auto-Deploy:       $($script:Config.deployment.autoDeployEnabled)" -ForegroundColor Gray
    Write-Host "    Check Interval:    $($script:Config.deployment.checkIntervalMinutes) minutes" -ForegroundColor Gray
    Write-Host ""
    Write-Host "  Config File: $script:ConfigFilePath" -ForegroundColor Gray
    Write-Host ("=" * 70) -ForegroundColor Cyan
}

function Edit-Configuration {
    Clear-Host
    Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan
    Write-Host "  Configuration Editor" -ForegroundColor Cyan
    Write-Host ("=" * 70) -ForegroundColor Cyan
    Write-Host ""
    Write-Host "  Current Settings:" -ForegroundColor Yellow
    Write-Host "    Server Host:       $($script:Config.server.host)" -ForegroundColor Gray
    Write-Host "    SSH Port:          $($script:Config.server.sshPort)" -ForegroundColor Gray
    Write-Host "    SSH User:          $($script:Config.server.sshUser)" -ForegroundColor Gray
    Write-Host "    SSH Key:           $($script:Config.server.sshKeyPath)" -ForegroundColor Gray
    Write-Host "    Windows Share:     $($script:Config.server.windowsShare)" -ForegroundColor Gray
    Write-Host "    Server Deploy Path: $($script:Config.server.deployPath)" -ForegroundColor Gray
    Write-Host ""
    Write-Host "  [1] Edit SSH Connection Settings" -ForegroundColor White
    Write-Host "  [2] Edit Windows Share Path" -ForegroundColor White
    Write-Host "  [3] Edit Server Deploy Path" -ForegroundColor White
    Write-Host "  [4] Edit Build Settings" -ForegroundColor White
    Write-Host "  [5] Edit Transfer Settings" -ForegroundColor White
    Write-Host "  [S] Save Configuration" -ForegroundColor Green
    Write-Host "  [R] Reset to Defaults" -ForegroundColor Yellow
    Write-Host "  [B] Back (discard changes)" -ForegroundColor Red
    Write-Host ""
    Write-Host ("=" * 70) -ForegroundColor Cyan

    do {
        Write-Host "`nYour choice: " -ForegroundColor Yellow -NoNewline
        $choice = Read-Host

        switch ($choice.ToUpper()) {
            "1" {
                Write-Host "`nEdit SSH Connection Settings:" -ForegroundColor Yellow
                Write-Host "Server Host [current: $($script:Config.server.host)]: " -NoNewline
                $newHost = Read-Host
                if ($newHost) { $script:Config.server.host = $newHost }

                Write-Host "SSH Port [current: $($script:Config.server.sshPort)]: " -NoNewline
                $newPort = Read-Host
                if ($newPort) { $script:Config.server.sshPort = [int]$newPort }

                Write-Host "SSH User [current: $($script:Config.server.sshUser)]: " -NoNewline
                $newUser = Read-Host
                if ($newUser) { $script:Config.server.sshUser = $newUser }

                Write-Host "SSH Key Path [current: $($script:Config.server.sshKeyPath)]: " -NoNewline
                $newKey = Read-Host
                if ($newKey) { $script:Config.server.sshKeyPath = $newKey }

                Write-Success "SSH settings updated (not saved yet)"
                return Edit-Configuration
            }
            "2" {
                Write-Host "`nEdit Windows Share Path:" -ForegroundColor Yellow
                Write-Host "Windows Share [current: $($script:Config.server.windowsShare)]: " -NoNewline
                $newShare = Read-Host
                if ($newShare) { $script:Config.server.windowsShare = $newShare }

                Write-Success "Windows Share updated (not saved yet)"
                return Edit-Configuration
            }
            "3" {
                Write-Host "`nEdit Server Deploy Path:" -ForegroundColor Yellow
                Write-Host "Deploy Path [current: $($script:Config.server.deployPath)]: " -NoNewline
                $newPath = Read-Host
                if ($newPath) { $script:Config.server.deployPath = $newPath }

                Write-Success "Deploy path updated (not saved yet)"
                return Edit-Configuration
            }
            "4" {
                Write-Host "`nEdit Build Settings:" -ForegroundColor Yellow
                Write-Host "Default Component (All/Frontend/Backend)" -ForegroundColor Gray
                Write-Host "[current: $($script:Config.build.defaultComponent)]: " -NoNewline
                $newComp = Read-Host
                if ($newComp) { $script:Config.build.defaultComponent = $newComp }

                Write-Host "Output Path [current: $($script:Config.build.outputPath)]: " -NoNewline
                $newOut = Read-Host
                if ($newOut) { $script:Config.build.outputPath = $newOut }

                Write-Success "Build settings updated (not saved yet)"
                return Edit-Configuration
            }
            "5" {
                Write-Host "`nEdit Transfer Settings:" -ForegroundColor Yellow
                Write-Host "Default Method (Auto/WindowsShare/SSH) [current: $($script:Config.transfer.defaultMethod)]: " -NoNewline
                $newMethod = Read-Host
                if ($newMethod) { $script:Config.transfer.defaultMethod = $newMethod }

                Write-Host "SCP Remote Path [current: $($script:Config.transfer.scpRemotePath)]: " -NoNewline
                $newScp = Read-Host
                if ($newScp) { $script:Config.transfer.scpRemotePath = $newScp }

                Write-Success "Transfer settings updated (not saved yet)"
                return Edit-Configuration
            }
            "S" {
                if (Save-Configuration) {
                    Write-Host "`nConfiguration saved successfully!" -ForegroundColor Green
                    Wait-ForKeyPress
                    return
                }
            }
            "R" {
                Write-Host "`nAre you sure you want to reset to defaults? [Y/N]: " -ForegroundColor Yellow -NoNewline
                $confirm = Read-Host
                if ($confirm.ToUpper() -eq "Y") {
                    Load-Configuration
                    Write-Success "Configuration reset to defaults"
                    return Edit-Configuration
                }
            }
            "B" {
                Write-Host "`nChanges discarded" -ForegroundColor Yellow
                Load-Configuration  # Reload from file
                return
            }
            default {
                Write-Host "Invalid choice. Please select 1-5, S, R, or B." -ForegroundColor Red
            }
        }
    } while ($true)
}

# =============================================================================
# MENU FUNCTIONS
# =============================================================================

function Show-MainMenu {
    Clear-Host
    Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan
    Write-Host "  ROA2WEB - Interactive Build & Publish Console" -ForegroundColor Cyan
    Write-Host ("=" * 70) -ForegroundColor Cyan
    Write-Host ""
    Write-Host "  Main Menu:" -ForegroundColor Yellow
    Write-Host ""
    Write-Host "  [1] Build & Publish Package" -ForegroundColor White
    Write-Host "      (Build locally and transfer to server)" -ForegroundColor Gray
    Write-Host ""
    Write-Host "  [2] Test Connections" -ForegroundColor White
    Write-Host "      (Verify Windows Share and SSH access)" -ForegroundColor Gray
    Write-Host ""
    Write-Host "  [3] Configure Settings" -ForegroundColor White
    Write-Host "      (Edit deployment configuration)" -ForegroundColor Gray
    Write-Host ""
    Write-Host "  [4] View Current Configuration" -ForegroundColor White
    Write-Host "      (Display active settings)" -ForegroundColor Gray
    Write-Host ""
    Write-Host "  [Q] Quit" -ForegroundColor Red
    Write-Host ""
    Write-Host ("=" * 70) -ForegroundColor Cyan

    do {
        Write-Host "`nYour choice: " -ForegroundColor Yellow -NoNewline
        $choice = Read-Host

        switch ($choice.ToUpper()) {
            "1" { return "BuildPublish" }
            "2" { return "TestConnections" }
            "3" { return "Configure" }
            "4" { return "ViewConfig" }
            "Q" { return "Quit" }
            default {
                Write-Host "Invalid choice. Please select 1-4 or Q." -ForegroundColor Red
            }
        }
    } while ($true)
}

function Show-ComponentMenu {
    Clear-Host
    Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan
    Write-Host "  Select Component to Build" -ForegroundColor Cyan
    Write-Host "  Ultrathin Monolith Architecture" -ForegroundColor Cyan
    Write-Host ("=" * 70) -ForegroundColor Cyan
    Write-Host ""
    Write-Host "  [1] All Components" -ForegroundColor White
    Write-Host "      (Unified Backend + Frontend)" -ForegroundColor Gray
    Write-Host "      Includes: Reports, Data Entry, and Telegram modules" -ForegroundColor DarkGray
    Write-Host ""
    Write-Host "  [2] Frontend + Backend" -ForegroundColor White
    Write-Host "      (Vue.js SPA build + Unified FastAPI backend)" -ForegroundColor Gray
    Write-Host ""
    Write-Host "  [3] Backend Only" -ForegroundColor White
    Write-Host "      (Unified FastAPI backend + shared modules)" -ForegroundColor Gray
    Write-Host "      All modules included - control via MODULE_*_ENABLED flags" -ForegroundColor DarkGray
    Write-Host ""
    Write-Host "  [B] Back to Main Menu" -ForegroundColor Yellow
    Write-Host ""
    Write-Host ("=" * 70) -ForegroundColor Cyan

    do {
        Write-Host "`nYour choice: " -ForegroundColor Yellow -NoNewline
        $choice = Read-Host

        switch ($choice.ToUpper()) {
            "1" { return "All" }
            "2" { return "Frontend" }
            "3" { return "Backend" }
            "B" { return "Back" }
            default {
                Write-Host "Invalid choice. Please select 1-3 or B." -ForegroundColor Red
            }
        }
    } while ($true)
}

function Show-TransferMenu {
    Clear-Host
    Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan
    Write-Host "  Select Transfer Method" -ForegroundColor Cyan
    Write-Host ("=" * 70) -ForegroundColor Cyan
    Write-Host ""
    Write-Host "  [1] Auto-detect (Recommended)" -ForegroundColor White
    Write-Host "      Try Windows Share first, fallback to SSH" -ForegroundColor Gray
    Write-Host ""
    Write-Host "  [2] Windows Share (LAN)" -ForegroundColor White
    Write-Host "      Fast transfer via network share ($($script:Config.server.windowsShare))" -ForegroundColor Gray
    Write-Host ""
    Write-Host "  [3] SSH/SCP (Remote)" -ForegroundColor White
    Write-Host "      Secure transfer via SSH (port $($script:Config.server.sshPort))" -ForegroundColor Gray
    Write-Host ""
    Write-Host "  [B] Back" -ForegroundColor Yellow
    Write-Host ""
    Write-Host ("=" * 70) -ForegroundColor Cyan

    do {
        Write-Host "`nYour choice: " -ForegroundColor Yellow -NoNewline
        $choice = Read-Host

        switch ($choice.ToUpper()) {
            "1" { return "Auto" }
            "2" { return "WindowsShare" }
            "3" { return "SSH" }
            "B" { return "Back" }
            default {
                Write-Host "Invalid choice. Please select 1-3 or B." -ForegroundColor Red
            }
        }
    } while ($true)
}

# =============================================================================
# ACTION HANDLERS
# =============================================================================

function Invoke-BuildAndPublish {
    param(
        [string]$Component = "",
        [string]$TransferMethod = ""
    )

    # Get component if not provided
    if (-not $Component) {
        $Component = Show-ComponentMenu
        if ($Component -eq "Back") { return }
    }

    # Get transfer method if not provided
    if (-not $TransferMethod) {
        $TransferMethod = Show-TransferMenu
        if ($TransferMethod -eq "Back") { return }
    }

    # Build
    $buildSuccess = Invoke-Build -Component $Component

    if (-not $buildSuccess) {
        Write-Host "`n[BUILD FAILED] Cannot proceed with transfer" -ForegroundColor Red
        if (-not $NonInteractive) { Wait-ForKeyPress }
        return
    }

    # Transfer
    $outputPath = $script:Config.build.outputPath

    # Resolve the output path for transfer
    $resolvedOutputPath = if ([System.IO.Path]::IsPathRooted($outputPath)) {
        $outputPath
    } else {
        Resolve-FullPath -Path $outputPath
    }

    $transferSuccess = Invoke-Transfer -Method $TransferMethod -SourcePath $resolvedOutputPath

    if ($transferSuccess) {
        Write-Host "`n" + ("=" * 70) -ForegroundColor Green
        Write-Host "  BUILD & PUBLISH COMPLETED SUCCESSFULLY" -ForegroundColor Green
        Write-Host ("=" * 70) -ForegroundColor Green
        Write-Host "`nPackage published to server: $($script:Config.server.host)" -ForegroundColor Gray
        Write-Host "Server will auto-deploy within $($script:Config.deployment.checkIntervalMinutes) minutes" -ForegroundColor Gray
        Write-Host ("=" * 70) -ForegroundColor Green
    } else {
        Write-Host "`n[TRANSFER FAILED] Package built but transfer failed" -ForegroundColor Red
    }

    if (-not $NonInteractive) { Wait-ForKeyPress }
}

# =============================================================================
# MAIN EXECUTION FLOW
# =============================================================================

function Main {
    # Load configuration
    if (-not (Load-Configuration)) {
        Write-Host "`nPress any key to exit..." -ForegroundColor Gray
        $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
        exit 1
    }

    # Non-interactive mode
    if ($NonInteractive -and $Action) {
        switch ($Action) {
            "Build" {
                $comp = if ($Component) { $Component } else { $script:Config.build.defaultComponent }
                $method = if ($TransferMethod) { $TransferMethod } else { $script:Config.transfer.defaultMethod }
                Invoke-BuildAndPublish -Component $comp -TransferMethod $method
            }
            "TestConnections" {
                Test-AllConnections | Out-Null
            }
            "ViewConfig" {
                Show-CurrentConfig
            }
        }
        return
    }

    # Interactive mode - main loop
    do {
        $mainChoice = Show-MainMenu

        switch ($mainChoice) {
            "BuildPublish" {
                Invoke-BuildAndPublish
            }

            "TestConnections" {
                Test-AllConnections | Out-Null
                Wait-ForKeyPress
            }

            "Configure" {
                Edit-Configuration
            }

            "ViewConfig" {
                Show-CurrentConfig
                Wait-ForKeyPress
            }

            "Quit" {
                Write-Host "`nGoodbye!`n" -ForegroundColor Cyan
                return
            }
        }
    } while ($true)
}

# Run main
Main
