// WorkloadTable: rows grouped by the engine `group` field, vmcluster
// expanded by default (rest collapsed) behind summary headers, filters
// auto-expanding matched groups, and the click-to-expand rationale row.
// Fabricated WorkloadRow fixtures; the
// trend chart's fetcher is mocked (its own spec covers the chart).

import { describe, expect, it, vi } from "vitest";
import { fireEvent, render, screen } from "@testing-library/react";
import { WorkloadTable } from "@/components/regions/WorkloadTable";
import type { WorkloadRow } from "@/engine/classify";

vi.mock("@/lib/api-client", () => ({
  fetchWorkloadUsage: vi.fn(async () => ({ mode: "absolute", points: [] })),
}));

function mkRow(overrides: Partial<WorkloadRow>): WorkloadRow {
  return {
    ns: "default",
    kind: "Deployment",
    name: "app",
    group: "other",
    npods: 1,
    images: [],
    nodes: [],
    nodeReplicaCounts: {},
    hasPvc: false,
    hasHpa: false,
    hpaMinReplicas: null,
    hpaMaxReplicas: null,
    reqCpu: 1,
    reqMemGib: 2,
    limCpu: 2,
    limMemGib: 4,
    avgCpu: 0.2,
    maxCpu: 0.5,
    avgMemGib: 1,
    maxMemGib: 1.5,
    maxPerReqCpu: 0.5,
    maxPerReqMem: 0.75,
    maxCpuUtil: 20,
    avgCpuUtil: 10,
    maxMemUtil: 30,
    avgMemUtil: 25,
    maxCpuLimUtil: 15,
    avgCpuLimUtil: 8,
    maxMemLimUtil: 40,
    avgMemLimUtil: 30,
    burstRatio: 2.5,
    scenario: "default_burstable",
    newReqCpu: 0.3,
    newReqMemGib: 1.5,
    newLimCpu: 1,
    newLimMemGib: 3,
    totalNewReqCpu: 0.3,
    totalNewReqMemGib: 1.5,
    confidence: "medium",
    rationale: "Default Burstable: req tracks 7d avg.",
    ...overrides,
  };
}

const rows: WorkloadRow[] = [
  mkRow({
    ns: "vm",
    name: "vmstorage-vmcluster",
    group: "vmcluster",
    npods: 2,
    reqCpu: 4,
    totalNewReqCpu: 1,
    totalNewReqMemGib: 3,
    scenario: "idle",
    confidence: "low",
    rationale: "Effectively idle (max/req < 5%). Shrink to floor.",
  }),
  mkRow({
    ns: "vm",
    name: "vmselect-vmcluster",
    group: "vmcluster",
    npods: 3,
    reqCpu: 2,
    totalNewReqCpu: 1.5,
    totalNewReqMemGib: 4,
  }),
  mkRow({ ns: "loki", name: "loki-ha-write", group: "loki", reqCpu: 1 }),
  mkRow({ ns: "o11y", name: "diagnosis-agent", group: "diagnosis", npods: 2, reqCpu: 0.5, confidence: "low" }),
  mkRow({
    ns: "monitoring",
    name: "vmalert-11111111-2222-3333-4444-555555555555",
    group: "vmalert",
    npods: 3,
    reqCpu: 0.5,
  }),
  mkRow({ ns: "pipeline-45", name: "pipeline-45-vector", group: "metrics-integration", reqCpu: 0.5 }),
];

