Private/Export-LogReport.ps1

function Export-LogReport {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [hashtable]$Summary,

        [Parameter(Mandatory)]
        [array]$Entries,

        [Parameter(Mandatory)]
        [string]$SourcePath,

        [Parameter(Mandatory)]
        [string]$OutputPath,

        [ValidateSet("Text", "Json", "Csv", "Html")]
        [string]$Format = "Text",

        [switch]$Redact,
        [switch]$IncludeMetadata,
        [switch]$GenerateRedactionLog
    )

    try {
        $moduleVersion = '1.0.0'
        $timestamp = Get-Date -Format 'yyyy-MM-ddTHH:mm:ssZ'

        $entryCount = if ($Entries) { $Entries.Count } else { 0 }
        $metadata = @{
            GeneratedAt   = $timestamp
            ModuleVersion = $moduleVersion
            SourceFile    = $SourcePath
            EntryCount    = $entryCount
        }

        # Validate and create output directory
        $outputDir = Split-Path -Path $OutputPath -Parent
        if ($outputDir -and !(Test-Path -Path $outputDir)) {
            Write-Verbose "Creating output directory: $outputDir"
            New-Item -Path $outputDir -ItemType Directory -Force | Out-Null
        }

        # Warn if file extension doesn't match format
        $expectedExt = ".$($Format.ToLower())"
        if (-not $OutputPath.ToLower().EndsWith($expectedExt)) {
            Write-Warning "⚠️ Output path extension does not match selected format '$Format'. Expected file extension: '$expectedExt'"
        }

        $redactionLogRef = [ref](New-Object System.Collections.Generic.List[string])
        $entriesToUse = $Entries

        if ($Redact) {
            Write-Progress -Activity "Exporting log report" -Status "Applying redaction" -PercentComplete 25
            $entriesToUse = foreach ($entry in $Entries) {
                Protect-LogEntry -Entry $entry -RedactionLog $redactionLogRef
            }
        }

        if ($GenerateRedactionLog -and $Redact -and $redactionLogRef.Value.Count -gt 0) {
            try {
                $logPath = Join-Path -Path $outputDir -ChildPath 'redaction-log.txt'
                $logContent = @(
                    "SmartLogAnalyzer Redaction Log - $timestamp",
                    "Source File: $SourcePath",
                    "Redacted Fields:",
                    ""
                ) + $redactionLogRef.Value
                $logContent | Out-File -FilePath $logPath -Encoding UTF8
                Write-Host "🛡️ Redaction log saved to: $logPath" -ForegroundColor DarkYellow
            } catch {
                Write-Warning "Failed to create redaction log: $_"
            }
        }

        Write-Progress -Activity "Exporting log report" -Status "Generating $Format report" -PercentComplete 50

        $hasEntries = ($entriesToUse -and $entriesToUse.Count -gt 0)

        switch ($Format) {
            "Json" {
                try {
                    $report = @{
                        Metadata = if ($IncludeMetadata) { $metadata } else { $null }
                        Summary  = $Summary
                        Entries  = $entriesToUse
                    } | ConvertTo-Json -Depth 5
                    $report | Out-File -FilePath $OutputPath -Encoding UTF8
                } catch {
                    throw "Failed to export JSON report: $_"
                }
            }

            "Csv" {
                try {
                    if (-not $hasEntries) {
                        Write-Warning "No entries to export to CSV"
                        "# No log entries found" | Out-File -FilePath $OutputPath -Encoding UTF8
                    } else {
                        $entriesToUse | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8
                    }
                } catch {
                    throw "Failed to export CSV report: $_"
                }
            }

            "Text" {
                try {
                    $lines = @()

                    if ($IncludeMetadata) {
                        $lines += "# SmartLogAnalyzer Report"
                        $lines += "Generated At: $timestamp"
                        $lines += "Source: $SourcePath"
                        $lines += "Entries: $entryCount"
                        $lines += "Version: $moduleVersion"
                        $lines += ""
                    }

                    $lines += "=== Summary ==="
                    foreach ($key in $Summary.Keys) {
                        $lines += "$key : $($Summary[$key])"
                    }

                    $lines += ""
                    $lines += "=== Log Entries ==="

                    if (-not $hasEntries) {
                        $lines += "No log entries found"
                    } else {
                        foreach ($entry in $entriesToUse) {
                            $lines += ($entry | Out-String).Trim()
                            $lines += "-" * 40
                        }
                    }

                    $lines | Out-File -FilePath $OutputPath -Encoding UTF8
                } catch {
                    throw "Failed to export text report: $_"
                }
            }

            "Html" {
                try {
                    $sb = [System.Text.StringBuilder]::new()
                    $sb.AppendLine((Get-HtmlTemplate -Timestamp $timestamp -SourcePath $SourcePath -EntryCount $entryCount -ModuleVersion $moduleVersion)) | Out-Null

                    foreach ($key in $Summary.Keys) {
                        $value = Format-HtmlString -InputString $Summary[$key]
                        $sb.AppendLine("<li><strong>$(Format-HtmlString -InputString $key)</strong>: $value</li>") | Out-Null
                    }

                    $sb.AppendLine("</ul><h2>Entries</h2>") | Out-Null

                    if (-not $hasEntries) {
                        $sb.AppendLine("<p>No entries to display</p></body></html>") | Out-Null
                    } else {
                        $props = $entriesToUse[0].PSObject.Properties.Name
                        $sb.AppendLine("<table><thead><tr>") | Out-Null
                        foreach ($p in $props) {
                            $sb.AppendLine("<th>$(Format-HtmlString -InputString $p)</th>") | Out-Null
                        }
                        $sb.AppendLine("</tr></thead><tbody>") | Out-Null

                        foreach ($entry in $entriesToUse) {
                            $sb.AppendLine("<tr>") | Out-Null
                            foreach ($p in $props) {
                                $v = if ($null -eq $entry.$p) { '' } else { $entry.$p.ToString() }
                                $sb.AppendLine("<td>$(Format-HtmlString -InputString $v)</td>") | Out-Null
                            }
                            $sb.AppendLine("</tr>") | Out-Null
                        }

                        $sb.AppendLine("</tbody></table></body></html>") | Out-Null
                    }

                    $sb.ToString() | Out-File -FilePath $OutputPath -Encoding UTF8
                } catch {
                    throw "Failed to export HTML report: $_"
                }
            }

            default {
                throw "Unsupported format: $Format"
            }
        }

        Write-Progress -Activity "Exporting log report" -Status "Complete" -PercentComplete 100 -Completed

        if (Test-Path $OutputPath) {
            $file = Get-Item $OutputPath
            $size = [Math]::Round($file.Length / 1KB, 2)
            Write-Host "✅ Report exported to: $($file.FullName) ($size KB)" -ForegroundColor Green
        } else {
            Write-Host "✅ Report exported to: $OutputPath" -ForegroundColor Green
        }
    }
    catch {
        Write-Progress -Activity "Exporting log report" -Completed
        Write-Error "❌ Export failed: $_"
        throw
    }
}