import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { describe, expect, it, vi } from "vitest";
import { GatePanel } from "./GatePanel";

const baseProps = {
	gateState: null,
	gateStatusLabel: "Unknown",
	gateStatusColor: "#aaa",
	isGateLoading: false,
	gateError: null,
	coverageError: null,
	lastGateRefresh: null,
	onRefresh: vi.fn(),
	onCollectCoverage: vi.fn(),
	isCollectingCoverage: false,
};

describe("GatePanel", () => {
	it("shows 'no workflow data' when gateState is null", () => {
		render(<GatePanel {...baseProps} />);
		expect(screen.getByText("No workflow data yet.")).toBeInTheDocument();
	});

	it("shows loading message when isGateLoading is true", () => {
		render(<GatePanel {...baseProps} isGateLoading={true} />);
		expect(screen.getByText("Loading workflow gates...")).toBeInTheDocument();
	});

	it("shows error with retry button", async () => {
		const onRefresh = vi.fn();
		render(
			<GatePanel
				{...baseProps}
				gateError="Connection failed"
				onRefresh={onRefresh}
			/>,
		);

		expect(screen.getByText("Connection failed")).toBeInTheDocument();

		const retryButton = screen.getByRole("button", { name: "Retry" });
		await userEvent.click(retryButton);
		expect(onRefresh).toHaveBeenCalledOnce();
	});

	it("shows gate status label and color", () => {
		render(
			<GatePanel
				{...baseProps}
				gateStatusLabel="Blocked"
				gateStatusColor="#ff7b72"
			/>,
		);
		expect(screen.getByText("Blocked")).toBeInTheDocument();
	});

	it("shows test summary when gateState is provided", () => {
		render(
			<GatePanel
				{...baseProps}
				gateState={{
					canAccept: true,
					reasons: [],
					warning: null,
					summary: { total: 5, passed: 5, failed: 0 },
					missingCategories: [],
					coverageReport: null,
				}}
				gateStatusLabel="Ready to accept"
			/>,
		);
		expect(screen.getByText(/5\/5 passing, 0 failing/)).toBeInTheDocument();
	});

	it("shows missing categories", () => {
		render(
			<GatePanel
				{...baseProps}
				gateState={{
					canAccept: false,
					reasons: [],
					warning: null,
					summary: { total: 0, passed: 0, failed: 0 },
					missingCategories: ["unit", "integration"],
					coverageReport: null,
				}}
			/>,
		);
		expect(screen.getByText("Missing: unit, integration")).toBeInTheDocument();
	});

	it("shows warning text", () => {
		render(
			<GatePanel
				{...baseProps}
				gateState={{
					canAccept: false,
					reasons: [],
					warning: "Multiple tests failing — fix one at a time.",
					summary: { total: 4, passed: 2, failed: 2 },
					missingCategories: [],
					coverageReport: null,
				}}
			/>,
		);
		expect(
			screen.getByText("Multiple tests failing — fix one at a time."),
		).toBeInTheDocument();
	});

	it("shows reasons as list items", () => {
		render(
			<GatePanel
				{...baseProps}
				gateState={{
					canAccept: false,
					reasons: ["No approved test plan.", "Tests are failing."],
					warning: null,
					summary: { total: 2, passed: 1, failed: 1 },
					missingCategories: [],
					coverageReport: null,
				}}
			/>,
		);
		expect(screen.getByText("No approved test plan.")).toBeInTheDocument();
		expect(screen.getByText("Tests are failing.")).toBeInTheDocument();
	});

	it("calls onRefresh when Refresh button is clicked", async () => {
		const onRefresh = vi.fn();
		render(<GatePanel {...baseProps} onRefresh={onRefresh} />);

		await userEvent.click(screen.getByRole("button", { name: "Refresh" }));
		expect(onRefresh).toHaveBeenCalledOnce();
	});

	it("disables Refresh button when loading", () => {
		render(<GatePanel {...baseProps} isGateLoading={true} />);
		expect(screen.getByRole("button", { name: "Refresh" })).toBeDisabled();
	});
});
