import { expect, test } from "@playwright/test";
import { serviceKeys, servicePath } from "../src/content/services";
import { libraryPath } from "../src/content/libraryPaths";

const locales = ["fr", "en", "ar"] as const;
const routes = ["", "growth-system/", "solutions/", "work/", "about/", "contact/", "privacy/", "legal/"] as const;

for (const locale of locales) {
  for (const route of routes) {
    const path = `/${locale}/${route}`;
    test(`${path} is a complete localized route`, async ({ page }) => {
      const response = await page.goto(path);
      expect(response?.ok()).toBe(true);
      await expect(page.locator("main#main")).toHaveCount(1);
      await expect(page.locator("h1")).toHaveCount(1);
      await expect(page.locator("html")).toHaveAttribute("lang", locale);
      await expect(page.locator("html")).toHaveAttribute("dir", locale === "ar" ? "rtl" : "ltr");

      const state = await page.evaluate(() => ({
        brokenImages: [...document.images].filter(
          (image) => image.complete && image.naturalWidth === 0,
        ).length,
        overflow: document.documentElement.scrollWidth > window.innerWidth + 1,
        text: document.body.innerText,
      }));

      expect(state.brokenImages).toBe(0);
      expect(state.overflow).toBe(false);
      expect(state.text).not.toContain("contact@yashalstudios.com");
      expect(state.text.toLowerCase()).not.toContain("testimonial");
    });
  }

  const library = libraryPath(locale);
  test(`${library} is the localized editorial library`, async ({ page }) => {
    const response = await page.goto(library);
    expect(response?.ok()).toBe(true);
    await expect(page.locator("main#main.library-page")).toHaveCount(1);
    await expect(page.locator("h1")).toHaveCount(1);
    await expect(page.locator("html")).toHaveAttribute("lang", locale);
    await expect(page.locator("html")).toHaveAttribute("dir", locale === "ar" ? "rtl" : "ltr");
    expect(await page.evaluate(() => document.documentElement.scrollWidth > window.innerWidth + 1)).toBe(false);
  });
}

test("French library filters six published articles by generated category", async ({ page }) => {
  await page.goto("/fr/bibliotheque/");
  await expect(page.locator(".library-card")).toHaveCount(6);
  await expect(page.getByRole("button", { name: "Tous", exact: true })).toHaveAttribute("aria-pressed", "true");
  await page.getByRole("button", { name: "Production vidéo", exact: true }).click();
  await expect(page.locator(".library-card")).toHaveCount(1);
  await expect(page.locator(".library-card")).toContainText("Pourquoi la vidéo est devenue essentielle");
  await expect(page.getByRole("button", { name: "Production vidéo", exact: true })).toHaveAttribute("aria-pressed", "true");
});

test("English Knowledge publishes six adapted articles with the required CTA", async ({ page }) => {
  await page.goto("/en/knowledge/");
  await expect(page.locator(".library-card")).toHaveCount(6);
  await expect(page.locator(".library-cta h2")).toHaveText("Looking for a Marketing Agency in Fez?");
  await expect(page.locator(".library-cta")).toContainText("YASHAL combines strategy, video production, web design, SEO and content");
});

test("The first article uses its dedicated cover in the library and both localized pages", async ({ page }) => {
  const cover = "/assets/images/library/marketing-agency-fez-cover.png";
  await page.goto("/fr/bibliotheque/");
  await expect(page.locator(`img[src*="${cover}"]`)).toHaveCount(2);
  await expect(page.locator(`img[src*="${cover}"]`).first()).toHaveJSProperty("naturalWidth", 1672);

  await page.goto("/fr/bibliotheque/comment-choisir-agence-communication-fes/");
  await expect(page.locator(`img[src*="${cover}"]`)).toHaveCount(1);
  await expect(page.locator(`img[src*="${cover}"]`)).toHaveAttribute("alt", "Image de couverture éditoriale sur le choix d’une agence de communication à Fès");

  await page.goto("/en/knowledge/how-to-choose-marketing-agency-fez/");
  await expect(page.locator(`img[src*="${cover}"]`)).toHaveCount(1);
  await expect(page.locator(`img[src*="${cover}"]`)).toHaveAttribute("alt", "Marketing strategy editorial cover for an article about choosing a marketing agency in Fez");
});

for (const width of [375, 768, 1024, 1440]) {
  test(`Library remains responsive at ${width}px`, async ({ page }) => {
    await page.setViewportSize({ width, height: 900 });
    await page.goto("/fr/bibliotheque/");
    await expect(page.locator(".library-card")).toHaveCount(6);
    expect(await page.evaluate(() => document.documentElement.scrollWidth > window.innerWidth + 1)).toBe(false);
    expect(await page.locator("img").evaluateAll((images) => images.filter((image) => image.complete && image.naturalWidth === 0).length)).toBe(0);
    const columns = await page.locator(".library-grid").evaluate((element) => getComputedStyle(element).gridTemplateColumns.split(" ").length);
    expect(columns).toBe(width < 768 ? 1 : width < 1200 ? 2 : 3);
  });
}

