functions/public/Remove-KlippyGcodeItem.ps1

function Remove-KlippyGcodeItem {
    <#
    .SYNOPSIS
        Removes a G-code file or folder from a Klipper printer.

    .DESCRIPTION
        Deletes files or folders from the printer's gcodes storage.
        Automatically detects item type (file vs folder) and uses the appropriate API.
        For folders, use -Force to delete non-empty folders recursively.
        Supports wildcard patterns and pipeline input from Get-KlippyGcodeItem.

    .PARAMETER Id
        The unique identifier of the printer.

    .PARAMETER PrinterName
        The friendly name of the printer.

    .PARAMETER InputObject
        A GcodeFile or GcodeFolder object from pipeline input (from Get-KlippyGcodeItem).

    .PARAMETER Path
        Path of the item to delete. Supports wildcards.

    .PARAMETER Force
        For folders: Delete even if folder contains files/subfolders (recursive delete).
        For files: No effect (files are always deleted directly).

    .PARAMETER Recurse
        Alias for -Force. Delete folders recursively.

    .EXAMPLE
        Remove-KlippyGcodeItem -Path "old_print.gcode"
        Removes a file from the default printer.

    .EXAMPLE
        Remove-KlippyGcodeItem -Path "old_folder" -Force
        Removes a folder and all its contents.

    .EXAMPLE
        Get-KlippyGcodeItem -Path "temp*" | Remove-KlippyGcodeItem -Force
        Removes all items matching "temp*" via pipeline.

    .EXAMPLE
        Get-KlippyGcodeItem -File -Path "*.tmp" | Remove-KlippyGcodeItem
        Removes all .tmp files via pipeline.

    .OUTPUTS
        None.
    #>

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

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

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

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

        [Parameter()]
        [Alias('Recurse')]
        [switch]$Force
    )

    process {
        # Handle pipeline input (GcodeFile or GcodeFolder object)
        if ($PSCmdlet.ParameterSetName -eq 'ByObject') {
            $printer = Resolve-KlippyPrinterTarget -Id $InputObject.PrinterId
            $itemPath = $InputObject.Path

            # Detect item type from PSTypeName
            $isFolder = $InputObject.PSObject.TypeNames -contains 'KlippyCLI.GcodeFolder'

            if ($isFolder) {
                $action = if ($Force) { "Delete folder (recursive)" } else { "Delete empty folder" }
                $itemType = "folder"
            }
            else {
                $action = "Delete file"
                $itemType = "file"
            }

            if ($PSCmdlet.ShouldProcess("$($printer.PrinterName):gcodes/$itemPath", $action)) {
                try {
                    Write-Verbose "[$($printer.PrinterName)] Deleting $itemType`: $itemPath"

                    if ($isFolder) {
                        $queryParams = @{ path = "gcodes/$itemPath" }
                        if ($Force) { $queryParams['force'] = 'true' }
                        $null = Invoke-KlippyHttpRequest -Printer $printer -Endpoint "server/files/directory" -Method DELETE -QueryParameters $queryParams
                    }
                    else {
                        $null = Invoke-KlippyHttpRequest -Printer $printer -Endpoint "server/files/gcodes/$itemPath" -Method DELETE
                    }

                    Write-Verbose "[$($printer.PrinterName)] Deleted $itemType`: $itemPath"
                }
                catch {
                    Write-Error "[$($printer.PrinterName)] Failed to delete $itemType '$itemPath': $_"
                }
            }
            return
        }

        # Resolve printer for non-pipeline cases
        $resolveParams = @{}
        switch ($PSCmdlet.ParameterSetName) {
            'ById' { $resolveParams['Id'] = $Id }
            'ByName' { $resolveParams['PrinterName'] = $PrinterName }
        }

        $printer = Resolve-KlippyPrinterTarget @resolveParams

        try {
            # Check if path contains wildcards
            $hasWildcard = $Path -match '[\*\?\[\]]'

            if ($hasWildcard) {
                # Get matching items (files and folders)
                $items = Get-KlippyGcodeItem @resolveParams -Path $Path

                if (-not $items -or $items.Count -eq 0) {
                    Write-Warning "[$($printer.PrinterName)] No items matching '$Path' found."
                    return
                }

                Write-Verbose "[$($printer.PrinterName)] Found $($items.Count) item(s) matching '$Path'"

                foreach ($item in $items) {
                    $isFolder = $item.PSObject.TypeNames -contains 'KlippyCLI.GcodeFolder'

                    if ($isFolder) {
                        $action = if ($Force) { "Delete folder (recursive)" } else { "Delete empty folder" }
                        $itemType = "folder"
                    }
                    else {
                        $action = "Delete file"
                        $itemType = "file"
                    }

                    if ($PSCmdlet.ShouldProcess("$($printer.PrinterName):gcodes/$($item.Path)", $action)) {
                        try {
                            if ($isFolder) {
                                $queryParams = @{ path = "gcodes/$($item.Path)" }
                                if ($Force) { $queryParams['force'] = 'true' }
                                $null = Invoke-KlippyHttpRequest -Printer $printer -Endpoint "server/files/directory" -Method DELETE -QueryParameters $queryParams
                            }
                            else {
                                $null = Invoke-KlippyHttpRequest -Printer $printer -Endpoint "server/files/gcodes/$($item.Path)" -Method DELETE
                            }
                            Write-Verbose "[$($printer.PrinterName)] Deleted $itemType`: $($item.Path)"
                        }
                        catch {
                            Write-Error "[$($printer.PrinterName)] Failed to delete $itemType '$($item.Path)': $_"
                        }
                    }
                }
            }
            else {
                # Direct path deletion - need to determine if file or folder
                # Try to get the item first to detect its type
                $cleanPath = $Path.TrimStart('/').TrimEnd('/')
                $items = Get-KlippyGcodeItem @resolveParams -Path $cleanPath

                if (-not $items -or $items.Count -eq 0) {
                    Write-Error "[$($printer.PrinterName)] Item '$cleanPath' not found."
                    return
                }

                $item = $items | Select-Object -First 1
                $isFolder = $item.PSObject.TypeNames -contains 'KlippyCLI.GcodeFolder'

                if ($isFolder) {
                    $action = if ($Force) { "Delete folder (recursive)" } else { "Delete empty folder" }
                    $itemType = "folder"
                }
                else {
                    $action = "Delete file"
                    $itemType = "file"
                }

                if ($PSCmdlet.ShouldProcess("$($printer.PrinterName):gcodes/$cleanPath", $action)) {
                    if ($isFolder) {
                        $queryParams = @{ path = "gcodes/$cleanPath" }
                        if ($Force) { $queryParams['force'] = 'true' }
                        $null = Invoke-KlippyHttpRequest -Printer $printer -Endpoint "server/files/directory" -Method DELETE -QueryParameters $queryParams
                    }
                    else {
                        $null = Invoke-KlippyHttpRequest -Printer $printer -Endpoint "server/files/gcodes/$cleanPath" -Method DELETE
                    }
                    Write-Verbose "[$($printer.PrinterName)] Deleted $itemType`: $cleanPath"
                }
            }
        }
        catch {
            Write-Error "[$($printer.PrinterName)] Failed to delete item(s): $_"
        }
    }
}