@using EntKube.Web.Services

@* ═══════════════════════════════════════════════════════════════════════════
   MetricChart — renders a time-series as an SVG area chart with gradient fill.
   Purely server-rendered, no JS dependencies. Responsive via viewBox.
   ═══════════════════════════════════════════════════════════════════════════ *@

<div class="metric-chart-container">
    @if (!string.IsNullOrEmpty(Title))
    {
        <div class="d-flex justify-content-between align-items-center mb-1">
            <small class="text-muted fw-medium">@Title</small>
            @if (DataPoints.Count > 0)
            {
                <small class="fw-bold @GetValueColorClass()">@CurrentValue</small>
            }
        </div>
    }

    @if (DataPoints.Count >= 2)
    {
        <svg viewBox="0 0 @Width @Height" preserveAspectRatio="none"
             style="width: 100%; height: @(HeightPx)px; display: block;">
            <defs>
                <linearGradient id="@GradientId" x1="0%" y1="0%" x2="0%" y2="100%">
                    <stop offset="0%" style="stop-color: @Color; stop-opacity: 0.3;" />
                    <stop offset="100%" style="stop-color: @Color; stop-opacity: 0.02;" />
                </linearGradient>
            </defs>

            @* Area fill below the line *@
            <path d="@AreaPath" fill="url(#@GradientId)" />

            @* The line itself *@
            <polyline points="@LinePath" fill="none" stroke="@Color" stroke-width="1.5"
                      stroke-linecap="round" stroke-linejoin="round" />
        </svg>
    }
    else
    {
        <div class="text-center py-2">
            <small class="text-muted">Insufficient data</small>
        </div>
    }
</div>

@code {
    [Parameter] public string? Title { get; set; }
    [Parameter] public List<TimeSeriesDataPoint> DataPoints { get; set; } = [];
    [Parameter] public string Color { get; set; } = "#0d6efd";
    [Parameter] public string? Unit { get; set; }
    [Parameter] public int HeightPx { get; set; } = 60;
    [Parameter] public double? MaxValue { get; set; }

    private const int Width = 300;
    private const int Height = 80;
    private const int Padding = 2;

    private string GradientId => $"grad-{Title?.GetHashCode():x}";

    private string CurrentValue
    {
        get
        {
            if (DataPoints.Count == 0)
            {
                return "";
            }

            double last = DataPoints[^1].Value;
            string formatted = last >= 100 ? last.ToString("F0") : last.ToString("F1");
            return Unit is not null ? $"{formatted}{Unit}" : formatted;
        }
    }

    private string LinePath
    {
        get
        {
            if (DataPoints.Count < 2)
            {
                return "";
            }

            double minVal = 0;
            double maxVal = MaxValue ?? DataPoints.Max(d => d.Value);
            if (maxVal <= minVal)
            {
                maxVal = minVal + 1;
            }

            double xStep = (double)(Width - 2 * Padding) / (DataPoints.Count - 1);

            List<string> points = [];
            for (int i = 0; i < DataPoints.Count; i++)
            {
                double x = Padding + i * xStep;
                double y = Height - Padding - ((DataPoints[i].Value - minVal) / (maxVal - minVal) * (Height - 2 * Padding));
                points.Add($"{x:F1},{y:F1}");
            }

            return string.Join(" ", points);
        }
    }

    private string AreaPath
    {
        get
        {
            if (DataPoints.Count < 2)
            {
                return "";
            }

            double minVal = 0;
            double maxVal = MaxValue ?? DataPoints.Max(d => d.Value);
            if (maxVal <= minVal)
            {
                maxVal = minVal + 1;
            }

            double xStep = (double)(Width - 2 * Padding) / (DataPoints.Count - 1);

            // Start at the bottom-left corner.
            List<string> pathParts = [$"M {Padding:F1},{Height - Padding:F1}"];

            // Line to first data point.
            for (int i = 0; i < DataPoints.Count; i++)
            {
                double x = Padding + i * xStep;
                double y = Height - Padding - ((DataPoints[i].Value - minVal) / (maxVal - minVal) * (Height - 2 * Padding));
                pathParts.Add($"L {x:F1},{y:F1}");
            }

            // Close back to bottom-right.
            double lastX = Padding + (DataPoints.Count - 1) * xStep;
            pathParts.Add($"L {lastX:F1},{Height - Padding:F1}");
            pathParts.Add("Z");

            return string.Join(" ", pathParts);
        }
    }

    private string GetValueColorClass()
    {
        if (DataPoints.Count == 0)
        {
            return "";
        }

        double last = DataPoints[^1].Value;
        return last switch
        {
            >= 90 => "text-danger",
            >= 70 => "text-warning",
            _ => "text-success"
        };
    }
}