test("Arabic Knowledge publishes no unreviewed translation", async ({ page }) => {
  await page.goto("/ar/knowledge/");
  await expect(page.locator(".library-card")).toHaveCount(0);
  await expect(page.locator(".library-empty")).toContainText("لا توجد مقالات منشورة");
});

test("Library article exposes SEO, structured data, contents and internal links", async ({ page }) => {
  const path = "/fr/bibliotheque/seo-local-google-fes/";
  const response = await page.goto(path);
  expect(response?.ok()).toBe(true);
  await expect(page.locator("h1")).toHaveCount(1);
  expect(await page.locator(".library-toc a").count()).toBeGreaterThanOrEqual(8);
  await expect(page.locator('a[href="#optimiser-le-profil-google-business-profile"]')).toHaveCount(1);
  await expect(page.locator("#optimiser-le-profil-google-business-profile")).toHaveCount(1);
  await expect(page.locator('.library-prose a[href="/fr/services/referencement-seo/"]')).toHaveCount(1);
  await expect(page.locator('.library-prose a[href="/fr/services/creation-site-web/"]')).toHaveCount(1);
  await expect(page.locator('link[rel="canonical"]')).toHaveAttribute("href", `https://yashalstudios.com${path}`);
  await expect(page.locator('link[rel="alternate"][hreflang="fr"]')).toHaveCount(1);
  await expect(page.locator('link[rel="alternate"][hreflang="en"]')).toHaveCount(1);
  await expect(page.locator('link[rel="alternate"][hreflang="ar"]')).toHaveCount(0);
  const schemas = await page.locator('script[type="application/ld+json"]').allTextContents();
  expect(schemas.some((value) => value.includes('"BlogPosting"'))).toBe(true);
  expect(schemas.some((value) => value.includes('"BreadcrumbList"'))).toBe(true);
  expect(schemas.some((value) => value.includes('"FAQPage"'))).toBe(true);
  await expect(page.locator(".library-article-cta h2")).toHaveText("Vous cherchez une agence de communication à Fès ?");
  await expect(page.locator(".library-related article")).toHaveCount(3);
});

test("Library language switch preserves the translated article", async ({ page }) => {
  await page.goto("/fr/bibliotheque/comment-choisir-agence-communication-fes/");
  await expect(page.getByRole("link", { name: "العربية", exact: true })).toHaveAttribute("href", "/ar/knowledge/");
  await page.getByRole("link", { name: "EN", exact: true }).click();
  await expect(page).toHaveURL(/\/en\/knowledge\/how-to-choose-marketing-agency-fez\/$/);
  await expect(page.locator("h1")).toHaveText("How to Choose a Marketing Agency in Fez");
});

test("Sitemap contains published library pages and excludes legacy drafts", async ({ page }) => {
  const response = await page.goto("/sitemap.xml");
  expect(response?.ok()).toBe(true);
  const sitemap = await page.locator("body").innerText();
  expect(sitemap).toContain("/fr/bibliotheque/seo-local-google-fes/");
  expect(sitemap).toContain("/en/knowledge/video-marketing-strategy/");
  expect(sitemap).toContain("/fr/bibliotheque/personal-branding-visibilite-clients/");
  expect(sitemap).not.toContain("marketing-medical-confiance");
});

for (const locale of locales) {
  for (const service of serviceKeys) {
    const path = servicePath(locale, service);
    test(`${path} is an indexable localized service`, async ({ page }) => {
      const response = await page.goto(path);
      expect(response?.ok()).toBe(true);
      await expect(page.locator("main#main")).toHaveCount(1);
      await expect(page.locator("h1")).toHaveCount(1);
      await expect(page.locator('script[type="application/ld+json"]')).toHaveCount(4);
      const canonical = await page.locator('link[rel="canonical"]').getAttribute("href");
      expect(canonical).not.toBeNull();
      expect(decodeURI(canonical || "")).toContain(path);
      await expect(page.locator('link[rel="alternate"][hreflang="fr"]')).toHaveCount(1);
      await expect(page.locator('link[rel="alternate"][hreflang="en"]')).toHaveCount(1);
      await expect(page.locator('link[rel="alternate"][hreflang="ar"]')).toHaveCount(1);
      expect(await page.evaluate(() => document.documentElement.scrollWidth > window.innerWidth + 1)).toBe(false);
    });
  }
}

