functions/public/Get-KlippyPrintHistory.ps1

function Get-KlippyPrintHistory {
    <#
    .SYNOPSIS
        Gets print history from a Klipper printer.

    .DESCRIPTION
        Retrieves historical print job records including filenames,
        print times, filament used, and completion status.

    .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 Limit
        Maximum number of records to return. Default is 50.

    .PARAMETER Start
        Starting index for pagination.

    .PARAMETER Before
        Get records before this Unix timestamp.

    .PARAMETER Since
        Get records since this Unix timestamp.

    .PARAMETER Order
        Sort order: 'desc' (newest first) or 'asc' (oldest first). Default is 'desc'.

    .EXAMPLE
        Get-KlippyPrintHistory
        Gets recent print history from the default printer.

    .EXAMPLE
        Get-KlippyPrintHistory -Limit 100
        Gets the last 100 print jobs.

    .EXAMPLE
        Get-KlippyPrintHistory -Since ([DateTimeOffset]::Now.AddDays(-7).ToUnixTimeSeconds())
        Gets prints from the last 7 days.

    .OUTPUTS
        KlippyCLI.PrintHistory objects.
    #>

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

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

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

        [Parameter()]
        [ValidateRange(1, 1000)]
        [int]$Limit = 50,

        [Parameter()]
        [int]$Start = 0,

        [Parameter()]
        [long]$Before,

        [Parameter()]
        [long]$Since,

        [Parameter()]
        [ValidateSet('desc', 'asc')]
        [string]$Order = 'desc'
    )

    process {
        # Resolve printer
        $resolveParams = @{}
        switch ($PSCmdlet.ParameterSetName) {
            'ById' { $resolveParams['Id'] = $Id }
            'ByName' { $resolveParams['PrinterName'] = $PrinterName }
            'ByObject' { $resolveParams['InputObject'] = $InputObject }
        }

        $printer = Resolve-KlippyPrinterTarget @resolveParams

        try {
            # Build query parameters
            $queryParams = @(
                "limit=$Limit",
                "start=$Start",
                "order=$Order"
            )

            if ($Before) {
                $queryParams += "before=$Before"
            }
            if ($Since) {
                $queryParams += "since=$Since"
            }

            $endpoint = "server/history/list?" + ($queryParams -join '&')
            $response = Invoke-KlippyJsonRpc -Printer $printer -Method $endpoint -NoNormalize

            if (-not $response -or -not $response.jobs) {
                Write-Verbose "No print history found."
                return
            }

            foreach ($job in $response.jobs) {
                $startTime = if ($job.start_time) {
                    [DateTimeOffset]::FromUnixTimeSeconds([long]$job.start_time).LocalDateTime
                } else { $null }

                $endTime = if ($job.end_time) {
                    [DateTimeOffset]::FromUnixTimeSeconds([long]$job.end_time).LocalDateTime
                } else { $null }

                [PSCustomObject]@{
                    PSTypeName      = 'KlippyCLI.PrintHistory'
                    PrinterId       = $printer.Id
                    PrinterName     = $printer.PrinterName
                    JobId           = $job.job_id
                    FileName        = $job.filename
                    Status          = $job.status
                    StartTime       = $startTime
                    EndTime         = $endTime
                    PrintDuration   = [TimeSpan]::FromSeconds($job.print_duration)
                    TotalDuration   = [TimeSpan]::FromSeconds($job.total_duration)
                    FilamentUsed    = [math]::Round($job.filament_used / 1000, 2)  # Convert to meters
                    Metadata        = $job.metadata
                }
            }
        }
        catch {
            Write-Error "Failed to get print history from '$($printer.PrinterName)': $_"
        }
    }
}