scripts/modules/shared/write-functions.ps1

# strangeloop setup - Shared Output Functions
# Version: 1.0.0


# Output formatting functions for consistent messaging across all modules

function Write-Step {
    param(
        [string]$Message,
        [string]$Color = "Cyan"
    )
    
    $timestamp = Get-Date -Format 'HH:mm:ss'
    Write-Host "`n[$timestamp] " -ForegroundColor Gray -NoNewline
    Write-Host "═══ $Message ═══" -ForegroundColor $Color
}

function Write-Success {
    param([string]$Message)
    
    $timestamp = Get-Date -Format 'HH:mm:ss'
    Write-Host "[$timestamp] " -ForegroundColor Gray -NoNewline
    Write-Host "✓ $Message" -ForegroundColor Green
}

function Write-Warning {
    param([string]$Message)
    
    $timestamp = Get-Date -Format 'HH:mm:ss'
    Write-Host "[$timestamp] " -ForegroundColor Gray -NoNewline
    Write-Host "⚠ $Message" -ForegroundColor Yellow
}

function Write-Error {
    param([string]$Message)
    
    $timestamp = Get-Date -Format 'HH:mm:ss'
    Write-Host "[$timestamp] " -ForegroundColor Gray -NoNewline
    Write-Host "✗ $Message" -ForegroundColor Red
}

function Write-Info {
    param([string]$Message)
    
    $timestamp = Get-Date -Format 'HH:mm:ss'
    Write-Host "[$timestamp] " -ForegroundColor Gray -NoNewline
    Write-Host "ℹ $Message" -ForegroundColor Cyan
}

function Write-Progress {
    param([string]$Message)
    
    $timestamp = Get-Date -Format 'HH:mm:ss'
    Write-Host "[$timestamp] " -ForegroundColor Gray -NoNewline
    Write-Host "⌛ $Message" -ForegroundColor Yellow
}

function Write-Banner {
    param(
        [string]$Title,
        [string]$Description = "",
        [string]$Version = ""
    )
    
    $width = 70
    $innerWidth = $width

    function PadBannerLine {
        param([string]$text)
        # Always render 'strangeloop' in lower case
        $text = $text -replace '(?i)strangeloop', 'strangeloop'
        return $text.PadLeft(($innerWidth + $text.Length) / 2).PadRight($innerWidth)
    }

    Write-Host ""
    Write-Host ("╔" + ('═' * $innerWidth) + "╗") -ForegroundColor Cyan
    $bannerTitle = $Title -replace '(?i)strangeloop', 'strangeloop'
    Write-Host ("║" + (PadBannerLine $bannerTitle) + "║") -ForegroundColor Cyan

    if ($Description) {
        Write-Host ("║" + (PadBannerLine $Description) + "║") -ForegroundColor White
    }

    if ($Version) {
        $versionText = "Version: $Version"
        Write-Host ("║" + (PadBannerLine $versionText) + "║") -ForegroundColor Gray
    }

    Write-Host ("╚" + ('═' * $innerWidth) + "╝") -ForegroundColor Cyan
    Write-Host ""
}

function Write-CompletionSummary {
    param(
        [hashtable]$Results,
        [string]$Title = "Operation Summary"
    )
    
    Write-Host ""
    Write-Host "╔══════════════════════════════════════════════════════════════╗" -ForegroundColor Green
    $TitleLower = $Title -replace '(?i)strangeloop', 'strangeloop'
    Write-Host "║$((' ' + $TitleLower + ' ').PadLeft((64 + $TitleLower.Length) / 2).PadRight(62))║" -ForegroundColor Green
    Write-Host "╠══════════════════════════════════════════════════════════════╣" -ForegroundColor Green

    foreach ($key in $Results.Keys) {
        $value = $Results[$key]
        $line = " $($key): $value".PadRight(62)
        # Print the whole line in green, but value in white for contrast
        Write-Host ("║" + $line.Substring(0, $line.IndexOf(':') + 2)) -NoNewline -ForegroundColor Green
        Write-Host ($line.Substring($line.IndexOf(':') + 2)) -NoNewline -ForegroundColor White
        Write-Host "║" -ForegroundColor Green
    }

    Write-Host "╚══════════════════════════════════════════════════════════════╝" -ForegroundColor Green
    Write-Host ""
}

