/**
 * Viewport profile helpers for responsive testing
 */

export type ViewportSize = "mobile" | "tablet" | "desktop" | "widescreen";

export interface ViewportDimensions {
	width: number;
	height: number;
}

export const VIEWPORTS: Record<ViewportSize, ViewportDimensions> = {
	mobile: { width: 375, height: 667 }, // iPhone SE / similar
	tablet: { width: 768, height: 1024 }, // iPad / similar
	desktop: { width: 1280, height: 720 }, // Standard desktop
	widescreen: { width: 1920, height: 1080 }, // Large desktop
} as const;

export const VIEWPORT_SIZES: ViewportSize[] = [
	"mobile",
	"tablet",
	"desktop",
	"widescreen",
];

/**
 * Breakpoint definitions matching CSS media queries
 */
export const BREAKPOINTS = {
	sm: 640, // Small devices
	md: 768, // Medium devices (tablet)
	lg: 1024, // Large devices (desktop)
	xl: 1280, // Extra large
	"2xl": 1536, // 2X large
} as const;

/**
 * Set viewport size
 */
export async function setViewport(
	page: any,
	size: ViewportSize,
): Promise<void> {
	const dimensions = VIEWPORTS[size];
	await page.setViewportSize(dimensions);
}

/**
 * Get current viewport size
 */
export async function getViewport(page: any): Promise<ViewportDimensions> {
	return page.evaluate(() => ({
		width: window.innerWidth,
		height: window.innerHeight,
	}));
}

/**
 * Assert viewport is at expected size
 */
export async function assertViewport(
	page: any,
	size: ViewportSize,
): Promise<void> {
	const expected = VIEWPORTS[size];
	const actual = await getViewport(page);

	if (actual.width !== expected.width || actual.height !== expected.height) {
		throw new Error(
			`Expected viewport ${size} (${expected.width}x${expected.height}) ` +
				`but got ${actual.width}x${actual.height}`,
		);
	}
}

/**
 * Check if element has horizontal overflow
 */
export async function hasHorizontalOverflow(
	page: any,
	selector: string,
): Promise<boolean> {
	return page.evaluate((sel: string) => {
		const element = document.querySelector(sel);
		if (!element) return false;
		return element.scrollWidth > element.clientWidth;
	}, selector);
}

/**
 * Check if element is clipped (overflow hidden with content exceeding bounds)
 */
export async function isClipped(page: any, selector: string): Promise<boolean> {
	return page.evaluate((sel: string) => {
		const element = document.querySelector(sel);
		if (!element) return false;

		const style = window.getComputedStyle(element);
		const rect = element.getBoundingClientRect();

		// Check if element has overflow hidden and children exceed bounds
		const children = element.children;
		for (const child of children) {
			const childRect = child.getBoundingClientRect();
			if (childRect.right > rect.right || childRect.bottom > rect.bottom) {
				return (
					style.overflow === "hidden" ||
					style.overflowX === "hidden" ||
					style.overflowY === "hidden"
				);
			}
		}

		return false;
	}, selector);
}

/**
 * Run a test across all viewport sizes
 */
export function testAllViewports(
	name: string,
	testFn: (size: ViewportSize) => Promise<void> | void,
): void {
	for (const size of VIEWPORT_SIZES) {
		test(`${name} - ${size}`, async () => {
			await testFn(size);
		});
	}
}

/**
 * Check sticky element position
 */
export async function getStickyPosition(
	page: any,
	selector: string,
): Promise<{ top: number; isSticky: boolean }> {
	return page.evaluate((sel: string) => {
		const element = document.querySelector(sel);
		if (!element) return { top: 0, isSticky: false };

		const style = window.getComputedStyle(element);
		const rect = element.getBoundingClientRect();

		return {
			top: rect.top,
			isSticky: style.position === "sticky" || style.position === "fixed",
		};
	}, selector);
}