test("Selected Work contains exactly five real video projects", async ({ page }) => {
  await page.goto("/fr/work/");
  await expect(page.locator(".portfolio-card")).toHaveCount(5);
  await expect(page.locator(".portfolio-thumbnail")).toHaveCount(5);
  await expect(page.locator("body")).not.toContainText("Contenu éducatif médical");

  const sources = await page.locator(".portfolio-card").evaluateAll((elements) =>
    elements.map((element) => element.getAttribute("data-video-src")),
  );
  expect(sources).toEqual([
    "/assets/videos/portfolio/marathon.mp4",
    "/assets/videos/portfolio/medical.mp4",
    "/assets/videos/portfolio/entertainment.mp4",
    "/assets/videos/portfolio/restaurant.mp4",
    "/assets/videos/portfolio/french-media.mp4",
  ]);

  const thumbnails = await page.locator(".portfolio-card").evaluateAll((elements) =>
    elements.map((element) => element.getAttribute("data-thumbnail-src")),
  );
  expect(thumbnails).toEqual([
    "/assets/images/portfolio/marathon-thumbnail.png",
    "/assets/images/portfolio/medical-thumbnail.png",
    "/assets/images/portfolio/entertainment-thumbnail.png",
    "/assets/images/portfolio/restaurant-thumbnail.png",
    "/assets/images/portfolio/press-thumbnail.png",
  ]);
  const thumbnailAlts = await page.locator(".portfolio-thumbnail").evaluateAll((elements) =>
    elements.map((element) => element.getAttribute("alt")),
  );
  expect(thumbnailAlts).toEqual([
    "Miniature du film événementiel Marathon",
    "Miniature du contenu médical du Dr Jihad Abbou",
    "Miniature du contenu social de divertissement",
    "Miniature du film publicitaire Restaurant et Bar",
    "Miniature du test vidéo éditorial pour un média français",
  ]);

  const marathonTrigger = page.getByRole("button", {
    name: "Voir le projet vidéo: Marathon — Film événementiel",
  });
  await marathonTrigger.focus();
  await marathonTrigger.press("Enter");
  const dialog = page.locator(".portfolio-dialog");
  await expect(dialog).toBeVisible();
  await expect(dialog.locator("video")).toHaveAttribute("controls", "");
  await expect(dialog.locator("video")).toHaveAttribute("playsinline", "");
  await expect(dialog.locator("video")).toHaveAttribute(
    "poster",
    "/assets/images/portfolio/marathon-thumbnail.png",
  );
  await expect(dialog.locator("video source")).toHaveAttribute(
    "src",
    "/assets/videos/portfolio/marathon.mp4",
  );
  await expect(dialog.locator("video")).not.toHaveAttribute("autoplay", "");
  await page.keyboard.press("Escape");
  await expect(dialog).toBeHidden();
  await expect(marathonTrigger).toBeFocused();
});

test("Arabic mobile layout remains RTL without overflow", async ({ page }) => {
  await page.setViewportSize({ width: 390, height: 844 });
  await page.goto("/ar/");
  await expect(page.locator("html")).toHaveAttribute("dir", "rtl");
  await expect(page.locator(".mobile-menu")).toBeVisible();
  await expect(page.locator(".desktop-nav")).toBeHidden();
  expect(
    await page.evaluate(
      () => document.documentElement.scrollWidth > window.innerWidth + 1,
    ),
  ).toBe(false);
});

test("Reduced motion preserves visible content and stops continuous hero motion", async ({
  page,
}) => {
  await page.emulateMedia({ reducedMotion: "reduce" });
  await page.goto("/fr/");

  const motionState = await page.evaluate(() => {
    const reveal = document.querySelector<HTMLElement>("[data-reveal]");
    const orbit = document.querySelector<HTMLElement>(".orbit-outer");
    return {
      revealOpacity: reveal ? getComputedStyle(reveal).opacity : null,
      orbitAnimation: orbit ? getComputedStyle(orbit).animationName : null,
      videoCount: document.querySelectorAll(".hero-media video").length,
      videoPaused: document.querySelector<HTMLVideoElement>(".hero-media video")?.paused,
      autoplay: document.querySelector(".hero-media video")?.hasAttribute("autoplay"),
    };
  });

  expect(motionState.revealOpacity).toBe("1");
  expect(motionState.orbitAnimation).toBe("none");
  expect(motionState.videoCount).toBe(1);
  expect(motionState.videoPaused).toBe(true);
  expect(motionState.autoplay).toBe(false);
});

test("Hero video and Services menu expose the expected controls", async ({ page }) => {
  await page.goto("/en/");
  const video = page.locator(".hero-media video");
  await expect(video).toHaveCount(1);
  await expect(video).toHaveAttribute("autoplay", "");
  await expect(video).toHaveAttribute("loop", "");
  await expect(video).toHaveAttribute("playsinline", "");
  await expect(video.locator("source")).toHaveAttribute("src", "/assets/videos/hero.mp4");
  await expect(page.locator(".hero-overlay-title")).toHaveText("YASHAL — MARKETING AGENCY");
  await expect(page.locator(".hero-scroll-cue")).toHaveAttribute("href", "#home-after-hero");
  await expect(page.locator("#home-after-hero.presentation-section")).toHaveCount(1);
  await expect(page.locator("#home-after-hero h2")).toHaveText(
    "We build the systems, assets and trust ambitious businesses need to grow.",
  );
  await expect(page.locator(".work-preview .portfolio-card")).toHaveCount(5);

  const trigger = page.locator(".services-trigger");
  await trigger.focus();
  await trigger.press("ArrowDown");
  await expect(trigger).toHaveAttribute("aria-expanded", "true");
  await expect(page.locator(".services-dropdown a")).toHaveCount(6);
  await page.keyboard.press("Escape");
  await expect(trigger).toHaveAttribute("aria-expanded", "false");
});