function Read-UserPrompt {
    <#
    .SYNOPSIS
        Unified function for all user prompts with consistent formatting and validation
    
    .PARAMETER Prompt
        The prompt message to display to the user
    
    .PARAMETER DefaultValue
        The default value if user presses Enter without input (not used for Y/N prompts)
    
    .PARAMETER ValidValues
        Array of valid values for validation. Use @("y","n") for Y/N prompts
    
    .EXAMPLE
        Read-UserPrompt -Prompt "Enter project name" -DefaultValue "MyProject"
    
    .EXAMPLE
        Read-UserPrompt -Prompt "Continue with installation?" -ValidValues @("y","n")
    
    .EXAMPLE
        Read-UserPrompt -Prompt "Choose action" -ValidValues @("O", "N", "A")
    #>

    param(
        [Parameter(Mandatory)]
        [string]$Prompt,
        
        [string]$DefaultValue = "",
        
        [string[]]$ValidValues = @()
    )
    
    # Determine if this is a Y/N prompt
    $isYesNo = $ValidValues.Count -eq 4 -and 
               ($ValidValues | ForEach-Object { $_.ToLower() }) -contains "y" -and
               ($ValidValues | ForEach-Object { $_.ToLower() }) -contains "yes" -and
               ($ValidValues | ForEach-Object { $_.ToLower() }) -contains "n" -and
               ($ValidValues | ForEach-Object { $_.ToLower() }) -contains "no"
    
    # For Y/N prompts, force no default and no empty input
    if ($isYesNo) {
        $DefaultValue = ""
        $emptyAllowed = $false
    } else {
        # For other prompts, allow empty if there's a default or no validation
        $emptyAllowed = ($DefaultValue -ne "") -or ($ValidValues.Count -eq 0)
    }
    
    # Build the prompt string
    $promptText = $Prompt
    
    # Add default value indicator if provided and empty is allowed
    if ($DefaultValue -and $emptyAllowed) {
        $promptText += " [$DefaultValue]"
    }
    
    # Add valid values indicator if specified
    if ($ValidValues.Count -gt 0) {
        if ($isYesNo) {
            $promptText += " (y/n)"
        } else {
            $promptText += " ($($ValidValues -join '/'))"
        }
    }
    
    $promptText += ": "
    
    do {
        Write-Host $promptText -NoNewline -ForegroundColor Yellow
        $userInput = Read-Host
        
        # Handle empty input
        if ([string]::IsNullOrWhiteSpace($userInput)) {
            if ($emptyAllowed -and $DefaultValue) {
                return $DefaultValue
            } elseif ($emptyAllowed) {
                return ""
            } else {
                Write-Host "Input is required. Please enter a valid value." -ForegroundColor Red
                continue
            }
        }
        
        $userInput = $userInput.Trim()
        
        # Validate against valid values if specified
        if ($ValidValues.Count -gt 0) {
            $normalizedInput = $userInput.ToLower()
            $normalizedValidValues = $ValidValues | ForEach-Object { $_.ToLower() }
            
            if ($normalizedInput -notin $normalizedValidValues) {
                Write-Host "Invalid input. Please enter one of: $($ValidValues -join ', ')" -ForegroundColor Red
                continue
            }
        }
        
        return $userInput
        
    } while ($true)
}

function Test-YesResponse {
    <#
    .SYNOPSIS
        Tests if a response indicates "Yes" - supports y, yes (case insensitive)
    
    .PARAMETER Response
        The user's response to test
    
    .EXAMPLE
        $continue = Test-YesResponse (Read-UserPrompt -Prompt "Continue?" -IsYesNo $true)
    #>

    param(
        [string]$Response
    )
    
    return $Response.ToLower() -in @("y", "yes")
}

# Export functions for module usage only
if ($MyInvocation.MyCommand.ModuleName) {
    Export-ModuleMember -Function @(
        'Write-Step',
        'Write-Success', 
        'Write-Warning',
        'Write-Error',
        'Write-Info',
        'Write-Progress',
        'Write-Banner',
        'Write-CompletionSummary',
        'Read-UserPrompt',
        'Test-YesResponse'
    )
}