import { test, expect, type Page } from "@playwright/test";

test.describe("Visual Regression Tests", () => {
  async function settle(page: Page) {
    await page.evaluate(() => {
      window.scrollTo(0, window.scrollY); // ensure a frame boundary
      void document.body.getBoundingClientRect();
    });
    await page.waitForTimeout(50);
  }

  test("homepage full page screenshot", async ({ page }) => {
    // Add deterministic CSS to normalize rendering
    await page.addStyleTag({
      content: `
        /* stop caret and selection flicker */
        * { caret-color: transparent !important; }
        ::selection { background: transparent !important; }
        /* hide scrollbars */
        ::-webkit-scrollbar { display: none !important; }
        html { scrollbar-width: none !important; }
        /* stabilize font rasterization */
        * {
          text-rendering: geometricPrecision !important;
          -webkit-font-smoothing: antialiased !important;
          -moz-osx-font-smoothing: grayscale !important;
        }
      `,
    });

    await page.goto("/");
    await page.waitForLoadState("networkidle");

    // Make sure we've really got the webfonts before shots
    await page.evaluate(async () => {
      // @ts-ignore
      if (document.fonts && document.fonts.status !== "loaded") {
        // @ts-ignore
        await document.fonts.ready;
      }
    });

    // Stabilize layout before screenshot
    await settle(page);

    // Take full page screenshot
    await expect(page).toHaveScreenshot("homepage-full.png", {
      fullPage: true,
      animations: "disabled",
      scale: "css",
    });
  });

  test("homepage viewport screenshot", async ({ page }) => {
    // Add deterministic CSS to normalize rendering
    await page.addStyleTag({
      content: `
        /* stop caret and selection flicker */
        * { caret-color: transparent !important; }
        ::selection { background: transparent !important; }
        /* hide scrollbars */
        ::-webkit-scrollbar { display: none !important; }
        html { scrollbar-width: none !important; }
        /* stabilize font rasterization */
        * {
          text-rendering: geometricPrecision !important;
          -webkit-font-smoothing: antialiased !important;
          -moz-osx-font-smoothing: grayscale !important;
        }
      `,
    });

    await page.goto("/");
    await page.waitForLoadState("networkidle");

    // Make sure we've really got the webfonts before shots
    await page.evaluate(async () => {
      // @ts-ignore
      if (document.fonts && document.fonts.status !== "loaded") {
        // @ts-ignore
        await document.fonts.ready;
      }
    });

    // Stabilize layout before screenshot
    await page.evaluate(() => {
      window.scrollTo(0, 0);
      void document.body.getBoundingClientRect();
    });
    await page.waitForTimeout(50);

    // Take viewport screenshot
    await expect(page).toHaveScreenshot("homepage-viewport.png", {
      animations: "disabled",
    });
  });

  test("blog listing page", async ({ page }) => {
    // Add deterministic CSS to normalize rendering
    await page.addStyleTag({
      content: `
        /* stop caret and selection flicker */
        * { caret-color: transparent !important; }
        ::selection { background: transparent !important; }
        /* hide scrollbars */
        ::-webkit-scrollbar { display: none !important; }
        html { scrollbar-width: none !important; }
        /* stabilize font rasterization */
        * {
          text-rendering: geometricPrecision !important;
          -webkit-font-smoothing: antialiased !important;
          -moz-osx-font-smoothing: grayscale !important;
        }
      `,
    });

    // Navigate to blog listing page
    await page.goto("/blog");
    await page.waitForLoadState("networkidle");

    // Wait for blog content to be fully rendered
    await page.waitForTimeout(1000);
    await settle(page);

    // Take full page screenshot of blog listing
    await expect(page).toHaveScreenshot("blog-listing.png", {
      fullPage: true,
      animations: "disabled",
    });
  });

  test("blog post page", async ({ page }) => {
    // Add deterministic CSS to normalize rendering
    await page.addStyleTag({
      content: `
        /* stop caret and selection flicker */
        * { caret-color: transparent !important; }
        ::selection { background: transparent !important; }
        /* hide scrollbars */
        ::-webkit-scrollbar { display: none !important; }
        html { scrollbar-width: none !important; }
        /* stabilize font rasterization */
        * {
          text-rendering: geometricPrecision !important;
          -webkit-font-smoothing: antialiased !important;
          -moz-osx-font-smoothing: grayscale !important;
        }
      `,
    });

    // Navigate to a specific blog post
    await page.goto("/blog/resolving-active-conflicts");
    await page.waitForLoadState("networkidle");

    // Wait for blog post content to be fully rendered
    await page.waitForSelector("main", { timeout: 10000 });
    await page.waitForTimeout(1000);
    await settle(page);

    // Take full page screenshot of blog post
    await expect(page).toHaveScreenshot("blog-post.png", {
      fullPage: true,
      animations: "disabled",
    });
  });

  test("404 error page", async ({ page }) => {
    // Add deterministic CSS to normalize rendering
    await page.addStyleTag({
      content: `
        /* stop caret and selection flicker */
        * { caret-color: transparent !important; }
        ::selection { background: transparent !important; }
        /* hide scrollbars */
        ::-webkit-scrollbar { display: none !important; }
        html { scrollbar-width: none !important; }
        /* stabilize font rasterization */
        * {
          text-rendering: geometricPrecision !important;
          -webkit-font-smoothing: antialiased !important;
          -moz-osx-font-smoothing: grayscale !important;
        }
      `,
    });

    // Navigate to a non-existent route to trigger 404
    await page.goto("/non-existent-page");
    await page.waitForLoadState("networkidle");
    await settle(page);

    // Take screenshot of 404 page
    await expect(page).toHaveScreenshot("404-error.png", {
      animations: "disabled",
    });
  });
});
