// Tests for the runs history table: status/trigger badge tones, the
// regions ok/total cell, and the fleet cost/savings summary math.

import { describe, expect, it } from "vitest";
import { render, screen, within } from "@testing-library/react";
import { RunsTable } from "@/components/runs/RunsTable";
import type { RunStatus, RunSummaryFile, SummaryRow } from "@/lib/api-types";

// ---------- fixture builders ----------

function makeRow(over: Partial<SummaryRow> = {}): SummaryRow {
  return {
    runId: "run-20260831T120000",
    regionKey: "aws-us-east-1",
    vendor: "aws",
    monthlyCostUsd: 100,
    potentialMonthlySavingsUsd: 10,
    bestScenario: "current",
    bestScenarioNodes: 5,
    nodeCount: 5,
    workloadCount: 20,
    idleCount: 1,
    overprovisionedCount: 2,
    reverseAdjustmentCount: 0,
    pricingMissing: false,
    finishedAt: "2026-08-31T12:00:00Z",
    ...over,
  };
}

function makeRun(
  status: RunStatus,
  regions: SummaryRow[],
  over: Partial<RunSummaryFile> = {},
): RunSummaryFile {
  return {
    runId: "run-20260831T122000",
    trigger: "schedule",
    status,
    startedAt: "2026-08-31T12:00:00Z",
    finishedAt: "2026-08-31T12:20:00Z",
    regions,
    ...over,
  };
}

// ---------- status + trigger badges ----------

describe("RunsTable badges", () => {
  it("colors run status badges: success good, partial warn, failed/aborted bad, running info", () => {
    render(
      <RunsTable
        runs={[
          makeRun("success", [makeRow()], { runId: "run-20260831T120001" }),
          makeRun("partial", [makeRow()], { runId: "run-20260831T120002" }),
          makeRun("failed", [], { runId: "run-20260831T120003" }),
          makeRun("aborted", [], { runId: "run-20260831T120004" }),
          makeRun("running", [], { runId: "run-20260831T120005" }),
        ]}
      />,
    );
    expect(screen.getByText("success")).toHaveClass("bg-success/10");
    expect(screen.getByText("partial")).toHaveClass("bg-warning/10");
    expect(screen.getByText("failed")).toHaveClass("bg-danger/10");
    expect(screen.getByText("aborted")).toHaveClass("bg-danger/10");
    expect(screen.getByText("running")).toHaveClass("bg-accent/10");
  });

  it("renders the trigger as a neutral badge", () => {
    render(
      <RunsTable
        runs={[
          makeRun("success", [makeRow()], { trigger: "schedule" }),
          makeRun("success", [makeRow()], { runId: "run-20260831T120006", trigger: "manual" }),
          makeRun("success", [makeRow()], { runId: "run-20260831T120007", trigger: "boot" }),
        ]}
      />,
    );
    for (const trigger of ["schedule", "manual", "boot"]) {
      expect(screen.getByText(trigger)).toHaveClass("bg-text-muted/10");
    }
  });
});

// ---------- regions cell ----------

describe("RunsTable regions cell", () => {
  it("shows ok/total for success runs", () => {
    render(<RunsTable runs={[makeRun("success", [makeRow(), makeRow(), makeRow()])]} />);
    expect(screen.getByText("3/3")).toBeInTheDocument();
  });

  it("shows ok/total and a derived failed count for partial runs that stamped totals", () => {
    render(
      <RunsTable runs={[makeRun("partial", [makeRow()], { regionsTotal: 3 })]} />,
    );
    expect(screen.getByText("1/3")).toBeInTheDocument();
    expect(screen.getByText("2 failed")).toBeInTheDocument();
  });

  it("shows the ok count without a total for legacy partial runs (no stamped totals)", () => {
    render(<RunsTable runs={[makeRun("partial", [makeRow()])]} />);
    expect(screen.getByText("1 ok")).toBeInTheDocument();
  });

  it("links each row to the run detail page", () => {
    render(<RunsTable runs={[makeRun("success", [makeRow()])]} />);
    const link = screen.getByRole("link", { name: "run-20260831T122000" });
    expect(link).toHaveAttribute("href", "/runs/run-20260831T122000");
  });
});

// ---------- summary math ----------

describe("runs summary math", () => {
  const run = makeRun("success", [
    makeRow({ monthlyCostUsd: 100, potentialMonthlySavingsUsd: 10 }),
    makeRow({ monthlyCostUsd: null, potentialMonthlySavingsUsd: null }),
    makeRow({ monthlyCostUsd: 50.25, potentialMonthlySavingsUsd: 0 }),
  ]);

  it("renders the sums as money", () => {
    render(<RunsTable runs={[run]} />);
    expect(screen.getByText("$150.25")).toBeInTheDocument();
    expect(screen.getByText("$10.00")).toBeInTheDocument();
  });
});

// ---------- timestamps ----------

describe("RunsTable timestamps", () => {
  it("formats started/finished as UTC+8 stamps", () => {
    render(<RunsTable runs={[makeRun("success", [makeRow()])]} />);
    const row = screen.getByText("run-20260831T122000").closest("tr");
    expect(row).not.toBeNull();
    expect(within(row!).getByText("2026-08-31 20:00 UTC+8")).toBeInTheDocument();
    expect(within(row!).getByText("2026-08-31 20:20 UTC+8")).toBeInTheDocument();
  });
});
