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

// Accessibility pass (feat/accessibility-pass) — non-kiosk public-web a11y.
// Each block maps to a task in
// docs/superpowers/plans/2026-06-30-accessibility-and-about-page.md.

test.describe("Task 1 — Output panel layout", () => {
  test("language picker sits below the Audio control", async ({ page }) => {
    await page.goto("/");
    const audio = page.locator("#audio");
    const lang = page.locator("#lang-select");
    await expect(audio).toBeVisible();
    await expect(lang).toBeVisible();
    const aBox = await audio.boundingBox();
    const lBox = await lang.boundingBox();
    expect(lBox!.y).toBeGreaterThan(aBox!.y); // lang renders lower than audio
  });

  test("globe icon is inline-left of the language select (same row)", async ({ page }) => {
    await page.goto("/");
    const pick = page.locator(".lang-pick");
    const select = page.locator("#lang-select");
    const pBox = await pick.boundingBox();
    const sBox = await select.boundingBox();
    expect(sBox!.x).toBeGreaterThan(pBox!.x); // select right of the label's left edge
    expect(pBox!.height).toBeLessThan(40);    // one row, not stacked
  });
});

test.describe("Task 4 — Photosensitivity warning gate", () => {
  test("motion warning gate shows once, then is remembered", async ({ page }) => {
    await page.goto("/");
    const gate = page.locator("#motion-warning");
    await expect(gate).toBeVisible({ timeout: 30000 }); // shown after media preload + splash fade
    await page.locator("#motion-warning-continue").click();
    await expect(gate).toBeHidden();
    // Reload in the SAME context: dismissal persisted, gate stays hidden.
    await page.reload();
    await expect(page.locator("#motion-warning")).toBeHidden();
    await expect(page.locator("#run-sim")).toBeVisible();
  });
});

test.describe("Task 5 — Reduced motion", () => {
  test("reduce-motion toggle pauses video playback", async ({ page }) => {
    await page.emulateMedia({ reducedMotion: "no-preference" }); // deterministic default-off
    await page.goto("/");
    await page.locator("#motion-warning-continue").click().catch(() => {});
    const rm = page.locator("#reduce-motion");
    await expect(rm).not.toBeChecked();          // default-off under no-preference
    await page.locator("#run-sim").click();
    await page.waitForTimeout(500);
    await expect
      .poll(() => page.locator("#vid-loop").evaluate((v: HTMLVideoElement) => v.paused))
      .toBe(false);                              // experience running → video plays
    await page.locator('label[for="reduce-motion"]').click(); // hidden input: toggle via its label
    await expect(rm).toBeChecked();
    await expect
      .poll(() => page.locator("#vid-loop").evaluate((v: HTMLVideoElement) => v.paused))
      .toBe(true);                               // reduced motion → frozen
  });
});

test.describe("Task 6 — Keyboard + ARIA dial", () => {
  test("altitude dial is a keyboard-operable slider", async ({ page }) => {
    await page.goto("/");
    const dial = page.locator("#dial");
    await expect(dial).toHaveAttribute("role", "slider");
    await expect(dial).toHaveAttribute("tabindex", "0");
    await dial.focus();
    const before = await page.locator("#scale-name").textContent();
    await dial.press("ArrowDown");               // descend one altitude
    await expect
      .poll(async () => page.locator("#scale-name").textContent())
      .not.toBe(before);
    await dial.press("Home");                    // jump to the top scale (cosmos)
    await expect(page.locator("#scale-name")).toHaveText(/cosmos|宇宙/i);
    await expect(dial).toHaveAttribute("aria-valuenow", "0");
  });
});

test.describe("Task 7 — Screen-reader narration", () => {
  test("an aria-live region narrates the current scale", async ({ page }) => {
    await page.goto("/");
    const live = page.locator("#sr-status");
    await expect(live).toHaveAttribute("aria-live", "polite");
    await page.locator("#dial").focus();
    await page.locator("#dial").press("Home");
    await expect
      .poll(async () => (await live.textContent())?.toLowerCase())
      .toContain("cosmos");
  });

  test("decorative overlay SVGs are hidden from assistive tech", async ({ page }) => {
    await page.goto("/");
    await expect(page.locator("#overlay")).toHaveAttribute("aria-hidden", "true");
    await expect(page.locator("#affect")).toHaveAttribute("aria-hidden", "true");
  });
});

test.describe("Task 9 — About page", () => {
  test("about page loads, names its themes, and links back", async ({ page }) => {
    await page.goto("/about.html");
    await expect(page.locator("h1")).toContainText(/about/i);
    await expect(page.getByText(/imperfect/i)).toBeVisible();        // honest-about-limits beat
    await expect(page.getByText(/space exploration/i)).toBeVisible(); // technology arc beat
    await expect(page.getByText(/large language models/i)).toBeVisible();
    await page.locator(".back-link").click();
    await expect(page).toHaveURL(/index\.html|\/$/);
  });

  test("the header links to the about page", async ({ page }) => {
    await page.goto("/");
    await expect(page.locator('a[href="about.html"]')).toBeVisible();
  });
});
