public static class AlertExplanationBuilder
{
    public static AlertExplanation Build(
        string scoringLabel,
        int? totalScore,
        List<ScoreContributor> contributors,
        TrendContext? trend = null,
        MedicationContext? medication = null)
    {
        return new AlertExplanation
        {
            ScoreContributors = contributors,
            Trend = trend,
            MedicationContext = medication,
            NarrativeSummary = BuildNarrative(scoringLabel, totalScore, contributors, trend, medication)
        };
    }

    private static string BuildNarrative(
        string scoringLabel,
        int? totalScore,
        List<ScoreContributor> contributors,
        TrendContext? trend,
        MedicationContext? medication)
    {
        var elevated = contributors.Where(c => c.Points > 0).ToList();
        if (elevated.Count == 0)
            elevated = contributors;

        var headline = totalScore.HasValue
            ? $"{scoringLabel} {totalScore} — "
            : $"{scoringLabel} — ";

        var contributorText = string.Join(", ",
            elevated.Select(c => $"{c.Parameter.ToLowerInvariant()} (+{c.Points})"));

        var parts = new List<string> { headline + contributorText };

        if (trend is not null)
        {
            parts.Add(
                $"{trend.Parameter} {trend.Direction.ToLowerInvariant()} " +
                $"{trend.PercentChange:F0}% over {FormatDuration(trend.Duration)}.");
        }

        if (medication is not null)
        {
            var minutesAgo = (int)(DateTimeOffset.UtcNow - medication.AdministeredAt).TotalMinutes;
            var medLine =
                $"{medication.DrugName} {medication.Dose} {medication.Route} " +
                $"administered {minutesAgo} minutes ago";
            if (!string.IsNullOrEmpty(medication.RelevanceNote))
                medLine += $" ({medication.RelevanceNote})";
            parts.Add(medLine);
        }

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

    private static string FormatDuration(TimeSpan duration)
    {
        if (duration.TotalHours >= 1)
        {
            var hours = (int)duration.TotalHours;
            return $"{hours} hour{(hours == 1 ? "" : "s")}";
        }

        var minutes = (int)duration.TotalMinutes;
        return $"{minutes} minute{(minutes == 1 ? "" : "s")}";
    }
}
