Private/TuiHelpers.ps1

function Write-TuiBox {
    <#
    .SYNOPSIS
        Draws a TUI box with the given content.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string]$Title,
        
        [string[]]$Content,
        
        [int]$Width = 80,
        
        [ConsoleColor]$BorderColor = 'Cyan',
        
        [ConsoleColor]$TitleColor = 'White'
    )

    $horizontal = '─'
    $vertical = '│'
    $topLeft = '┌'
    $topRight = '┐'
    $bottomLeft = '└'
    $bottomRight = '┘'
    $titleLeft = '┤'
    $titleRight = '├'

    # Top border
    $titlePadding = $Width - 4 - $Title.Length
    $leftPad = [math]::Floor($titlePadding / 2)
    $rightPad = [math]::Ceiling($titlePadding / 2)
    
    Write-Host $topLeft -ForegroundColor $BorderColor -NoNewline
    Write-Host ($horizontal * $leftPad) -ForegroundColor $BorderColor -NoNewline
    Write-Host " $Title " -ForegroundColor $TitleColor -NoNewline
    Write-Host ($horizontal * $rightPad) -ForegroundColor $BorderColor -NoNewline
    Write-Host $topRight -ForegroundColor $BorderColor

    # Content
    foreach ($line in $Content) {
        $padding = $Width - 2 - $line.Length
        if ($padding -lt 0) { $padding = 0 }
        Write-Host $vertical -ForegroundColor $BorderColor -NoNewline
        Write-Host $line -NoNewline
        Write-Host (' ' * $padding) -NoNewline
        Write-Host $vertical -ForegroundColor $BorderColor
    }

    # Bottom border
    Write-Host $bottomLeft -ForegroundColor $BorderColor -NoNewline
    Write-Host ($horizontal * ($Width - 2)) -ForegroundColor $BorderColor -NoNewline
    Write-Host $bottomRight -ForegroundColor $BorderColor
}

function Write-TuiTable {
    <#
    .SYNOPSIS
        Renders a formatted table for TUI display.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [array]$Data,
        
        [string[]]$Columns,
        
        [hashtable]$ColumnWidths,
        
        [ConsoleColor]$HeaderColor = 'Yellow',
        
        [ConsoleColor]$BorderColor = 'DarkGray'
    )

    if ($null -eq $Data -or $Data.Count -eq 0) {
        Write-Host " No data to display." -ForegroundColor DarkGray
        return
    }

    # Calculate column widths if not provided
    if (-not $ColumnWidths) {
        $ColumnWidths = @{}
        foreach ($col in $Columns) {
            $maxLen = ($Data | ForEach-Object { $_.$col.ToString().Length } | Measure-Object -Maximum).Maximum
            $ColumnWidths[$col] = [math]::Max($maxLen, $col.Length) + 2
        }
    }

    # Header
    $headerLine = '│'
    foreach ($col in $Columns) {
        $headerLine += " $($col.PadRight($ColumnWidths[$col] - 1))│"
    }
    
    $totalWidth = ($ColumnWidths.Values | Measure-Object -Sum).Sum + $Columns.Count + 1
    
    Write-Host ('┌' + ('─' * ($totalWidth - 2)) + '┐') -ForegroundColor $BorderColor
    Write-Host $headerLine -ForegroundColor $HeaderColor
    Write-Host ('├' + ('─' * ($totalWidth - 2)) + '┤') -ForegroundColor $BorderColor

    # Data rows
    foreach ($row in $Data) {
        $line = '│'
        foreach ($col in $Columns) {
            $value = if ($null -ne $row.$col) { $row.$col.ToString() } else { '' }
            
            # Truncate if too long
            if ($value.Length -gt ($ColumnWidths[$col] - 2)) {
                $value = $value.Substring(0, $ColumnWidths[$col] - 5) + '...'
            }
            
            # Color based on status
            $color = 'White'
            if ($col -eq 'Status') {
                $color = switch ($value) {
                    '✓' { 'Green' }
                    '⚠' { 'Yellow' }
                    '✗' { 'Red' }
                    default { 'White' }
                }
            }
            
            $line += " "
            Write-Host -NoNewline $line -ForegroundColor $BorderColor
            Write-Host -NoNewline $value.PadRight($ColumnWidths[$col] - 1) -ForegroundColor $color
            Write-Host -NoNewline "│" -ForegroundColor $BorderColor
            $line = ''
        }
        Write-Host
    }
    
    Write-Host ('└' + ('─' * ($totalWidth - 2)) + '┘') -ForegroundColor $BorderColor
}

function Show-TuiMenu {
    <#
    .SYNOPSIS
        Displays an interactive menu and returns the selected option.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string]$Title,
        
        [Parameter(Mandatory)]
        [string[]]$Options,
        
        [string[]]$Hotkeys
    )

    Write-Host
    Write-Host " $Title" -ForegroundColor Cyan
    Write-Host
    
    for ($i = 0; $i -lt $Options.Count; $i++) {
        $key = if ($Hotkeys -and $i -lt $Hotkeys.Count) { $Hotkeys[$i] } else { ($i + 1).ToString() }
        Write-Host " [$key] $($Options[$i])" -ForegroundColor White
    }
    
    Write-Host
    Write-Host " Selection: " -ForegroundColor Gray -NoNewline
    
    $selection = Read-Host
    return $selection.ToUpper()
}

function Clear-TuiScreen {
    <#
    .SYNOPSIS
        Clears the screen and shows the application header.
    #>

    [CmdletBinding()]
    param()
    
    Clear-Host
    Write-Host
    Write-Host " ╔═══════════════════════════════════════════════════════════════╗" -ForegroundColor Cyan
    Write-Host " ║ ║" -ForegroundColor Cyan
    Write-Host " ║ " -ForegroundColor Cyan -NoNewline
    Write-Host "🧹 WinPath-Clean v$script:ModuleVersion" -ForegroundColor White -NoNewline
    Write-Host " ║" -ForegroundColor Cyan
    Write-Host " ║ Windows PATH Environment Variable Manager ║" -ForegroundColor Cyan
    Write-Host " ║ ║" -ForegroundColor Cyan
    Write-Host " ╚═══════════════════════════════════════════════════════════════╝" -ForegroundColor Cyan
    Write-Host
}