// ============================================================================
// mb_clouseau - Report Generator
// Uncovering clues with MusicBee Clouseau
//
// Comprehensive export and reporting functionality:
// - Full diagnostic reports combining all data sources
// - Event log exports (JSON, CSV, TXT)
// - Metrics history exports
// - Plugin list exports
// - Compression support for large exports
// ============================================================================

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using MusicBeePlugin.Clouseau.Logging;
using MusicBeePlugin.Clouseau.Metrics;
using MusicBeePlugin.Clouseau.Introspection;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace MusicBeePlugin.Clouseau.Core
{
    /// <summary>
    /// Export format options for reports.
    /// </summary>
    public enum ReportFormat
    {
        /// <summary>
        /// JSON format for structured data interchange.
        /// </summary>
        Json,

        /// <summary>
        /// CSV format for spreadsheet import.
        /// </summary>
        Csv,

        /// <summary>
        /// Plain text format with human-readable layout.
        /// </summary>
        Text
    }

    /// <summary>
    /// Generates comprehensive diagnostic reports and exports data from
    /// EventLogger, MetricsCollector, and PluginDiscovery.
    /// </summary>
    public class ReportGenerator
    {
        private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();

        // Consistent date formats across all exports
        private const string TimestampFormat = "yyyy-MM-dd HH:mm:ss.fff";
        private const string DateOnlyFormat = "yyyy-MM-dd";
        private const string FileTimestampFormat = "yyyyMMdd_HHmmss";

        // Dependencies
        private readonly LogBuffer _logBuffer;
        private readonly MetricsCollector _metricsCollector;
        private readonly PluginDiscovery _pluginDiscovery;
        private readonly ClouseauSettings _settings;
        private readonly string _dataPath;
        private readonly string _exportsPath;

        // Session information
        private readonly DateTime _sessionStartTime;
        private readonly string _sessionId;

        /// <summary>
        /// Gets the path where exports are saved.
        /// </summary>
        public string ExportsPath => _exportsPath;

        /// <summary>
        /// Creates a new ReportGenerator instance.
        /// </summary>
        /// <param name="logBuffer">The log buffer containing event entries.</param>
        /// <param name="metricsCollector">The metrics collector for system metrics.</param>
        /// <param name="pluginDiscovery">The plugin discovery service.</param>
        /// <param name="settings">The Clouseau settings.</param>
        /// <param name="dataPath">The plugin data directory path.</param>
        public ReportGenerator(
            LogBuffer logBuffer,
            MetricsCollector metricsCollector,
            PluginDiscovery pluginDiscovery,
            ClouseauSettings settings,
            string dataPath)
        {
            _logBuffer = logBuffer ?? throw new ArgumentNullException(nameof(logBuffer));
            _metricsCollector = metricsCollector;
            _pluginDiscovery = pluginDiscovery;
            _settings = settings ?? new ClouseauSettings();
            _dataPath = dataPath ?? throw new ArgumentNullException(nameof(dataPath));

            // Set up exports directory
            _exportsPath = Path.Combine(_dataPath, "exports");
            EnsureDirectoryExists(_exportsPath);

            // Session info
            _sessionStartTime = DateTime.Now;
            _sessionId = Guid.NewGuid().ToString("N").Substring(0, 8);

            Logger.Debug($"ReportGenerator initialized. Exports path: {_exportsPath}");
        }

        #region Full Report Generation

        /// <summary>
        /// Generates a comprehensive diagnostic report combining all data sources.
        /// </summary>
        /// <param name="format">The output format for the report.</param>
        /// <param name="compress">Whether to compress the output file.</param>
        /// <returns>The path to the generated report file.</returns>
        public string GenerateFullReport(ReportFormat format = ReportFormat.Json, bool? compress = null)
        {
            var shouldCompress = compress ?? _settings.Export.CompressionEnabled;
            var timestamp = DateTime.Now.ToString(FileTimestampFormat);
            var baseName = $"clouseau_report_{timestamp}";

            Logger.Info($"Generating full diagnostic report (format: {format}, compress: {shouldCompress})");

            try
            {
                string filePath;
                string content;

                switch (format)
                {
                    case ReportFormat.Json:
                        filePath = Path.Combine(_exportsPath, baseName + ".json");
                        content = GenerateFullReportJson();
                        break;

                    case ReportFormat.Csv:
                        // For CSV, we export multiple files in a zip
                        return GenerateFullReportCsvBundle(baseName, shouldCompress);

                    case ReportFormat.Text:
                    default:
                        filePath = Path.Combine(_exportsPath, baseName + ".txt");
                        content = GenerateFullReportText();
                        break;
                }

                if (shouldCompress)
                {
                    var compressedPath = filePath + ".gz";
                    WriteCompressed(compressedPath, content);
                    Logger.Info($"Full report generated: {compressedPath}");
                    return compressedPath;
                }
                else
                {
                    File.WriteAllText(filePath, content, Encoding.UTF8);
                    Logger.Info($"Full report generated: {filePath}");
                    return filePath;
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "Failed to generate full report");
                throw;
            }
        }

        /// <summary>
        /// Generates the full report in JSON format.
        /// </summary>
        private string GenerateFullReportJson()
        {
            var report = new FullDiagnosticReport
            {
                ReportInfo = CreateReportInfo(),
                SystemInfo = CreateSystemInfo(),
                Events = GetEventSummary(),
                Metrics = CreateMetricsSummary(),
                Plugins = GetPluginList(),
                Alerts = GetActiveAlerts()
            };

            return JsonConvert.SerializeObject(report, Formatting.Indented, new JsonSerializerSettings
            {
                DateFormatString = TimestampFormat,
                NullValueHandling = NullValueHandling.Ignore,
                Converters = new List<JsonConverter> { new StringEnumConverter() }
            });
        }

        /// <summary>
        /// Generates the full report in plain text format.
        /// </summary>
        private string GenerateFullReportText()
        {
            var sb = new StringBuilder();

            // Header
            sb.AppendLine("================================================================================");
            sb.AppendLine("                     mb_clouseau DIAGNOSTIC REPORT");
            sb.AppendLine("================================================================================");
            sb.AppendLine();
            sb.AppendLine($"Generated:      {DateTime.Now.ToString(TimestampFormat)}");
            sb.AppendLine($"Session ID:     {_sessionId}");
            sb.AppendLine($"Session Start:  {_sessionStartTime.ToString(TimestampFormat)}");
            sb.AppendLine($"Session Uptime: {DateTime.Now - _sessionStartTime}");
            sb.AppendLine();

            // System Information
            sb.AppendLine("================================================================================");
            sb.AppendLine("SYSTEM INFORMATION");
            sb.AppendLine("================================================================================");
            sb.AppendLine();
            sb.AppendLine($"Machine Name:    {Environment.MachineName}");
            sb.AppendLine($"OS Version:      {Environment.OSVersion}");
            sb.AppendLine($"CLR Version:     {Environment.Version}");
            sb.AppendLine($"Processor Count: {Environment.ProcessorCount}");
            sb.AppendLine($"64-bit OS:       {Environment.Is64BitOperatingSystem}");
            sb.AppendLine($"64-bit Process:  {Environment.Is64BitProcess}");
            sb.AppendLine();

            // Metrics Summary
            if (_metricsCollector != null)
            {
                sb.AppendLine("================================================================================");
                sb.AppendLine("METRICS SUMMARY");
                sb.AppendLine("================================================================================");
                sb.AppendLine();

                var snapshot = _metricsCollector.GetCurrentSnapshot();
                if (snapshot != null)
                {
                    sb.AppendLine(snapshot.ToDetailedString());
                }
                else
                {
                    sb.AppendLine("No metrics data available.");
                }
                sb.AppendLine();
            }

            // Event Summary
            sb.AppendLine("================================================================================");
            sb.AppendLine("EVENT SUMMARY");
            sb.AppendLine("================================================================================");
            sb.AppendLine();
            sb.AppendLine($"Total Events in Buffer: {_logBuffer.Count}");
            sb.AppendLine($"Buffer Capacity:        {_logBuffer.MaxSize}");
            sb.AppendLine();

            // Event counts by category
            var entries = _logBuffer.GetAll().ToList();
            var categoryGroups = entries.GroupBy(e => e.Category)
                                        .OrderByDescending(g => g.Count());
            sb.AppendLine("Events by Category:");
            foreach (var group in categoryGroups)
            {
                sb.AppendLine($"  {group.Key,-15} : {group.Count(),6}");
            }
            sb.AppendLine();

            // Event counts by level
            var levelGroups = entries.GroupBy(e => e.Level)
                                     .OrderByDescending(g => g.Count());
            sb.AppendLine("Events by Level:");
            foreach (var group in levelGroups)
            {
                sb.AppendLine($"  {group.Key,-10} : {group.Count(),6}");
            }
            sb.AppendLine();

            // Recent Events (last 20)
            sb.AppendLine("Recent Events (last 20):");
            sb.AppendLine("-".PadRight(80, '-'));
            foreach (var entry in _logBuffer.GetRecent(20))
            {
                sb.AppendLine(entry.ToString());
            }
            sb.AppendLine();

            // Plugin List
            if (_pluginDiscovery != null)
            {
                sb.AppendLine("================================================================================");
                sb.AppendLine("DISCOVERED PLUGINS");
                sb.AppendLine("================================================================================");
                sb.AppendLine();
                sb.AppendLine(_pluginDiscovery.GetDiscoverySummary());
                sb.AppendLine();
            }

            // Alerts
            var alerts = GetActiveAlerts();
            if (alerts != null && alerts.Count > 0)
            {
                sb.AppendLine("================================================================================");
                sb.AppendLine("ACTIVE ALERTS");
                sb.AppendLine("================================================================================");
                sb.AppendLine();
                foreach (var alert in alerts)
                {
                    sb.AppendLine($"  [{alert.Severity}] {alert.Message}");
                    sb.AppendLine($"           Timestamp: {alert.Timestamp.ToString(TimestampFormat)}");
                    sb.AppendLine();
                }
            }

            // Footer
            sb.AppendLine("================================================================================");
            sb.AppendLine("                           END OF REPORT");
            sb.AppendLine("================================================================================");

            return sb.ToString();
        }

        /// <summary>
        /// Generates a CSV bundle with multiple files in a zip archive.
        /// </summary>
        private string GenerateFullReportCsvBundle(string baseName, bool compress)
        {
            var zipPath = Path.Combine(_exportsPath, baseName + ".zip");

            using (var zipStream = new FileStream(zipPath, FileMode.Create))
            using (var archive = new ZipArchive(zipStream, ZipArchiveMode.Create))
            {
                // Events CSV
                var eventsEntry = archive.CreateEntry("events.csv");
                using (var writer = new StreamWriter(eventsEntry.Open(), Encoding.UTF8))
                {
                    WriteEventsCsv(writer);
                }

                // Metrics CSV
                if (_metricsCollector != null)
                {
                    var metricsEntry = archive.CreateEntry("metrics.csv");
                    using (var writer = new StreamWriter(metricsEntry.Open(), Encoding.UTF8))
                    {
                        WriteMetricsCsv(writer);
                    }
                }

                // Plugins CSV
                if (_pluginDiscovery != null)
                {
                    var pluginsEntry = archive.CreateEntry("plugins.csv");
                    using (var writer = new StreamWriter(pluginsEntry.Open(), Encoding.UTF8))
                    {
                        WritePluginsCsv(writer);
                    }
                }

                // Summary text file
                var summaryEntry = archive.CreateEntry("summary.txt");
                using (var writer = new StreamWriter(summaryEntry.Open(), Encoding.UTF8))
                {
                    writer.Write(GenerateFullReportText());
                }
            }

            Logger.Info($"Full report bundle generated: {zipPath}");
            return zipPath;
        }

        #endregion

        #region Export Events

        /// <summary>
        /// Exports log entries to a file.
        /// </summary>
        /// <param name="format">The output format.</param>
        /// <param name="filter">Optional filter function to select entries.</param>
        /// <param name="compress">Whether to compress the output file.</param>
        /// <returns>The path to the exported file.</returns>
        public string ExportEvents(
            ReportFormat format = ReportFormat.Json,
            Func<LogEntry, bool> filter = null,
            bool? compress = null)
        {
            var shouldCompress = compress ?? _settings.Export.CompressionEnabled;
            var timestamp = DateTime.Now.ToString(FileTimestampFormat);
            var extension = GetFileExtension(format);
            var filePath = Path.Combine(_exportsPath, $"events_{timestamp}.{extension}");

            Logger.Info($"Exporting events (format: {format}, compress: {shouldCompress})");

            try
            {
                var entries = _logBuffer.GetAll();
                if (filter != null)
                {
                    entries = entries.Where(filter);
                }
                var entryList = entries.ToList();

                string content;
                switch (format)
                {
                    case ReportFormat.Json:
                        content = ExportEventsJson(entryList);
                        break;

                    case ReportFormat.Csv:
                        content = ExportEventsCsv(entryList);
                        break;

                    case ReportFormat.Text:
                    default:
                        content = ExportEventsText(entryList);
                        break;
                }

                if (shouldCompress)
                {
                    var compressedPath = filePath + ".gz";
                    WriteCompressed(compressedPath, content);
                    Logger.Info($"Events exported: {compressedPath} ({entryList.Count} entries)");
                    return compressedPath;
                }
                else
                {
                    File.WriteAllText(filePath, content, Encoding.UTF8);
                    Logger.Info($"Events exported: {filePath} ({entryList.Count} entries)");
                    return filePath;
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "Failed to export events");
                throw;
            }
        }

        /// <summary>
        /// Exports events in JSON format.
        /// </summary>
        private string ExportEventsJson(List<LogEntry> entries)
        {
            var export = new EventsExport
            {
                ExportInfo = new ExportInfo
                {
                    ExportedAt = DateTime.Now,
                    SessionId = _sessionId,
                    SessionStartTime = _sessionStartTime,
                    TotalEntries = entries.Count,
                    ExportFormat = "JSON"
                },
                Entries = entries
            };

            return JsonConvert.SerializeObject(export, Formatting.Indented, new JsonSerializerSettings
            {
                DateFormatString = TimestampFormat,
                NullValueHandling = NullValueHandling.Ignore
            });
        }

        /// <summary>
        /// Exports events in CSV format.
        /// </summary>
        private string ExportEventsCsv(List<LogEntry> entries)
        {
            var sb = new StringBuilder();
            sb.AppendLine("Timestamp,SequenceNumber,Level,Category,EventType,EventTypeValue,SourceFile,Message");

            foreach (var entry in entries)
            {
                sb.AppendLine(string.Join(",",
                    EscapeCsv(entry.Timestamp.ToString(TimestampFormat)),
                    entry.SequenceNumber,
                    EscapeCsv(entry.Level),
                    EscapeCsv(entry.Category),
                    EscapeCsv(entry.EventType),
                    entry.EventTypeValue,
                    EscapeCsv(entry.SourceFile),
                    EscapeCsv(entry.Message)
                ));
            }

            return sb.ToString();
        }

        /// <summary>
        /// Exports events in text format.
        /// </summary>
        private string ExportEventsText(List<LogEntry> entries)
        {
            var sb = new StringBuilder();
            sb.AppendLine("mb_clouseau Event Log Export");
            sb.AppendLine($"Exported: {DateTime.Now.ToString(TimestampFormat)}");
            sb.AppendLine($"Session ID: {_sessionId}");
            sb.AppendLine($"Session Start: {_sessionStartTime.ToString(TimestampFormat)}");
            sb.AppendLine($"Total Entries: {entries.Count}");
            sb.AppendLine(new string('=', 80));
            sb.AppendLine();

            foreach (var entry in entries)
            {
                sb.AppendLine(entry.ToString());

                if (entry.Context != null && entry.Context.Count > 0)
                {
                    foreach (var kvp in entry.Context)
                    {
                        sb.AppendLine($"    {kvp.Key}: {kvp.Value}");
                    }
                }
                sb.AppendLine();
            }

            return sb.ToString();
        }

        /// <summary>
        /// Writes events to a CSV StreamWriter.
        /// </summary>
        private void WriteEventsCsv(StreamWriter writer)
        {
            writer.WriteLine("Timestamp,SequenceNumber,Level,Category,EventType,EventTypeValue,SourceFile,Message");

            foreach (var entry in _logBuffer.GetAll())
            {
                writer.WriteLine(string.Join(",",
                    EscapeCsv(entry.Timestamp.ToString(TimestampFormat)),
                    entry.SequenceNumber,
                    EscapeCsv(entry.Level),
                    EscapeCsv(entry.Category),
                    EscapeCsv(entry.EventType),
                    entry.EventTypeValue,
                    EscapeCsv(entry.SourceFile),
                    EscapeCsv(entry.Message)
                ));
            }
        }

        #endregion

        #region Export Metrics

        /// <summary>
        /// Exports metrics history to a file.
        /// </summary>
        /// <param name="format">The output format.</param>
        /// <param name="maxSnapshots">Maximum number of snapshots to export.</param>
        /// <param name="compress">Whether to compress the output file.</param>
        /// <returns>The path to the exported file.</returns>
        public string ExportMetrics(
            ReportFormat format = ReportFormat.Json,
            int maxSnapshots = 100,
            bool? compress = null)
        {
            if (_metricsCollector == null)
            {
                throw new InvalidOperationException("MetricsCollector is not available");
            }

            var shouldCompress = compress ?? _settings.Export.CompressionEnabled;
            var timestamp = DateTime.Now.ToString(FileTimestampFormat);
            var extension = GetFileExtension(format);
            var filePath = Path.Combine(_exportsPath, $"metrics_{timestamp}.{extension}");

            Logger.Info($"Exporting metrics (format: {format}, max: {maxSnapshots}, compress: {shouldCompress})");

            try
            {
                var history = _metricsCollector.GetHistory(maxSnapshots);

                string content;
                switch (format)
                {
                    case ReportFormat.Json:
                        content = ExportMetricsJson(history);
                        break;

                    case ReportFormat.Csv:
                        content = ExportMetricsCsv(history);
                        break;

                    case ReportFormat.Text:
                    default:
                        content = ExportMetricsText(history);
                        break;
                }

                if (shouldCompress)
                {
                    var compressedPath = filePath + ".gz";
                    WriteCompressed(compressedPath, content);
                    Logger.Info($"Metrics exported: {compressedPath} ({history.Length} snapshots)");
                    return compressedPath;
                }
                else
                {
                    File.WriteAllText(filePath, content, Encoding.UTF8);
                    Logger.Info($"Metrics exported: {filePath} ({history.Length} snapshots)");
                    return filePath;
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "Failed to export metrics");
                throw;
            }
        }

        /// <summary>
        /// Exports metrics in JSON format.
        /// </summary>
        private string ExportMetricsJson(MetricsSnapshot[] history)
        {
            var export = new MetricsExport
            {
                ExportInfo = new ExportInfo
                {
                    ExportedAt = DateTime.Now,
                    SessionId = _sessionId,
                    SessionStartTime = _sessionStartTime,
                    TotalEntries = history.Length,
                    ExportFormat = "JSON"
                },
                CollectorInfo = new CollectorInfo
                {
                    IsRunning = _metricsCollector.IsRunning,
                    CollectionCount = _metricsCollector.CollectionCount,
                    Uptime = _metricsCollector.Uptime
                },
                CurrentSnapshot = _metricsCollector.GetCurrentSnapshot(),
                History = history
            };

            return JsonConvert.SerializeObject(export, Formatting.Indented, new JsonSerializerSettings
            {
                DateFormatString = TimestampFormat,
                NullValueHandling = NullValueHandling.Ignore
            });
        }

        /// <summary>
        /// Exports metrics in CSV format.
        /// </summary>
        private string ExportMetricsCsv(MetricsSnapshot[] history)
        {
            var sb = new StringBuilder();

            // Header
            sb.AppendLine("Timestamp,CpuPercent,MemoryPercent,AvailableMemoryMB,TotalMemoryMB," +
                         "MBWorkingSetMB,MBPrivateBytesMB,MBHandleCount,MBThreadCount," +
                         "GCGen0,GCGen1,GCGen2,ManagedHeapMB,GCTimePercent," +
                         "HandleCountDelta,PrivateBytesDelta,HandleLeakSuspected,MemoryLeakSuspected");

            foreach (var snapshot in history)
            {
                sb.AppendLine(string.Join(",",
                    EscapeCsv(snapshot.Timestamp.ToString(TimestampFormat)),
                    snapshot.CpuPercent.ToString("F1"),
                    snapshot.MemoryPercent.ToString("F1"),
                    snapshot.AvailableMemoryMB,
                    snapshot.TotalMemoryMB,
                    snapshot.MBWorkingSetMB,
                    snapshot.MBPrivateBytesMB,
                    snapshot.MBHandleCount,
                    snapshot.MBThreadCount,
                    snapshot.GCGen0Collections,
                    snapshot.GCGen1Collections,
                    snapshot.GCGen2Collections,
                    snapshot.ManagedHeapMB,
                    snapshot.GCTimePercent.ToString("F1"),
                    snapshot.HandleCountDelta,
                    snapshot.PrivateBytesDelta,
                    snapshot.HandleLeakSuspected,
                    snapshot.MemoryLeakSuspected
                ));
            }

            return sb.ToString();
        }

        /// <summary>
        /// Exports metrics in text format.
        /// </summary>
        private string ExportMetricsText(MetricsSnapshot[] history)
        {
            var sb = new StringBuilder();
            sb.AppendLine("mb_clouseau Metrics History Export");
            sb.AppendLine($"Exported: {DateTime.Now.ToString(TimestampFormat)}");
            sb.AppendLine($"Session ID: {_sessionId}");
            sb.AppendLine($"Session Start: {_sessionStartTime.ToString(TimestampFormat)}");
            sb.AppendLine($"Collector Uptime: {_metricsCollector.Uptime}");
            sb.AppendLine($"Total Collections: {_metricsCollector.CollectionCount}");
            sb.AppendLine($"Snapshots in Export: {history.Length}");
            sb.AppendLine(new string('=', 80));
            sb.AppendLine();

            // Current snapshot details
            sb.AppendLine("=== CURRENT SNAPSHOT ===");
            var current = _metricsCollector.GetCurrentSnapshot();
            if (current != null)
            {
                sb.AppendLine(current.ToDetailedString());
            }
            sb.AppendLine();

            // History summary
            sb.AppendLine("=== HISTORY (Newest First) ===");
            sb.AppendLine();

            foreach (var snapshot in history)
            {
                sb.AppendLine(snapshot.ToLogLine());
            }

            return sb.ToString();
        }

        /// <summary>
        /// Writes metrics to a CSV StreamWriter.
        /// </summary>
        private void WriteMetricsCsv(StreamWriter writer)
        {
            var history = _metricsCollector.GetHistory(1000);

            writer.WriteLine("Timestamp,CpuPercent,MemoryPercent,AvailableMemoryMB,TotalMemoryMB," +
                           "MBWorkingSetMB,MBPrivateBytesMB,MBHandleCount,MBThreadCount," +
                           "GCGen0,GCGen1,GCGen2,ManagedHeapMB");

            foreach (var snapshot in history)
            {
                writer.WriteLine(string.Join(",",
                    EscapeCsv(snapshot.Timestamp.ToString(TimestampFormat)),
                    snapshot.CpuPercent.ToString("F1"),
                    snapshot.MemoryPercent.ToString("F1"),
                    snapshot.AvailableMemoryMB,
                    snapshot.TotalMemoryMB,
                    snapshot.MBWorkingSetMB,
                    snapshot.MBPrivateBytesMB,
                    snapshot.MBHandleCount,
                    snapshot.MBThreadCount,
                    snapshot.GCGen0Collections,
                    snapshot.GCGen1Collections,
                    snapshot.GCGen2Collections,
                    snapshot.ManagedHeapMB
                ));
            }
        }

        #endregion

        #region Export Plugins

        /// <summary>
        /// Exports the list of discovered plugins to a file.
        /// </summary>
        /// <param name="format">The output format.</param>
        /// <param name="compress">Whether to compress the output file.</param>
        /// <returns>The path to the exported file.</returns>
        public string ExportPluginList(
            ReportFormat format = ReportFormat.Json,
            bool? compress = null)
        {
            if (_pluginDiscovery == null)
            {
                throw new InvalidOperationException("PluginDiscovery is not available");
            }

            var shouldCompress = compress ?? _settings.Export.CompressionEnabled;
            var timestamp = DateTime.Now.ToString(FileTimestampFormat);
            var extension = GetFileExtension(format);
            var filePath = Path.Combine(_exportsPath, $"plugins_{timestamp}.{extension}");

            Logger.Info($"Exporting plugin list (format: {format}, compress: {shouldCompress})");

            try
            {
                var plugins = _pluginDiscovery.DiscoverPlugins();

                string content;
                switch (format)
                {
                    case ReportFormat.Json:
                        content = ExportPluginsJson(plugins);
                        break;

                    case ReportFormat.Csv:
                        content = ExportPluginsCsv(plugins);
                        break;

                    case ReportFormat.Text:
                    default:
                        content = ExportPluginsText(plugins);
                        break;
                }

                if (shouldCompress)
                {
                    var compressedPath = filePath + ".gz";
                    WriteCompressed(compressedPath, content);
                    Logger.Info($"Plugins exported: {compressedPath} ({plugins.Count} plugins)");
                    return compressedPath;
                }
                else
                {
                    File.WriteAllText(filePath, content, Encoding.UTF8);
                    Logger.Info($"Plugins exported: {filePath} ({plugins.Count} plugins)");
                    return filePath;
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "Failed to export plugin list");
                throw;
            }
        }

        /// <summary>
        /// Exports plugins in JSON format.
        /// </summary>
        private string ExportPluginsJson(List<DiscoveredPlugin> plugins)
        {
            var export = new PluginsExport
            {
                ExportInfo = new ExportInfo
                {
                    ExportedAt = DateTime.Now,
                    SessionId = _sessionId,
                    SessionStartTime = _sessionStartTime,
                    TotalEntries = plugins.Count,
                    ExportFormat = "JSON"
                },
                PluginsPath = _pluginDiscovery.PluginsPath,
                ValidPluginCount = plugins.Count(p => p.IsValidPlugin),
                InvalidPluginCount = plugins.Count(p => !p.IsValidPlugin),
                Plugins = plugins
            };

            return JsonConvert.SerializeObject(export, Formatting.Indented, new JsonSerializerSettings
            {
                DateFormatString = TimestampFormat,
                NullValueHandling = NullValueHandling.Ignore
            });
        }

        /// <summary>
        /// Exports plugins in CSV format.
        /// </summary>
        private string ExportPluginsCsv(List<DiscoveredPlugin> plugins)
        {
            var sb = new StringBuilder();

            // Header
            sb.AppendLine("FileName,PluginName,PluginAuthor,PluginType,Version,IsValid,FileSizeBytes,LastModified,LoadError");

            foreach (var plugin in plugins)
            {
                var version = plugin.IsValidPlugin
                    ? $"{plugin.VersionMajor}.{plugin.VersionMinor}.{plugin.Revision}"
                    : plugin.Version ?? "";

                sb.AppendLine(string.Join(",",
                    EscapeCsv(plugin.FileName),
                    EscapeCsv(plugin.PluginName ?? ""),
                    EscapeCsv(plugin.PluginAuthor ?? ""),
                    EscapeCsv(plugin.PluginType ?? ""),
                    EscapeCsv(version),
                    plugin.IsValidPlugin,
                    plugin.FileSizeBytes,
                    EscapeCsv(plugin.LastModified.ToString(TimestampFormat)),
                    EscapeCsv(plugin.LoadError ?? "")
                ));
            }

            return sb.ToString();
        }

        /// <summary>
        /// Exports plugins in text format.
        /// </summary>
        private string ExportPluginsText(List<DiscoveredPlugin> plugins)
        {
            var sb = new StringBuilder();
            sb.AppendLine("mb_clouseau Plugin List Export");
            sb.AppendLine($"Exported: {DateTime.Now.ToString(TimestampFormat)}");
            sb.AppendLine($"Plugins Path: {_pluginDiscovery.PluginsPath}");
            sb.AppendLine(new string('=', 80));
            sb.AppendLine();
            sb.AppendLine(_pluginDiscovery.GetDiscoverySummary());

            return sb.ToString();
        }

        /// <summary>
        /// Writes plugins to a CSV StreamWriter.
        /// </summary>
        private void WritePluginsCsv(StreamWriter writer)
        {
            var plugins = _pluginDiscovery.DiscoverPlugins();

            writer.WriteLine("FileName,PluginName,PluginAuthor,PluginType,Version,IsValid,FileSizeBytes,LastModified");

            foreach (var plugin in plugins)
            {
                var version = plugin.IsValidPlugin
                    ? $"{plugin.VersionMajor}.{plugin.VersionMinor}.{plugin.Revision}"
                    : plugin.Version ?? "";

                writer.WriteLine(string.Join(",",
                    EscapeCsv(plugin.FileName),
                    EscapeCsv(plugin.PluginName ?? ""),
                    EscapeCsv(plugin.PluginAuthor ?? ""),
                    EscapeCsv(plugin.PluginType ?? ""),
                    EscapeCsv(version),
                    plugin.IsValidPlugin,
                    plugin.FileSizeBytes,
                    EscapeCsv(plugin.LastModified.ToString(TimestampFormat))
                ));
            }
        }

        #endregion

        #region Helper Methods

        /// <summary>
        /// Creates report metadata.
        /// </summary>
        private ReportInfo CreateReportInfo()
        {
            return new ReportInfo
            {
                GeneratedAt = DateTime.Now,
                SessionId = _sessionId,
                SessionStartTime = _sessionStartTime,
                SessionUptime = DateTime.Now - _sessionStartTime,
                ClouseauVersion = GetClouseauVersion(),
                DataPath = _dataPath
            };
        }

        /// <summary>
        /// Creates system information section.
        /// </summary>
        private SystemInfo CreateSystemInfo()
        {
            return new SystemInfo
            {
                MachineName = Environment.MachineName,
                OSVersion = Environment.OSVersion.ToString(),
                ClrVersion = Environment.Version.ToString(),
                ProcessorCount = Environment.ProcessorCount,
                Is64BitOperatingSystem = Environment.Is64BitOperatingSystem,
                Is64BitProcess = Environment.Is64BitProcess,
                WorkingSet = Environment.WorkingSet
            };
        }

        /// <summary>
        /// Gets event summary statistics.
        /// </summary>
        private EventsSummary GetEventSummary()
        {
            var entries = _logBuffer.GetAll().ToList();

            return new EventsSummary
            {
                TotalCount = entries.Count,
                BufferCapacity = _logBuffer.MaxSize,
                ByCategory = entries.GroupBy(e => e.Category)
                                    .ToDictionary(g => g.Key ?? "Unknown", g => g.Count()),
                ByLevel = entries.GroupBy(e => e.Level)
                                 .ToDictionary(g => g.Key ?? "Unknown", g => g.Count()),
                OldestEntry = entries.FirstOrDefault()?.Timestamp,
                NewestEntry = entries.LastOrDefault()?.Timestamp,
                RecentEntries = _logBuffer.GetRecent(10).ToList()
            };
        }

        /// <summary>
        /// Creates metrics summary section.
        /// </summary>
        private MetricsSummary CreateMetricsSummary()
        {
            if (_metricsCollector == null)
                return null;

            var current = _metricsCollector.GetCurrentSnapshot();
            var history = _metricsCollector.GetHistory(10);

            return new MetricsSummary
            {
                IsRunning = _metricsCollector.IsRunning,
                CollectionCount = _metricsCollector.CollectionCount,
                Uptime = _metricsCollector.Uptime,
                CurrentSnapshot = current,
                RecentHistory = history.ToList()
            };
        }

        /// <summary>
        /// Gets the list of discovered plugins.
        /// </summary>
        private List<DiscoveredPlugin> GetPluginList()
        {
            return _pluginDiscovery?.DiscoverPlugins() ?? new List<DiscoveredPlugin>();
        }

        /// <summary>
        /// Gets active alerts from the current metrics snapshot.
        /// </summary>
        private List<Alert> GetActiveAlerts()
        {
            var alerts = new List<Alert>();

            if (_metricsCollector != null)
            {
                var snapshot = _metricsCollector.GetCurrentSnapshot();
                if (snapshot != null)
                {
                    if (snapshot.HandleLeakSuspected)
                    {
                        alerts.Add(new Alert
                        {
                            Severity = "Warning",
                            Type = "HandleLeak",
                            Message = $"Handle leak suspected. Handles: {snapshot.MBHandleCount}, " +
                                     $"Trend: +{snapshot.HandleCountTrendTotal} over {snapshot.TrendSampleCount} samples",
                            Timestamp = snapshot.Timestamp
                        });
                    }

                    if (snapshot.MemoryLeakSuspected)
                    {
                        alerts.Add(new Alert
                        {
                            Severity = "Warning",
                            Type = "MemoryLeak",
                            Message = $"Memory leak suspected. Private bytes: {snapshot.MBPrivateBytesMB}MB, " +
                                     $"Trend: +{FormatBytes(snapshot.PrivateBytesTrendTotal)} over {snapshot.TrendSampleCount} samples",
                            Timestamp = snapshot.Timestamp
                        });
                    }

                    if (snapshot.GCPressureHigh)
                    {
                        alerts.Add(new Alert
                        {
                            Severity = "Warning",
                            Type = "GCPressure",
                            Message = $"High GC pressure. Gen2: {snapshot.GCGen2Collections}, " +
                                     $"Time in GC: {snapshot.GCTimePercent:F1}%",
                            Timestamp = snapshot.Timestamp
                        });
                    }

                    if (snapshot.LowMemoryWarning)
                    {
                        alerts.Add(new Alert
                        {
                            Severity = "Warning",
                            Type = "LowMemory",
                            Message = $"Low system memory. Available: {snapshot.AvailableMemoryMB}MB / " +
                                     $"{snapshot.TotalMemoryMB}MB ({snapshot.MemoryPercent:F1}% used)",
                            Timestamp = snapshot.Timestamp
                        });
                    }
                }
            }

            return alerts;
        }

        /// <summary>
        /// Gets the file extension for the given format.
        /// </summary>
        private string GetFileExtension(ReportFormat format)
        {
            switch (format)
            {
                case ReportFormat.Json:
                    return "json";
                case ReportFormat.Csv:
                    return "csv";
                case ReportFormat.Text:
                default:
                    return "txt";
            }
        }

        /// <summary>
        /// Escapes a value for CSV output.
        /// </summary>
        private string EscapeCsv(string value)
        {
            if (string.IsNullOrEmpty(value))
                return "";

            // If value contains comma, quote, or newline, wrap in quotes and escape quotes
            if (value.Contains(",") || value.Contains("\"") || value.Contains("\n") || value.Contains("\r"))
            {
                return "\"" + value.Replace("\"", "\"\"") + "\"";
            }

            return value;
        }

        /// <summary>
        /// Writes content to a gzip-compressed file.
        /// </summary>
        private void WriteCompressed(string path, string content)
        {
            using (var fileStream = new FileStream(path, FileMode.Create))
            using (var gzipStream = new GZipStream(fileStream, CompressionLevel.Optimal))
            using (var writer = new StreamWriter(gzipStream, Encoding.UTF8))
            {
                writer.Write(content);
            }
        }

        /// <summary>
        /// Ensures a directory exists, creating it if necessary.
        /// </summary>
        private void EnsureDirectoryExists(string path)
        {
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
        }

        /// <summary>
        /// Formats bytes as human-readable string.
        /// </summary>
        private static string FormatBytes(long bytes)
        {
            if (bytes < 0) bytes = Math.Abs(bytes);

            if (bytes >= 1024 * 1024 * 1024)
                return $"{bytes / (1024.0 * 1024 * 1024):F1}GB";
            if (bytes >= 1024 * 1024)
                return $"{bytes / (1024.0 * 1024):F1}MB";
            if (bytes >= 1024)
                return $"{bytes / 1024.0:F1}KB";
            return $"{bytes}B";
        }

        /// <summary>
        /// Gets the Clouseau plugin version.
        /// </summary>
        private string GetClouseauVersion()
        {
            try
            {
                var assembly = System.Reflection.Assembly.GetExecutingAssembly();
                var version = assembly.GetName().Version;
                return version?.ToString() ?? "Unknown";
            }
            catch
            {
                return "Unknown";
            }
        }

        #endregion
    }

    #region Data Transfer Objects

    /// <summary>
    /// Full diagnostic report structure.
    /// </summary>
    public class FullDiagnosticReport
    {
        public ReportInfo ReportInfo { get; set; }
        public SystemInfo SystemInfo { get; set; }
        public EventsSummary Events { get; set; }
        public MetricsSummary Metrics { get; set; }
        public List<DiscoveredPlugin> Plugins { get; set; }
        public List<Alert> Alerts { get; set; }
    }

    /// <summary>
    /// Report metadata.
    /// </summary>
    public class ReportInfo
    {
        public DateTime GeneratedAt { get; set; }
        public string SessionId { get; set; }
        public DateTime SessionStartTime { get; set; }
        public TimeSpan SessionUptime { get; set; }
        public string ClouseauVersion { get; set; }
        public string DataPath { get; set; }
    }

    /// <summary>
    /// System information.
    /// </summary>
    public class SystemInfo
    {
        public string MachineName { get; set; }
        public string OSVersion { get; set; }
        public string ClrVersion { get; set; }
        public int ProcessorCount { get; set; }
        public bool Is64BitOperatingSystem { get; set; }
        public bool Is64BitProcess { get; set; }
        public long WorkingSet { get; set; }
    }

    /// <summary>
    /// Events summary.
    /// </summary>
    public class EventsSummary
    {
        public int TotalCount { get; set; }
        public int BufferCapacity { get; set; }
        public Dictionary<string, int> ByCategory { get; set; }
        public Dictionary<string, int> ByLevel { get; set; }
        public DateTime? OldestEntry { get; set; }
        public DateTime? NewestEntry { get; set; }
        public List<LogEntry> RecentEntries { get; set; }
    }

    /// <summary>
    /// Metrics summary.
    /// </summary>
    public class MetricsSummary
    {
        public bool IsRunning { get; set; }
        public int CollectionCount { get; set; }
        public TimeSpan Uptime { get; set; }
        public MetricsSnapshot CurrentSnapshot { get; set; }
        public List<MetricsSnapshot> RecentHistory { get; set; }
    }

    /// <summary>
    /// Alert information.
    /// </summary>
    public class Alert
    {
        public string Severity { get; set; }
        public string Type { get; set; }
        public string Message { get; set; }
        public DateTime Timestamp { get; set; }
    }

    /// <summary>
    /// Export metadata.
    /// </summary>
    public class ExportInfo
    {
        public DateTime ExportedAt { get; set; }
        public string SessionId { get; set; }
        public DateTime SessionStartTime { get; set; }
        public int TotalEntries { get; set; }
        public string ExportFormat { get; set; }
    }

    /// <summary>
    /// Events export structure.
    /// </summary>
    public class EventsExport
    {
        public ExportInfo ExportInfo { get; set; }
        public List<LogEntry> Entries { get; set; }
    }

    /// <summary>
    /// Metrics export structure.
    /// </summary>
    public class MetricsExport
    {
        public ExportInfo ExportInfo { get; set; }
        public CollectorInfo CollectorInfo { get; set; }
        public MetricsSnapshot CurrentSnapshot { get; set; }
        public MetricsSnapshot[] History { get; set; }
    }

    /// <summary>
    /// Collector information.
    /// </summary>
    public class CollectorInfo
    {
        public bool IsRunning { get; set; }
        public int CollectionCount { get; set; }
        public TimeSpan Uptime { get; set; }
    }

    /// <summary>
    /// Plugins export structure.
    /// </summary>
    public class PluginsExport
    {
        public ExportInfo ExportInfo { get; set; }
        public string PluginsPath { get; set; }
        public int ValidPluginCount { get; set; }
        public int InvalidPluginCount { get; set; }
        public List<DiscoveredPlugin> Plugins { get; set; }
    }

    #endregion
}
