using EonaCat.LogStack.Analytics;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace EonaCat.LogStack;

// This file is part of the EonaCat project(s) which is released under the Apache License.
// See the LICENSE file or go to https://EonaCat.com/License for full license details.

/// <summary>
/// Comprehensive metrics about the logger
/// </summary>
public class LoggerMetrics
{
    public long TotalLogged { get; set; }
    public long TotalDropped { get; set; }
    public long TotalExceptions { get; set; }
    public long TotalBytes { get; set; }
    public double WritesPerSecond { get; set; }
    public long TraceCount { get; set; }
    public long DebugCount { get; set; }
    public long InformationCount { get; set; }
    public long WarningCount { get; set; }
    public long ErrorCount { get; set; }
    public long CriticalCount { get; set; }
    public long SpanCount { get; set; }
    public long ActiveOperations { get; set; }
    public double P50LatencyMs { get; set; }
    public double P95LatencyMs { get; set; }
    public double P99LatencyMs { get; set; }
    public long UptimeMilliseconds { get; set; }
    public List<FlowStatisticsSnapshot> FlowMetrics { get; set; } = new();

    /// <summary>
    /// Gets the success rate (logged / (logged + dropped))
    /// </summary>
    public double SuccessRate
    {
        get
        {
            var total = TotalLogged + TotalDropped;
            return total > 0 ? (TotalLogged * 100.0) / total : 100;
        }
    }

    /// <summary>
    /// Gets average bytes per event
    /// </summary>
    public double AverageBytesPerEvent
    {
        get => TotalLogged > 0 ? TotalBytes / (double)TotalLogged : 0;
    }

    /// <summary>
    /// Returns formatted report
    /// </summary>
    public override string ToString()
    {
        var sb = new StringBuilder();
        sb.AppendLine("===== LOGGER METRICS =====");
        sb.AppendLine($"Total Logged: {TotalLogged:N0}");
        sb.AppendLine($"Total Dropped: {TotalDropped:N0}");
        sb.AppendLine($"Success Rate: {SuccessRate:F2}%");
        sb.AppendLine($"Total Exceptions: {TotalExceptions:N0}");
        sb.AppendLine($"Total Bytes: {TotalBytes:N0}");
        sb.AppendLine($"Average Bytes/Event: {AverageBytesPerEvent:F2}");
        sb.AppendLine($"Writes/Second: {WritesPerSecond:F2}");
        sb.AppendLine();

        sb.AppendLine("Events by Level:");
        sb.AppendLine($"  Trace: {TraceCount:N0}");
        sb.AppendLine($"  Debug: {DebugCount:N0}");
        sb.AppendLine($"  Information: {InformationCount:N0}");
        sb.AppendLine($"  Warning: {WarningCount:N0}");
        sb.AppendLine($"  Error: {ErrorCount:N0}");
        sb.AppendLine($"  Critical: {CriticalCount:N0}");
        sb.AppendLine();

        sb.AppendLine($"Uptime: {System.TimeSpan.FromMilliseconds(UptimeMilliseconds):hh\\:mm\\:ss}");

        if (FlowMetrics.Count > 0)
        {
            sb.AppendLine();
            sb.AppendLine("Flow Statistics:");
            foreach (var flow in FlowMetrics)
            {
                sb.AppendLine($"  {flow.FlowName} ({flow.FlowType}): {flow.EventsProcessed:N0} events, {flow.SuccessRate:F2}% success");
            }
        }

        sb.AppendLine("==========================");
        return sb.ToString();
    }
}
