using Spectre.Console;
using VigilCare.Simulation;

public static class SimulatorConsole
{
    public static void Header(string title, string? description = null)
    {
        AnsiConsole.Write(new Rule($"[bold]{title}[/]").LeftJustified());
        if (description is not null)
            AnsiConsole.MarkupLine($"[dim]{description}[/]");
        AnsiConsole.WriteLine();
    }

    public static void Event(string simTime, string message) =>
        AnsiConsole.MarkupLine($"[green][[{simTime}]][/] {Markup.Escape(message)}");

    public static void Warn(string message) =>
        AnsiConsole.MarkupLine($"[yellow]{Markup.Escape(message)}[/]");

    public static void Error(string message) =>
        AnsiConsole.MarkupLine($"[red]{Markup.Escape(message)}[/]");

    public static void Info(string message) =>
        AnsiConsole.MarkupLine($"[blue]{Markup.Escape(message)}[/]");

    public static void DryRun(string message) =>
        AnsiConsole.MarkupLine($"[dim]DRY-RUN:[/] {Markup.Escape(message)}");

    public static void Success(string message) =>
        AnsiConsole.MarkupLine($"[bold green]{Markup.Escape(message)}[/]");

    public static void Wait(double deltaMinutes, int delayMs) =>
        AnsiConsole.MarkupLine(
            $"[dim]  ⏳ waiting {deltaMinutes:F0}m simulated ({delayMs / 1000.0:F1}s real)...[/]");

    public static void Divider() =>
        AnsiConsole.Write(new Rule().RuleStyle(Style.Parse("dim")));

    public static void Summary(ReplayResult r)
    {
        AnsiConsole.WriteLine();
        var table = new Table().AddColumn("Metric").AddColumn("Value");
        table.AddRow("Scenario", r.ScenarioId);
        table.AddRow("Observations sent", r.ObservationsSent.ToString());
        table.AddRow("Medications sent", r.MedicationsSent.ToString());
        if (r.MedicationsSkipped > 0)
            table.AddRow("Medications skipped", r.MedicationsSkipped.ToString());
        table.AddRow("Orders placed", r.OrdersPlaced.ToString());
        table.AddRow("Orders resulted", r.OrdersResulted.ToString());
        table.AddRow("Wall-clock time", $"{r.Duration.TotalSeconds:F1}s");
        if (r.HadExpectedOutcomes)
        {
            table.AddRow("Expected outcomes",
                r.OutcomeFailures.Count > 0
                    ? $"[red]{r.OutcomeFailures.Count} failed[/]"
                    : "[green]passed[/]");
        }
        AnsiConsole.Write(table);
    }

    public static void BatchSummary(List<ReplayResult> results)
    {
        AnsiConsole.WriteLine();
        AnsiConsole.Write(new Rule("[bold]Batch Summary[/]").LeftJustified());
        var table = new Table()
            .AddColumn("Scenario")
            .AddColumn("Observations")
            .AddColumn("Medications")
            .AddColumn("Time");
        foreach (var r in results)
            table.AddRow(r.ScenarioId, r.ObservationsSent.ToString(),
                r.MedicationsSent.ToString(), $"{r.Duration.TotalSeconds:F1}s");
        AnsiConsole.Write(table);
    }

    public static void PollResults(string simTime, PollResult poll)
    {
        if (poll.News2 is not null)
            AnsiConsole.MarkupLine(
                $"[cyan][[{simTime}]][/] NEWS2 = {poll.News2.TotalScore} ({poll.News2.RiskLevel})");

        if (poll.Gcs is not null)
            AnsiConsole.MarkupLine(
                $"[cyan][[{simTime}]][/] GCS = {poll.Gcs.TotalScore}/15 ({poll.Gcs.Classification}) " +
                $"E{poll.Gcs.EyeScore} V{poll.Gcs.VerbalScore} M{poll.Gcs.MotorScore}");

        if (poll.Sofa is not null)
        {
            var delta = poll.Sofa.DeltaFromBaseline is int d ? $" Δ+{d}" : "";
            AnsiConsole.MarkupLine(
                $"[cyan][[{simTime}]][/] SOFA = {poll.Sofa.TotalScore}/24{delta}");
        }

        if (poll.Qsofa is not null)
            AnsiConsole.MarkupLine(
                $"[cyan][[{simTime}]][/] qSOFA screen = {poll.Qsofa.ActiveCriteria}/3");

        foreach (var alert in poll.NewAlerts)
        {
            var line = $"[red][[{simTime}]][/] ALERT {alert.AlertType} ({alert.Severity})";
            if (!string.IsNullOrWhiteSpace(alert.Explanation?.NarrativeSummary))
                line += $" — {Markup.Escape(alert.Explanation.NarrativeSummary)}";
            AnsiConsole.MarkupLine(line);
        }

        if (poll.SepsisBundle is not null)
            AnsiConsole.MarkupLine(
                $"[cyan][[{simTime}]][/] SEPSIS BUNDLE {poll.SepsisBundle.ComplianceStatus} " +
                $"({poll.SepsisBundle.ElementsCompleted}/4) " +
                $"trigger={poll.SepsisBundle.TriggeringAlertType}");
    }
}