// @vitest-environment jsdom
import {
	act,
	cleanup,
	fireEvent,
	render,
	screen,
} from "@testing-library/react";
import "@testing-library/jest-dom/vitest";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { ConfirmButton } from "../components/ui/confirm-button";

function XIcon() {
	return <span data-testid="x-icon">X</span>;
}

function renderButton(
	props: Partial<Parameters<typeof ConfirmButton>[0]> = {},
) {
	const onConfirm = props.onConfirm ?? vi.fn();
	render(
		<ConfirmButton
			icon={<XIcon />}
			label="Remove combatant"
			onConfirm={onConfirm}
			{...props}
		/>,
	);
	return { onConfirm };
}

describe("ConfirmButton", () => {
	beforeEach(() => {
		vi.useFakeTimers();
	});

	afterEach(() => {
		vi.useRealTimers();
		cleanup();
	});

	it("renders the default icon in idle state", () => {
		renderButton();
		expect(screen.getByTestId("x-icon")).toBeTruthy();
		expect(screen.getByRole("button")).toHaveAttribute(
			"aria-label",
			"Remove combatant",
		);
	});

	it("transitions to confirm state with Check icon on first click", () => {
		renderButton();
		fireEvent.click(screen.getByRole("button"));

		expect(screen.queryByTestId("x-icon")).toBeNull();
		expect(screen.getByRole("button")).toHaveAttribute(
			"aria-label",
			"Confirm remove combatant",
		);
		expect(screen.getByRole("button").className).toContain("bg-destructive");
	});

	it("calls onConfirm on second click in confirm state", () => {
		const { onConfirm } = renderButton();
		const button = screen.getByRole("button");

		fireEvent.click(button);
		fireEvent.click(button);

		expect(onConfirm).toHaveBeenCalledOnce();
	});

	it("auto-reverts after 5 seconds", () => {
		renderButton();
		fireEvent.click(screen.getByRole("button"));

		expect(screen.queryByTestId("x-icon")).toBeNull();

		act(() => {
			vi.advanceTimersByTime(5000);
		});

		expect(screen.getByTestId("x-icon")).toBeTruthy();
	});

	it("reverts on Escape key", () => {
		renderButton();
		fireEvent.click(screen.getByRole("button"));

		expect(screen.queryByTestId("x-icon")).toBeNull();

		fireEvent.keyDown(document, { key: "Escape" });

		expect(screen.getByTestId("x-icon")).toBeTruthy();
	});

	it("reverts on click outside", () => {
		renderButton();
		fireEvent.click(screen.getByRole("button"));

		expect(screen.queryByTestId("x-icon")).toBeNull();

		fireEvent.mouseDown(document.body);

		expect(screen.getByTestId("x-icon")).toBeTruthy();
	});

	it("does not enter confirm state when disabled", () => {
		renderButton({ disabled: true });
		fireEvent.click(screen.getByRole("button"));

		expect(screen.getByTestId("x-icon")).toBeTruthy();
	});

	it("cleans up timer on unmount", () => {
		const clearTimeoutSpy = vi.spyOn(globalThis, "clearTimeout");
		renderButton();
		fireEvent.click(screen.getByRole("button"));

		cleanup();

		expect(clearTimeoutSpy).toHaveBeenCalled();
		clearTimeoutSpy.mockRestore();
	});

	it("manages independent instances separately", () => {
		const onConfirm1 = vi.fn();
		const onConfirm2 = vi.fn();

		render(
			<>
				<ConfirmButton
					icon={<span data-testid="icon-1">1</span>}
					label="Remove first"
					onConfirm={onConfirm1}
				/>
				<ConfirmButton
					icon={<span data-testid="icon-2">2</span>}
					label="Remove second"
					onConfirm={onConfirm2}
				/>
			</>,
		);

		const buttons = screen.getAllByRole("button");
		fireEvent.click(buttons[0]);

		// First is confirming, second is still idle
		expect(screen.queryByTestId("icon-1")).toBeNull();
		expect(screen.getByTestId("icon-2")).toBeTruthy();
	});

	// T008: Keyboard-specific tests
	it("Enter key triggers confirm state", () => {
		renderButton();
		const button = screen.getByRole("button");

		// Native button handles Enter via click event
		fireEvent.click(button);

		expect(screen.queryByTestId("x-icon")).toBeNull();
		expect(button).toHaveAttribute("aria-label", "Confirm remove combatant");
	});

	it("Enter in confirm state calls onConfirm", () => {
		const { onConfirm } = renderButton();
		const button = screen.getByRole("button");

		fireEvent.click(button); // enter confirm state
		fireEvent.click(button); // confirm

		expect(onConfirm).toHaveBeenCalledOnce();
	});

	it("Escape in confirm state reverts", () => {
		renderButton();
		fireEvent.click(screen.getByRole("button"));

		fireEvent.keyDown(document, { key: "Escape" });

		expect(screen.getByTestId("x-icon")).toBeTruthy();
		expect(screen.getByRole("button")).toHaveAttribute(
			"aria-label",
			"Remove combatant",
		);
	});

	it("blur event reverts confirm state", () => {
		renderButton();
		const button = screen.getByRole("button");

		fireEvent.click(button);
		expect(screen.queryByTestId("x-icon")).toBeNull();

		fireEvent.blur(button);
		expect(screen.getByTestId("x-icon")).toBeTruthy();
	});

	it("Enter/Space keydown stops propagation to prevent parent handlers", () => {
		const parentHandler = vi.fn();
		render(
			// biome-ignore lint/a11y/noStaticElementInteractions: test wrapper
			// biome-ignore lint/a11y/noNoninteractiveElementInteractions: test wrapper
			<div onKeyDown={parentHandler}>
				<ConfirmButton
					icon={<XIcon />}
					label="Remove combatant"
					onConfirm={vi.fn()}
				/>
			</div>,
		);
		const button = screen.getByRole("button");

		fireEvent.keyDown(button, { key: "Enter" });
		fireEvent.keyDown(button, { key: " " });

		expect(parentHandler).not.toHaveBeenCalled();
	});
});