describe("WorkloadTable", () => {
  it("renders vmcluster expanded and the other groups collapsed", () => {
    render(<WorkloadTable workloads={rows} regionKey="aws-us-west-2" />);
    expect(screen.getByText("▾ VMCluster")).toBeTruthy();
    expect(screen.getByText("▸ VMAlert")).toBeTruthy();
    expect(screen.getByText("▸ Loki")).toBeTruthy();
    expect(screen.getByText("▸ Diagnosis")).toBeTruthy();
    expect(screen.getByText("▸ Metrics Integration")).toBeTruthy();
    expect(screen.getByText("vmstorage-vmcluster")).toBeTruthy();
    expect(screen.queryByText("loki-ha-write")).toBeNull();
    expect(screen.getByText("6 of 6 workloads")).toBeTruthy();
  });

  it("expands a group on header click and collapses again", () => {
    render(<WorkloadTable workloads={rows} regionKey="aws-us-west-2" />);
    fireEvent.click(screen.getByText("▸ VMAlert"));
    expect(screen.getByText("▾ VMAlert")).toBeTruthy();
    expect(screen.getByText("vmalert-11111111-2222-3333-4444-555555555555")).toBeTruthy();
    expect(screen.queryByText("loki-ha-write")).toBeNull();
    fireEvent.click(screen.getByText("▾ VMAlert"));
    expect(screen.getByText("▸ VMAlert")).toBeTruthy();
    expect(screen.queryByText("vmalert-11111111-2222-3333-4444-555555555555")).toBeNull();
  });

  it("summarizes each group from its rows", () => {
    render(<WorkloadTable workloads={rows} regionKey="aws-us-west-2" />);
    expect(screen.getByText("2 workloads")).toBeTruthy();
    expect(screen.getByText("5 pods")).toBeTruthy();
    expect(screen.getByText("req 6.00 CPU / 4.00 GiB")).toBeTruthy();
    expect(screen.getByText("new 2.50 CPU / 7.00 GiB")).toBeTruthy();
    expect(screen.getAllByText("1 workload").length).toBe(4);
    expect(screen.getAllByText("1 pod").length).toBe(2);
    expect(screen.getByText("2 pods")).toBeTruthy();
    expect(screen.getByText("3 pods")).toBeTruthy();
  });

  it("filters by text search, auto-expanding the matching group", () => {
    render(<WorkloadTable workloads={rows} regionKey="aws-us-west-2" />);
    fireEvent.change(screen.getByPlaceholderText("search ns or name…"), {
      target: { value: "loki" },
    });
    expect(screen.getByText("▾ Loki")).toBeTruthy();
    expect(screen.getByText("loki-ha-write")).toBeTruthy();
    expect(screen.queryByText(/VMCluster/)).toBeNull();
    expect(screen.queryByText("diagnosis-agent")).toBeNull();
    expect(screen.getByText("1 of 6 workloads")).toBeTruthy();
  });

  it("filters by scenario and confidence, hiding empty groups", () => {
    render(<WorkloadTable workloads={rows} regionKey="aws-us-west-2" />);
    fireEvent.change(screen.getByRole("combobox", { name: "filter by scenario" }), {
      target: { value: "idle" },
    });
    expect(screen.getByText("vmstorage-vmcluster")).toBeTruthy();
    expect(screen.queryByText(/Loki/)).toBeNull();

    fireEvent.change(screen.getByRole("combobox", { name: "filter by scenario" }), {
      target: { value: "all" },
    });
    fireEvent.change(screen.getByRole("combobox", { name: "filter by confidence" }), {
      target: { value: "low" },
    });
    expect(screen.getByText("vmstorage-vmcluster")).toBeTruthy();
    expect(screen.getByText("diagnosis-agent")).toBeTruthy();
    expect(screen.queryByText("loki-ha-write")).toBeNull();
  });

  it("expands a row on click to reveal the rationale and detail, and collapses again", () => {
    render(<WorkloadTable workloads={rows} regionKey="aws-us-west-2" />);
    expect(screen.queryByText(/Effectively idle/)).toBeNull();
    fireEvent.click(screen.getByText("vmstorage-vmcluster"));
    expect(screen.getByText(/Effectively idle/)).toBeTruthy();
    expect(screen.getByText("burst ratio")).toBeTruthy();
    fireEvent.click(screen.getByText("vmstorage-vmcluster"));
    expect(screen.queryByText(/Effectively idle/)).toBeNull();
  });

  it("sorts within groups by a numeric column", () => {
    const { container } = render(<WorkloadTable workloads={rows} regionKey="aws-us-west-2" />);
    fireEvent.click(screen.getByText(/Req CPU/)); // reqCpu is the default sort: desc -> asc
    const trs = [...container.querySelectorAll("tbody tr")].map((tr) => tr.textContent ?? "");
    const iSelect = trs.findIndex((t) => t.includes("vmselect-vmcluster"));
    const iStorage = trs.findIndex((t) => t.includes("vmstorage-vmcluster"));
    expect(iSelect).toBeGreaterThan(-1);
    expect(iStorage).toBeGreaterThan(iSelect);
  });

  it("shows an empty-filter message when nothing matches", () => {
    render(<WorkloadTable workloads={rows} regionKey="aws-us-west-2" />);
    fireEvent.change(screen.getByPlaceholderText("search ns or name…"), {
      target: { value: "zzz" },
    });
    expect(screen.getByText("No workloads match the active filters.")).toBeTruthy();
    expect(screen.getByText("0 of 6 workloads")).toBeTruthy();
  });
});
