Public/Show-Deck.ps1

function Show-Deck {
    <#
    .SYNOPSIS
        Displays a Markdown file as an interactive terminal presentation.

    .DESCRIPTION
        Converts a Markdown file into a live terminal-based presentation with rich
        formatting, colors, and ASCII art. Navigate through slides using arrow keys,
        space, or enter.

    .PARAMETER Path
        Path to the Markdown file containing the presentation.

    .PARAMETER Background
        Override the background color from the Markdown frontmatter.
        Accepts Spectre.Console.Color values (e.g., 'Black', 'DarkBlue', 'Grey15').

    .PARAMETER Foreground
        Override the foreground color from the Markdown frontmatter.
        Accepts Spectre.Console.Color values (e.g., 'White', 'Cyan1', 'Yellow').

    .PARAMETER Border
        Override the border color from the Markdown frontmatter.
        Accepts Spectre.Console.Color values (e.g., 'Blue', 'Magenta1', 'Green').

    .EXAMPLE
        Show-Deck -Path ./presentation.md

        Displays the presentation from the specified Markdown file.

    .EXAMPLE
        Show-Deck -Path ./presentation.md -Foreground Cyan1 -Background Black

        Displays the presentation with custom colors.

    .NOTES
        Requires PwshSpectreConsole module for terminal rendering.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true, Position = 0)]
        [ValidateScript({ Test-Path $_ -PathType Leaf })]
        [string]$Path,

        [Parameter()]
        [string]$Background,

        [Parameter()]
        [string]$Foreground,

        [Parameter()]
        [string]$Border
    )

    begin {
        Write-Verbose "Starting presentation from: $Path"
        
        # Ensure PwshSpectreConsole is loaded
        Import-SlidesDependency
    }

    process {
        try {
            # Parse the markdown file
            $presentation = ConvertFrom-SlideMarkdown -Path $Path
            Write-Verbose "Loaded $($presentation.Slides.Count) slides"

            # Apply parameter overrides to settings
            if ($PSBoundParameters.ContainsKey('Background')) {
                $presentation.Settings.background = $Background
            }
            if ($PSBoundParameters.ContainsKey('Foreground')) {
                $presentation.Settings.foreground = $Foreground
            }
            if ($PSBoundParameters.ContainsKey('Border')) {
                $presentation.Settings.border = $Border
            }

            # Hide cursor during presentation using ANSI escape codes
            Write-Host "`e[?25l" -NoNewline  # Hide cursor

            try {
                # Full navigation loop (Phase 6)
                $currentSlide = 0
                $totalSlides = $presentation.Slides.Count
                $shouldExit = $false

                while ($true) {
                    # Clear screen for new slide
                Clear-Host

                $slide = $presentation.Slides[$currentSlide]
                
                # Detect slide type based on content
                if ($slide.Content -match '^\s*#\s+.+$' -and $slide.Content -notmatch '\n[^#]') {
                    # Title slide: Only has # heading, no other content
                    Write-Verbose "Rendering title slide $($currentSlide + 1)/$totalSlides"
                    Show-TitleSlide -Slide $slide -Settings $presentation.Settings -IsFirstSlide:($currentSlide -eq 0)
                }
                elseif ($slide.Content -match '^\s*##\s+.+$' -and $slide.Content -notmatch '\n[^#]') {
                    # Section slide: Only has ## heading, no other content
                    Write-Verbose "Rendering section slide $($currentSlide + 1)/$totalSlides"
                    Show-SectionSlide -Slide $slide -Settings $presentation.Settings
                }
                else {
                    # Content slide: May have ### heading or just content
                    Write-Verbose "Rendering content slide $($currentSlide + 1)/$totalSlides"
                    Show-ContentSlide -Slide $slide -Settings $presentation.Settings
                }

                # Get user input
                $key = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
                $action = Get-SlideNavigation -KeyInfo $key

                # Handle help key
                if ($key.Character -eq '?') {
                    Clear-Host
                    Write-Host "`n Navigation Controls`n" -ForegroundColor Cyan
                    Write-Host " Forward: " -ForegroundColor Gray -NoNewline
                    Write-Host "Right, Down, Space, Enter, n, Page Down" -ForegroundColor White
                    Write-Host " Backward: " -ForegroundColor Gray -NoNewline
                    Write-Host "Left, Up, Backspace, p, Page Up" -ForegroundColor White
                    Write-Host " Exit: " -ForegroundColor Gray -NoNewline
                    Write-Host "Esc, Ctrl+C" -ForegroundColor White
                    Write-Host "`n Press any key to return to presentation..." -ForegroundColor DarkGray
                    $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
                    continue
                }

                # Handle navigation
                switch ($action) {
                    'Next' {
                        if ($currentSlide -lt $totalSlides - 1) {
                            $currentSlide++
                            Write-Verbose "Advanced to slide $($currentSlide + 1)"
                        }
                        else {
                            # On last slide, trying to go forward shows end screen
                            Clear-Host
                            
                            # Center text vertically and horizontally
                            $windowHeight = $Host.UI.RawUI.WindowSize.Height
                            $windowWidth = $Host.UI.RawUI.WindowSize.Width
                            
                            $line1 = "End of Slides"
                            $line2 = "Press ESC to Exit"
                            
                            # Calculate vertical position (center)
                            $verticalPadding = [math]::Floor($windowHeight / 2) - 1
                            
                            # Print vertical padding
                            Write-Host ("`n" * $verticalPadding) -NoNewline
                            
                            # Print first line centered
                            $padding1 = [math]::Max(0, [math]::Floor(($windowWidth - $line1.Length) / 2))
                            Write-Host (" " * $padding1) -NoNewline
                            Write-Host $line1 -ForegroundColor White
                            
                            # Blank line between
                            Write-Host ""
                            
                            # Print second line centered
                            $padding2 = [math]::Max(0, [math]::Floor(($windowWidth - $line2.Length) / 2))
                            Write-Host (" " * $padding2) -NoNewline
                            Write-Host $line2 -ForegroundColor Gray
                            
                            # Wait for ESC or backward navigation
                            do {
                                $exitKey = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
                                $exitAction = Get-SlideNavigation -KeyInfo $exitKey
                                
                                if ($exitAction -eq 'Previous') {
                                    # Go back to last slide
                                    Write-Verbose "Returning to last slide from end screen"
                                    break
                                }
                            } while ($exitKey.VirtualKeyCode -ne 27)  # 27 = ESC
                            
                            # If ESC was pressed, exit; if backward nav, continue loop
                            if ($exitKey.VirtualKeyCode -eq 27) {
                                Write-Verbose "User exited from end screen"
                                $shouldExit = $true
                                break
                            }
                        }
                    }
                    'Previous' {
                        if ($currentSlide -gt 0) {
                            $currentSlide--
                            Write-Verbose "Moved back to slide $($currentSlide + 1)"
                        }
                    }
                    'Exit' {
                        Write-Verbose "User requested exit"
                        $shouldExit = $true
                        break
                    }
                    'None' {
                        # Unhandled key, ignore
                        Write-Verbose "Unhandled key: $($key.Key)"
                    }
                }

                # Check if we should exit
                if ($shouldExit) {
                    break
                }
            }

            Write-Verbose "Presentation ended"
            }
            finally {
                # Show cursor again
                Write-Host "`e[?25h" -NoNewline  # Show cursor
            }
        }
        catch {
            $errorRecord = [System.Management.Automation.ErrorRecord]::new(
                $_.Exception,
                'PresentationFailed',
                [System.Management.Automation.ErrorCategory]::InvalidOperation,
                $Path
            )
            $PSCmdlet.ThrowTerminatingError($errorRecord)
        }
    }

    end {
        Write-Verbose "Show-Deck complete"
    }
}