// RunTriggerButton: dialog flow (open → confirm → triggerRun), onTriggered
// firing only on success, inline error on rejection (e.g. 409), and the
// read-only fleet-wide copy. triggerRun is mocked — no dataplane contact
// from component tests.

import { describe, expect, it, vi } from "vitest";
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import { RunTriggerButton } from "@/components/runs/RunTriggerButton";

vi.mock("@/lib/api-client", () => ({
  triggerRun: vi.fn(),
}));

import { triggerRun } from "@/lib/api-client";

const mockedTriggerRun = vi.mocked(triggerRun);

describe("RunTriggerButton", () => {
  it("opens the dialog, describes the fleet, and triggers on confirm", async () => {
    mockedTriggerRun.mockResolvedValue({ started: true });
    render(<RunTriggerButton totalRegions={12} label="Analyze all regions" />);

    fireEvent.click(screen.getByText("Analyze all regions"));
    expect(screen.getByText("Analyze", { selector: "h3" })).toBeTruthy();
    expect(screen.getByText(/analyze all 12 regions —/)).toBeTruthy();
    expect(screen.getByText(/Read-only/)).toBeTruthy();

    fireEvent.click(screen.getByText("Start analysis"));
    await waitFor(() => expect(mockedTriggerRun).toHaveBeenCalledWith());
    await waitFor(() => expect(screen.queryByText("Start analysis")).toBeNull());
  });

  it("falls back to whole-fleet copy with no region count", () => {
    render(<RunTriggerButton totalRegions={0} label="Analyze" />);
    fireEvent.click(screen.getByText("Analyze"));
    expect(screen.getByText(/analyze the whole fleet/)).toBeTruthy();
  });

  it("fires onTriggered after a successful trigger", async () => {
    mockedTriggerRun.mockResolvedValue({ started: true });
    const onTriggered = vi.fn();
    render(
      <RunTriggerButton totalRegions={12} label="Analyze all regions" onTriggered={onTriggered} />,
    );

    fireEvent.click(screen.getByText("Analyze all regions"));
    fireEvent.click(screen.getByText("Start analysis"));
    await waitFor(() => expect(onTriggered).toHaveBeenCalledTimes(1));
  });

  it("does not fire onTriggered when the trigger is rejected", async () => {
    mockedTriggerRun.mockRejectedValue(new Error("a run is already in flight"));
    const onTriggered = vi.fn();
    render(
      <RunTriggerButton totalRegions={12} label="Analyze all regions" onTriggered={onTriggered} />,
    );

    fireEvent.click(screen.getByText("Analyze all regions"));
    fireEvent.click(screen.getByText("Start analysis"));
    await waitFor(() => expect(screen.getByText(/already in flight/)).toBeTruthy());
    expect(onTriggered).not.toHaveBeenCalled();
    expect(screen.getByText("Start analysis")).toBeTruthy();
  });
});
