Functions/Public/Wait-ForInput.ps1

function Wait-ForInput {
    <#
    .SYNOPSIS
        Pauses execution until the user presses any key, optionally with a timer.

    .DESCRIPTION
        The Wait-ForInput function displays a message and waits for the user to press
        any key before continuing. Optionally integrates with OrionDesign theming.
        
        When -Timer is specified, pauses for a specified duration with optional countdown,
        allowing key press to interrupt the wait early.

    .PARAMETER Message
        The message to display. Default is "Press any key to continue..."
        When using -Timer, use {0} as placeholder for seconds (e.g., "Waiting {0} seconds...").

    .PARAMETER NoNewLine
        If specified, does not add a newline after the message.

    .PARAMETER Color
        The color for the message text. If not specified and OrionDesign is available,
        uses the theme's Question color.

    .PARAMETER PassThru
        If specified, returns the key that was pressed as a ConsoleKeyInfo object.
        When using -Timer, returns $true if wait completed, $false if interrupted.

    .PARAMETER Timer
        The number of seconds to wait before continuing automatically.
        Users can press any key to interrupt the wait early.

    .PARAMETER ShowCountdown
        When using -Timer, displays the remaining seconds as a countdown.

    .PARAMETER NoInterrupt
        When using -Timer, disables key press interruption (pure wait).

    .PARAMETER CompletionMessage
        When using -Timer, a message displayed after the wait completes (not shown if interrupted).

    .INPUTS
        None. You cannot pipe objects to Wait-ForInput.

    .OUTPUTS
        None by default.
        System.ConsoleKeyInfo if -PassThru is specified (without -Timer).
        System.Boolean if -Timer is specified (true = completed, false = interrupted).

    .EXAMPLE
        Wait-ForInput

        Displays "Press any key to continue..." and waits for input.

    .EXAMPLE
        Wait-ForInput -Message "Review the results above, then press any key..."

        Displays custom message and waits.

    .EXAMPLE
        $key = Wait-ForInput -PassThru
        if ($key.Key -eq 'Escape') { exit }

        Captures the pressed key for conditional logic.

    .EXAMPLE
        Wait-ForInput -Timer 10

        Waits for 10 seconds with default message, allowing key press to skip.

    .EXAMPLE
        Wait-ForInput -Timer 5 -ShowCountdown

        Shows a countdown timer: "5s - 4s - 3s - 2s - 1s -"

    .EXAMPLE
        Wait-ForInput -Timer 30 -Message "Starting in {0} seconds..." -ShowCountdown

        Shows custom message and countdown.

    .EXAMPLE
        $completed = Wait-ForInput -Timer 60 -NoInterrupt
        
        Waits 60 seconds without allowing interruption.

    .NOTES
        Author: Sune Alexandersen Narud
        Version: 1.1.0
        Date: February 2026
    #>


    [CmdletBinding(DefaultParameterSetName = 'Immediate')]
    [OutputType([System.ConsoleKeyInfo], ParameterSetName = 'Immediate')]
    [OutputType([bool], ParameterSetName = 'Timer')]
    param (
        [Parameter(Position = 0)]
        [string]$Message,

        [Parameter(ParameterSetName = 'Immediate')]
        [switch]$NoNewLine,

        [Parameter()]
        [System.ConsoleColor]$Color,

        [Parameter()]
        [switch]$PassThru,

        [Parameter(ParameterSetName = 'Timer', Mandatory = $true)]
        [ValidateRange(1, 3600)]
        [int]$Timer,

        [Parameter(ParameterSetName = 'Timer')]
        [switch]$ShowCountdown,

        [Parameter(ParameterSetName = 'Timer')]
        [switch]$NoInterrupt,

        [Parameter(ParameterSetName = 'Timer')]
        [string]$CompletionMessage
    )

    # Set default messages based on mode
    if (-not $PSBoundParameters.ContainsKey('Message')) {
        if ($Timer) {
            $Message = "Waiting {0} seconds. Press any key to continue!"
        }
        else {
            $Message = "Press any key to continue!"
        }
    }

    # Timer mode - countdown with optional key interrupt
    if ($Timer) {
        # Display the initial message if specified
        if ($Message) {
            Write-Host ($Message -f $Timer) -ForegroundColor Yellow
        }

        $interrupted = $false

        for ($i = $Timer; $i -gt 0; $i--) {
            if ($ShowCountdown) {
                Write-Host -NoNewline "${i}s - " -ForegroundColor Cyan
            }

            Start-Sleep -Seconds 1

            if (-not $NoInterrupt -and [Console]::KeyAvailable) {
                # Consume the key press
                $null = [Console]::ReadKey($true)
                Write-Host "Key pressed - Continuing" -ForegroundColor Yellow
                $interrupted = $true
                break
            }
        }

        # Clear the countdown line
        if ($ShowCountdown) {
            Write-Host ""
        }

        # Display completion message if wait finished naturally
        if (-not $interrupted -and $CompletionMessage) {
            Write-Host $CompletionMessage -ForegroundColor Yellow
        }

        return -not $interrupted
    }

    # Immediate mode - wait for key press
    # Determine the color to use
    $displayColor = $Color
    if (-not $PSBoundParameters.ContainsKey('Color')) {
        # Try to get OrionDesign theme color if available; prefer Accent, then Question/Primary/Info
        if (Get-Command -Name 'Get-OrionTheme' -ErrorAction SilentlyContinue) {
            try {
                $theme = Get-OrionTheme

                $candidateKeys = @('Accent', 'Question', 'Primary', 'Info')
                foreach ($key in $candidateKeys) {
                    if ($theme.PSObject.Properties.Match($key).Count -gt 0 -and $theme.$key) {
                        $displayColor = $theme.$key
                        break
                    }
                }

                if (-not $displayColor) {
                    $displayColor = 'Cyan'
                }
            }
            catch {
                $displayColor = 'Cyan'
            }
        }
        else {
            $displayColor = 'Cyan'
        }
    }

    Write-Host
    if ($NoNewLine) {
        Write-Host $Message -ForegroundColor $displayColor -NoNewline
    }
    else {
        Write-Host $Message -ForegroundColor $displayColor
    }
    Write-Host

    # Wait for and capture key press
    $keyInfo = [System.Console]::ReadKey($true)

    if ($PassThru) {
        return $keyInfo
    }
}