import { render } from "@testing-library/react";
import * as React from "react";
import { describe, expect, it } from "vitest";
import type { PipelineState } from "../api/client";
import { LozengeFlyProvider } from "./LozengeFlyContext";
import { StagePanel } from "./StagePanel";

// ─── Helpers ──────────────────────────────────────────────────────────────────

function makePipeline(overrides: Partial<PipelineState> = {}): PipelineState {
	return {
		backlog: [],
		current: [],
		qa: [],
		merge: [],
		done: [],
		deterministic_merges_in_flight: [],
		...overrides,
	};
}

function Wrapper({
	pipeline,
	children,
}: {
	pipeline: PipelineState;
	children: React.ReactNode;
}) {
	return (
		<LozengeFlyProvider pipeline={pipeline}>{children}</LozengeFlyProvider>
	);
}

// ─── Agent lozenge fixed intrinsic width ──────────────────────────────────────

describe("AgentLozenge fixed intrinsic width", () => {
	it("has align-self: flex-start so it never stretches inside a flex column", () => {
		const items = [
			{
				story_id: "74_width_test",
				name: "Width Test",
				error: null,
				merge_failure: null,
				agent: { agent_name: "coder-1", model: "sonnet", status: "running" },
				review_hold: null,
				qa: null,
				depends_on: null,
			},
		];
		const pipeline = makePipeline({ current: items });
		const { container } = render(
			<Wrapper pipeline={pipeline}>
				<StagePanel title="Current" items={items} />
			</Wrapper>,
		);

		const lozenge = container.querySelector(
			'[data-testid="slot-lozenge-74_width_test"]',
		) as HTMLElement;
		expect(lozenge).toBeInTheDocument();
		expect(lozenge.style.alignSelf).toBe("flex-start");
	});
});

// ─── Idle vs active visual distinction ────────────────────────────────────────

describe("AgentLozenge idle vs active appearance", () => {
	it("running agent lozenge uses the green active color", () => {
		const items = [
			{
				story_id: "74_running_color",
				name: "Running",
				error: null,
				merge_failure: null,
				agent: { agent_name: "coder-1", model: null, status: "running" },
				review_hold: null,
				qa: null,
				depends_on: null,
			},
		];
		const { container } = render(
			<Wrapper pipeline={makePipeline({ current: items })}>
				<StagePanel title="Current" items={items} />
			</Wrapper>,
		);

		const lozenge = container.querySelector(
			'[data-testid="slot-lozenge-74_running_color"]',
		) as HTMLElement;
		expect(lozenge).toBeInTheDocument();
		// Green: rgb(63, 185, 80) = #3fb950
		expect(lozenge.style.color).toBe("rgb(63, 185, 80)");
	});

	it("pending agent lozenge uses the yellow pending color", () => {
		const items = [
			{
				story_id: "74_pending_color",
				name: "Pending",
				error: null,
				merge_failure: null,
				agent: { agent_name: "coder-1", model: null, status: "pending" },
				review_hold: null,
				qa: null,
				depends_on: null,
			},
		];
		const { container } = render(
			<Wrapper pipeline={makePipeline({ current: items })}>
				<StagePanel title="Current" items={items} />
			</Wrapper>,
		);

		const lozenge = container.querySelector(
			'[data-testid="slot-lozenge-74_pending_color"]',
		) as HTMLElement;
		expect(lozenge).toBeInTheDocument();
		// Yellow: rgb(227, 179, 65) = #e3b341
		expect(lozenge.style.color).toBe("rgb(227, 179, 65)");
	});

	it("running lozenge has a pulsing dot child element", () => {
		const items = [
			{
				story_id: "74_pulse_dot",
				name: "Pulse",
				error: null,
				merge_failure: null,
				agent: { agent_name: "coder-1", model: null, status: "running" },
				review_hold: null,
				qa: null,
				depends_on: null,
			},
		];
		const { container } = render(
			<Wrapper pipeline={makePipeline({ current: items })}>
				<StagePanel title="Current" items={items} />
			</Wrapper>,
		);

		const lozenge = container.querySelector(
			'[data-testid="slot-lozenge-74_pulse_dot"]',
		) as HTMLElement;
		// The pulse dot is a child span with animation: pulse
		const dot = lozenge.querySelector("span");
		expect(dot).not.toBeNull();
		expect(dot?.style.animation).toContain("pulse");
	});
});
