// Tests for the fleet compare region delta table: rows rendered in the
// server's delivered order (|cost Δ| desc, nulls last — diffOverview owns
// the sort), added/removed callouts, fallback footnote markers, and the
// per-region link carrying both run ids.

import { describe, expect, it, vi } from "vitest";
import { render, screen, within } from "@testing-library/react";
import { RegionDeltaTable } from "@/components/compare/RegionDeltaTable";
import type { OverviewDiff, RegionDeltaRow, TotalsSide } from "@/lib/api-types";

// next/link requires app-router context; render it as a plain anchor.
vi.mock("next/link", () => ({
  default: ({ href, children }: { href: string; children: React.ReactNode }) => (
    <a href={href}>{children}</a>
  ),
}));

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

const totals: TotalsSide = {
  monthlyCostUsd: 1000,
  potentialMonthlySavingsUsd: 100,
  regions: 2,
};

function makeRow(over: Partial<RegionDeltaRow> = {}): RegionDeltaRow {
  return {
    regionKey: "aws-us-east-1",
    vendor: "aws",
    monthlyCostUsdA: 1000,
    monthlyCostUsdB: 1000,
    monthlyCostDelta: 0,
    potentialSavingsA: 100,
    potentialSavingsB: 100,
    bestScenarioA: "current",
    bestScenarioB: "current",
    presentA: true,
    presentB: true,
    ...over,
  };
}

function makeDiff(over: Partial<OverviewDiff> = {}): OverviewDiff {
  return {
    dateA: "2026-08-24",
    dateB: "2026-08-31",
    runIdA: "run-20260824T120000",
    runIdB: "run-20260831T120000",
    totals: { a: totals, b: totals, delta: { monthlyCostUsd: 0, potentialMonthlySavingsUsd: 0 } },
    regions: [],
    addedRegions: [],
    removedRegions: [],
    ...over,
  };
}

// ---------- rendering order ----------

describe("region delta rendering", () => {
  const rows = [
    makeRow({ regionKey: "region-x", monthlyCostDelta: 500 }),
    makeRow({
      regionKey: "region-z",
      monthlyCostDelta: null,
      monthlyCostUsdA: null,
      monthlyCostUsdB: null,
      potentialSavingsB: null,
      bestScenarioB: null,
      presentB: false,
    }),
    makeRow({
      regionKey: "region-y",
      monthlyCostDelta: -2000,
      monthlyCostUsdA: 3000,
      monthlyCostUsdB: 1000,
    }),
    makeRow({ regionKey: "region-a", monthlyCostDelta: 500 }),
  ];

  it("renders rows in the server-delivered order with links carrying both run ids", () => {
    render(<RegionDeltaTable diff={makeDiff({ regions: rows })} />);
    const links = within(screen.getByRole("table")).getAllByRole("link");
    expect(links.map((l) => l.textContent)).toEqual([
      "region-x",
      "region-z",
      "region-y",
      "region-a",
    ]);
    expect(links[0]).toHaveAttribute(
      "href",
      "/compare/region-x?runA=run-20260824T120000&runB=run-20260831T120000",
    );
  });

  it("colors the cost delta good-when-negative", () => {
    render(<RegionDeltaTable diff={makeDiff({ regions: rows })} />);
    const cell = screen.getByText("-$2,000.00").closest("td");
    expect(cell).toHaveClass("text-success");
  });
});

// ---------- added / removed ----------

describe("added and removed regions", () => {
  const rows = [
    makeRow({
      regionKey: "new-region",
      presentA: false,
      monthlyCostUsdA: null,
      monthlyCostDelta: null,
      potentialSavingsA: null,
      bestScenarioA: null,
    }),
    makeRow({
      regionKey: "old-region",
      presentB: false,
      monthlyCostUsdB: null,
      monthlyCostDelta: null,
      potentialSavingsB: null,
      bestScenarioB: null,
    }),
  ];

  it("renders new/gone badges in the callout sections and the presence column", () => {
    render(
      <RegionDeltaTable
        diff={makeDiff({ regions: rows, addedRegions: ["new-region"], removedRegions: ["old-region"] })}
      />,
    );
    expect(screen.getAllByText("new").length).toBe(2);
    expect(screen.getAllByText("gone").length).toBe(2);
    expect(screen.getByText("Added")).toBeInTheDocument();
    expect(screen.getByText("Removed")).toBeInTheDocument();
    // callout entries link to the region compare with the same run ids
    for (const link of screen.getAllByRole("link", { name: "new-region" })) {
      expect(link).toHaveAttribute(
        "href",
        "/compare/new-region?runA=run-20260824T120000&runB=run-20260831T120000",
      );
    }
  });

  it("shows no callouts when nothing was added or removed", () => {
    render(<RegionDeltaTable diff={makeDiff({ regions: [makeRow()] })} />);
    expect(screen.queryByText("Added")).not.toBeInTheDocument();
    expect(screen.queryByText("Removed")).not.toBeInTheDocument();
  });
});

// ---------- fallback markers ----------

describe("fallback footnote markers", () => {
  it("marks costs pulled from an older run with a tooltip naming it", () => {
    render(
      <RegionDeltaTable
        diff={makeDiff({ regions: [makeRow({ fallbackA: "run-20260817T120000" })] })}
      />,
    );
    expect(
      screen.getByTitle("value from fallback run run-20260817T120000"),
    ).toBeInTheDocument();
    expect(screen.getByText("*")).toBeInTheDocument();
    expect(screen.getByText(/\* value pulled from an older run/)).toBeInTheDocument();
  });

  it("marks neither side when no fallback happened", () => {
    render(<RegionDeltaTable diff={makeDiff({ regions: [makeRow()] })} />);
    expect(screen.queryByText("*")).not.toBeInTheDocument();
  });
});

// ---------- empty ----------

describe("empty region list", () => {
  it("renders an empty state", () => {
    render(<RegionDeltaTable diff={makeDiff()} />);
    expect(screen.getByText("No regions to compare.")).toBeInTheDocument();
  });
});
