import { SELECTORS } from "../../fixtures/selectors";
import { expect, test } from "../../fixtures/test";
import { getStickyPosition, ViewportSize } from "../../fixtures/viewports";

test.describe("Sticky Header Behavior @smoke", () => {
	test.beforeEach(async ({ gotoApp, waitForAppReady }) => {
		await gotoApp();
		await waitForAppReady();
	});

	test("header is sticky on scroll", async ({ page }) => {
		const header = page.locator(SELECTORS.header.root);

		// Check initial position
		const initialPosition = await getStickyPosition(
			page,
			SELECTORS.header.root,
		);
		expect(initialPosition.isSticky).toBe(true);

		// Scroll down
		await page.evaluate(() => window.scrollTo(0, 500));
		await page.waitForTimeout(500);

		// Header should still be at top
		const scrolledPosition = await getStickyPosition(
			page,
			SELECTORS.header.root,
		);
		expect(scrolledPosition.top).toBeLessThanOrEqual(10); // Allow small offset
		expect(scrolledPosition.isSticky).toBe(true);
	});

	test("header shrinks on scroll", async ({ page }) => {
		const header = page.locator(SELECTORS.header.root);
		const headerContainer = header.locator("> div");

		// Get initial height
		const initialHeight = await headerContainer.evaluate(
			(el) => el.offsetHeight,
		);

		// Scroll down
		await page.evaluate(() => window.scrollTo(0, 300));
		await page.waitForTimeout(500);

		// Get scrolled height
		const scrolledHeight = await headerContainer.evaluate(
			(el) => el.offsetHeight,
		);

		// Header should shrink (or stay same, but not grow)
		expect(scrolledHeight).toBeLessThanOrEqual(initialHeight);
	});

	test("header maintains glass effect on scroll", async ({ page }) => {
		// Scroll down
		await page.evaluate(() => window.scrollTo(0, 500));
		await page.waitForTimeout(500);

		// Check header has backdrop blur
		const hasBlur = await page.evaluate(() => {
			const header = document.querySelector("header");
			if (!header) return false;
			const style = window.getComputedStyle(header);
			return style.backdropFilter.includes("blur");
		});

		expect(hasBlur).toBe(true);
	});
});

test.describe("Sticky Footer Behavior", () => {
	test.beforeEach(async ({ gotoApp, waitForAppReady }) => {
		await gotoApp();
		await waitForAppReady();
	});

	test("footer is sticky at bottom", async ({ page }) => {
		const footer = page.locator(SELECTORS.footer.root);

		// Check footer is visible
		await expect(footer).toBeVisible();

		// Check footer position
		const footerBox = await footer.boundingBox();
		const viewportHeight = await page.evaluate(() => window.innerHeight);

		// Footer should be at bottom of viewport
		expect(footerBox!.y + footerBox!.height).toBeGreaterThanOrEqual(
			viewportHeight - 10,
		);
	});

	test("footer does not overlap main content", async ({ page }) => {
		const footer = page.locator(SELECTORS.footer.root);
		const mainContent = page.locator("main");

		// Get bounding boxes
		const footerBox = await footer.boundingBox();
		const mainBox = await mainContent.boundingBox();

		// Main content should have padding at bottom to account for footer
		const bodyPadding = await page.evaluate(() => {
			const body = document.body;
			const style = window.getComputedStyle(body);
			return parseInt(style.paddingBottom || "0");
		});

		expect(bodyPadding).toBeGreaterThan(0);
	});
});

test.describe("Back to Top Behavior @smoke", () => {
	test.beforeEach(async ({ gotoApp, waitForAppReady }) => {
		await gotoApp();
		await waitForAppReady();
	});

	test("back to top is hidden initially", async ({ page }) => {
		const backToTop = page.locator(SELECTORS.backToTop.root);

		// Should not be visible at top of page
		const isVisible = await backToTop.isVisible().catch(() => false);
		expect(isVisible).toBe(false);
	});

	test("back to top appears on scroll", async ({ page }) => {
		// Scroll down
		await page.evaluate(() => window.scrollTo(0, 800));
		await page.waitForTimeout(500);

		const backToTop = page.locator(SELECTORS.backToTop.root);

		// Should be visible after scroll
		await expect(backToTop).toBeVisible();
	});

	test("back to top scrolls to top when clicked", async ({ page }) => {
		// Scroll down
		await page.evaluate(() => window.scrollTo(0, 1000));
		await page.waitForTimeout(500);

		// Click back to top
		const backToTop = page.locator(SELECTORS.backToTop.root);
		await backToTop.click();

		// Wait for scroll animation
		await page.waitForTimeout(1000);

		// Should be at top
		const scrollPosition = await page.evaluate(() => window.scrollY);
		expect(scrollPosition).toBeLessThanOrEqual(50);
	});

	test("back to top is accessible", async ({ page }) => {
		// Scroll down to make visible
		await page.evaluate(() => window.scrollTo(0, 800));
		await page.waitForTimeout(500);

		const backToTop = page.locator(SELECTORS.backToTop.root);

		// Should have aria-label
		await expect(backToTop).toHaveAttribute("aria-label");

		// Should be keyboard focusable
		await backToTop.focus();
		await expect(backToTop).toBeFocused();
	});
});

test.describe("Sticky Behavior Across Breakpoints", () => {
	test("header and footer work on mobile", async ({
		gotoApp,
		waitForAppReady,
		setViewport,
		page,
	}) => {
		await setViewport("mobile");
		await gotoApp();
		await waitForAppReady();

		// Check header is sticky
		const header = page.locator(SELECTORS.header.root);
		await expect(header).toBeVisible();

		// Scroll down
		await page.evaluate(() => window.scrollTo(0, 500));
		await page.waitForTimeout(500);

		// Header should still be visible
		await expect(header).toBeVisible();

		// Footer should be visible
		const footer = page.locator(SELECTORS.footer.root);
		await expect(footer).toBeVisible();
	});

	test("header and footer work on tablet", async ({
		gotoApp,
		waitForAppReady,
		setViewport,
		page,
	}) => {
		await setViewport("tablet");
		await gotoApp();
		await waitForAppReady();

		// Check header is sticky
		const header = page.locator(SELECTORS.header.root);
		await expect(header).toBeVisible();

		// Scroll down
		await page.evaluate(() => window.scrollTo(0, 500));
		await page.waitForTimeout(500);

		// Header should still be visible
		await expect(header).toBeVisible();

		// Footer should be visible
		const footer = page.locator(SELECTORS.footer.root);
		await expect(footer).toBeVisible();
	});

	test("header and footer work on desktop", async ({
		gotoApp,
		waitForAppReady,
		setViewport,
		page,
	}) => {
		await setViewport("desktop");
		await gotoApp();
		await waitForAppReady();

		// Check header is sticky
		const header = page.locator(SELECTORS.header.root);
		await expect(header).toBeVisible();

		// Scroll down
		await page.evaluate(() => window.scrollTo(0, 500));
		await page.waitForTimeout(500);

		// Header should still be visible
		await expect(header).toBeVisible();

		// Footer should be visible
		const footer = page.locator(SELECTORS.footer.root);
		await expect(footer).toBeVisible();
	});
});
