functions/public/Stop-KlippyPrint.ps1

function Stop-KlippyPrint {
    <#
    .SYNOPSIS
        Stops/cancels the current print job on a Klipper printer.

    .DESCRIPTION
        Cancels the current print job. This action cannot be undone.

    .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 Force
        Skip confirmation prompt.

    .EXAMPLE
        Stop-KlippyPrint
        Stops the print on the default printer with confirmation.

    .EXAMPLE
        Stop-KlippyPrint -PrinterName "voronv2" -Force
        Stops the print without confirmation.

    .EXAMPLE
        Get-KlippyPrinter | Stop-KlippyPrint -Force
        Stops all prints on all printers.

    .OUTPUTS
        PSCustomObject with stop result.
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High', 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]$Force
    )

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

        $printer = Resolve-KlippyPrinterTarget @resolveParams

        # Check current state
        $currentFilename = ''
        $currentProgress = 0
        try {
            $status = Get-KlippyStatus -PrinterName $printer.PrinterName
            $currentFilename = $status.Filename
            $currentProgress = $status.Progress

            if ($status.State -notin @('printing', 'paused')) {
                Write-Warning "[$($printer.PrinterName)] No active print to stop (state: $($status.State))"
                return [PSCustomObject]@{
                    PSTypeName  = 'KlippyCLI.PrintJob'
                    PrinterId   = $printer.Id
                    PrinterName = $printer.PrinterName
                    Action      = 'StopSkipped'
                    State       = $status.State
                    Success     = $false
                    Message     = "No active print"
                }
            }
        }
        catch {
            Write-Verbose "Could not check current state: $_"
        }

        $confirmMessage = "Stop print '$currentFilename' at $currentProgress% progress?"

        if ($Force -or $PSCmdlet.ShouldProcess($printer.PrinterName, "Stop print: $currentFilename")) {
            if (-not $Force -and -not $PSCmdlet.ShouldContinue($confirmMessage, "Confirm Stop")) {
                return [PSCustomObject]@{
                    PSTypeName  = 'KlippyCLI.PrintJob'
                    PrinterId   = $printer.Id
                    PrinterName = $printer.PrinterName
                    Filename    = $currentFilename
                    Action      = 'StopCancelled'
                    Success     = $false
                    Message     = "User cancelled"
                }
            }

            try {
                Write-Verbose "[$($printer.PrinterName)] Stopping print: $currentFilename"

                $null = Invoke-KlippyJsonRpc -Printer $printer -Method "printer/print/cancel"

                Write-Verbose "[$($printer.PrinterName)] Print stopped"

                return [PSCustomObject]@{
                    PSTypeName  = 'KlippyCLI.PrintJob'
                    PrinterId   = $printer.Id
                    PrinterName = $printer.PrinterName
                    Filename    = $currentFilename
                    Progress    = $currentProgress
                    Action      = 'Stopped'
                    Success     = $true
                }
            }
            catch {
                Write-Error "[$($printer.PrinterName)] Failed to stop print: $_"

                return [PSCustomObject]@{
                    PSTypeName  = 'KlippyCLI.PrintJob'
                    PrinterId   = $printer.Id
                    PrinterName = $printer.PrinterName
                    Filename    = $currentFilename
                    Action      = 'StopFailed'
                    Success     = $false
                    Error       = $_.Exception.Message
                }
            }
        }
    }
}