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

const scopes = ["LSTs", "MSTs", "SSTs"];

function checkCommonElements({
  wrapper,
  sidebarWrapper,
  pageContentWrapper,
  firstNav,
  secondNav,
  footer,
  relativePath,
  errors,
}) {
  expect(wrapper).not.toBeNull();
  expect(sidebarWrapper).not.toBeNull();
  expect(pageContentWrapper).not.toBeNull();
  expect(firstNav).not.toBeNull();
  expect(footer).not.toBeNull();
  if (relativePath === "/home") {
    expect(secondNav).toBeNull();
  } else {
    expect(secondNav).not.toBeNull();
  }
  expect(errors, `Console errors: ${errors.join("\n")}`).toEqual([]);
}

async function runCommonElementTest({ page, relativePath }) {
  const errors = [];
  page.on("pageerror", (err) => errors.push(err));
  page.on("console", (msg) => {
    if (msg.type() === "error") errors.push(msg.text());
  });

  // Use networkidle for more reliable page loading, especially in Firefox
  await page.goto(relativePath, {
    waitUntil: "networkidle",
    timeout: 60000, // Increase timeout to 60s for Firefox module loading issues
  });

  const hasConfigError = await page
    .locator(".alert-heading", { hasText: "Page configuration error" })
    .isVisible()
    .catch(() => false);
  const hasNotFound = await page
    .locator("h1", { hasText: "404 - Page Not Found" })
    .isVisible()
    .catch(() => false);

  if (hasConfigError || hasNotFound) {
    return { skipped: true };
  }

  const wrapper = await page.$("#wrapper");
  const sidebarWrapper = await page.$("#sidebar-wrapper");
  const pageContentWrapper = await page.$("#page-content-wrapper");
  const firstNav = await page.$("#first-nav");
  const secondNav = await page.$("#second-nav");
  const footer = await page.$("footer");

  checkCommonElements({
    wrapper,
    sidebarWrapper,
    pageContentWrapper,
    firstNav,
    secondNav,
    footer,
    relativePath,
    errors,
  });
  // Further DOM check can be added here

  return { skipped: false };
}

async function getNavLinksForScope(page, scope) {
  await page.goto(`/${scope}`, {
    waitUntil: "networkidle",
    timeout: 60000,
  });

  return page.$$eval("#second-nav a.nav-link", (links) =>
    links
      .map((link) => link.getAttribute("href"))
      .filter((href) => typeof href === "string" && href.length > 0)
  );
}

for (const scope of scopes) {
  test(`'${scope}': configured pages load with common elements`, async ({
    page,
  }) => {
    const navLinks = await getNavLinksForScope(page, scope);
    expect(navLinks.length).toBeGreaterThan(0);

    let validatedPages = 0;
    for (const relativePath of navLinks) {
      const result = await runCommonElementTest({ page, relativePath });
      if (!result.skipped) {
        validatedPages += 1;
      }
    }

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

test("'Home': summary page loads with 1 navigation-bar, side-bar and footer", async ({
  page,
}) => {
  await runCommonElementTest({
    page,
    relativePath: "/home",
  });
});
