import { render, screen, within } from "@testing-library/react";
import * as stylex from "@stylexjs/stylex";
import type { StatsTimeseries } from "@/lib/types";
import { styles as shared } from "@/ui/styles";
import TimeseriesChart from "./TimeseriesChart";

const SINCE = 1_700_000_000;

function timeseries(bucketCount: number): StatsTimeseries {
	return {
		period: "24h",
		since: SINCE,
		until: SINCE + bucketCount * 1800,
		bucket_seconds: 1800,
		coverage: { complete: true, available_since: SINCE },
		buckets: Array.from({ length: bucketCount }, (_, i) => ({
			ts: SINCE + i * 1800,
			queries: i + 1,
			blocked: 1,
			cached: 1,
		})),
	};
}

/** The element wearing the shared hidden style, found by its compiled classes. */
function hiddenElement(container: HTMLElement): Element | null {
	const classes = stylex.props(shared.srOnly).className?.split(" ").filter(Boolean) ?? [];
	expect(classes.length).toBeGreaterThan(0);
	return container.querySelector(classes.map((name) => `.${name}`).join(""));
}

test("the data table is the SVG's accessible equivalent", () => {
	render(<TimeseriesChart data={timeseries(3)} />);

	expect(screen.getByRole("img", { name: /queries over time/i })).toBeTruthy();
	const table = screen.getByRole("table", { name: "Queries per time bucket" });
	expect(within(table).getAllByRole("row").length).toBe(4);
});

/**
 * `overflow` does not apply to a table box and `height` on one is a minimum, so
 * the hidden style has to sit on a block container wrapping the table. Worn by
 * the table itself it clips the paint but not the layout, and 48 invisible rows
 * push the document's scroll height a screen past the app shell.
 */
test("the hidden data table is clipped by a block wrapper, not by the table itself", () => {
	const { container } = render(<TimeseriesChart data={timeseries(48)} />);

	const hidden = hiddenElement(container);
	expect(hidden?.tagName).toBe("DIV");
	expect(hidden?.querySelector("table")).not.toBeNull();
});
