functions/public/Get-KlippyPrintJob.ps1

function Get-KlippyPrintJob {
    <#
    .SYNOPSIS
        Gets information about the current or recent print job.

    .DESCRIPTION
        Retrieves detailed information about the current print job including
        progress, duration, filament usage, and layer information.

    .PARAMETER Id
        The unique identifier of the printer.

    .PARAMETER PrinterName
        The friendly name of the printer.

    .PARAMETER InputObject
        A printer object from pipeline input.

    .PARAMETER History
        Include print job history.

    .PARAMETER Limit
        Number of historical jobs to return. Default is 10.

    .EXAMPLE
        Get-KlippyPrintJob
        Gets the current print job from the default printer.

    .EXAMPLE
        Get-KlippyPrintJob -PrinterName "voronv2" -History -Limit 5
        Gets the last 5 print jobs from history.

    .EXAMPLE
        Get-KlippyPrinter | Get-KlippyPrintJob
        Gets current print job from all printers.

    .OUTPUTS
        PSCustomObject with print job information.
    #>

    [CmdletBinding(DefaultParameterSetName = 'Default')]
    [OutputType([PSCustomObject])]
    param(
        [Parameter(Mandatory = $true, ParameterSetName = 'ById')]
        [ValidateNotNullOrEmpty()]
        [string]$Id,

        [Parameter(Mandatory = $true, ParameterSetName = 'ByName', Position = 0)]
        [ValidateNotNullOrEmpty()]
        [string]$PrinterName,

        [Parameter(Mandatory = $true, ParameterSetName = 'ByObject', ValueFromPipeline = $true)]
        [PSCustomObject]$InputObject,

        [Parameter()]
        [switch]$History,

        [Parameter()]
        [ValidateRange(1, 100)]
        [int]$Limit = 10
    )

    process {
        # Resolve printer
        $resolveParams = @{}
        if ($Id) { $resolveParams['Id'] = $Id }
        elseif ($PrinterName) { $resolveParams['PrinterName'] = $PrinterName }
        elseif ($InputObject) { $resolveParams['InputObject'] = $InputObject }

        $printer = Resolve-KlippyPrinterTarget @resolveParams

        try {
            if ($History) {
                # Get job history from server
                Write-Verbose "[$($printer.PrinterName)] Fetching print job history..."

                $historyResponse = Invoke-KlippyHttpRequest -Printer $printer -Endpoint "server/history/list" -QueryParameters @{
                    limit = $Limit
                    order = 'desc'
                }

                $jobs = foreach ($job in $historyResponse.Jobs) {
                    [PSCustomObject]@{
                        PSTypeName      = 'KlippyCLI.PrintJobHistory'
                        PrinterId       = $printer.Id
                        PrinterName     = $printer.PrinterName
                        JobId           = $job.JobId
                        Filename        = $job.Filename
                        Status          = $job.Status
                        StartTime       = if ($job.StartTime) { [DateTimeOffset]::FromUnixTimeSeconds($job.StartTime).LocalDateTime } else { $null }
                        EndTime         = if ($job.EndTime) { [DateTimeOffset]::FromUnixTimeSeconds($job.EndTime).LocalDateTime } else { $null }
                        PrintDuration   = [TimeSpan]::FromSeconds([int]($job.PrintDuration ?? 0))
                        TotalDuration   = [TimeSpan]::FromSeconds([int]($job.TotalDuration ?? 0))
                        FilamentUsed    = [Math]::Round(($job.FilamentUsed ?? 0) / 1000, 2)
                        Metadata        = $job.Metadata
                    }
                }

                return $jobs
            }
            else {
                # Get current job status
                Write-Verbose "[$($printer.PrinterName)] Fetching current print job..."

                $printStats = Get-KlippyObject -PrinterName $printer.PrinterName -ObjectName "print_stats"
                $displayStatus = Get-KlippyObject -PrinterName $printer.PrinterName -ObjectName "display_status" -Attributes "progress"

                # Get file metadata if printing
                $metadata = $null
                if ($printStats.Filename -and $printStats.State -in @('printing', 'paused')) {
                    try {
                        $metadata = Invoke-KlippyHttpRequest -Printer $printer -Endpoint "server/files/metadata" -QueryParameters @{
                            filename = $printStats.Filename
                        }
                    }
                    catch {
                        Write-Verbose "Could not fetch file metadata: $_"
                    }
                }

                $progress = [Math]::Round(($displayStatus.Progress ?? 0) * 100, 1)
                $printDuration = [TimeSpan]::FromSeconds([int]($printStats.PrintDuration ?? 0))
                $totalDuration = [TimeSpan]::FromSeconds([int]($printStats.TotalDuration ?? 0))

                # Estimate remaining time
                $estimatedRemaining = $null
                if ($progress -gt 0 -and $printStats.State -eq 'printing') {
                    $estimatedTotal = $printDuration.TotalSeconds / ($progress / 100)
                    $remaining = $estimatedTotal - $printDuration.TotalSeconds
                    $estimatedRemaining = [TimeSpan]::FromSeconds([int]$remaining)
                }

                $result = [PSCustomObject]@{
                    PSTypeName         = 'KlippyCLI.PrintJob'
                    PrinterId          = $printer.Id
                    PrinterName        = $printer.PrinterName
                    State              = $printStats.State
                    Filename           = $printStats.Filename
                    Progress           = $progress
                    PrintDuration      = $printDuration
                    TotalDuration      = $totalDuration
                    EstimatedRemaining = $estimatedRemaining
                    FilamentUsed       = [Math]::Round(($printStats.FilamentUsed ?? 0) / 1000, 2)
                    Message            = $printStats.Message
                    CurrentLayer       = $printStats.Info.CurrentLayer
                    TotalLayers        = $printStats.Info.TotalLayer
                }

                # Add metadata if available
                if ($metadata) {
                    $result | Add-Member -NotePropertyName 'EstimatedTime' -NotePropertyValue ([TimeSpan]::FromSeconds([int]($metadata.EstimatedTime ?? 0))) -Force
                    $result | Add-Member -NotePropertyName 'Slicer' -NotePropertyValue $metadata.Slicer -Force
                    $result | Add-Member -NotePropertyName 'FilamentTotal' -NotePropertyValue ([Math]::Round(($metadata.FilamentTotal ?? 0) / 1000, 2)) -Force
                }

                return $result
            }
        }
        catch {
            Write-Error "[$($printer.PrinterName)] Failed to get print job info: $_"
        }
    }
}