import { writeFile } from "node:fs/promises";
import { expect } from "e2e";
import { test, WEB } from "./t3.ts";

test("Diff resumes its scroll position after switching projects and threads", WEB, async ({ t3, app, screen, browser }) => {
  const original = Array.from({ length: 600 }, (_, i) => `export const line${i + 1} = ${i + 1};`).join("\n") + "\n";
  const changed = Array.from({ length: 600 }, (_, i) => `export const line${i + 1} = ${i + 1001};`).join("\n") + "\n";
  const alpha = await t3.project("alpha", { "big.ts": original });
  const beta = await t3.project("beta", { "big.ts": original });
  await writeFile(`${alpha}/big.ts`, changed);
  await writeFile(`${beta}/big.ts`, changed);
  await t3.thread({ project: alpha, title: "Review alpha", messages: ["Review the pending change"] });
  await t3.thread({ project: beta, title: "Review beta", messages: ["Review the pending change"] });
  await t3.open();
  await screen.getByRole("button", "Review alpha, Done, alpha", { exact: true }).tap();
  await screen.getByRole("button", "Toggle right panel", { exact: true }).tap();
  await screen.getByText("Diff", { exact: true }).first().tap();
  // Pierre's scroll surface has no role; identify it by its long scrollable layout.
  const surface = async () => browser.evaluate(() => {
    const nodes = [...document.querySelectorAll<HTMLElement>("div")].filter(e => e.clientHeight > 100 && e.scrollHeight > 10000 && ["auto", "scroll"].includes(getComputedStyle(e).overflowY));
    const e = nodes.sort((a,b) => b.scrollHeight - a.scrollHeight)[0];
    if (!e) throw new Error("Long diff scroll surface not loaded");
    const r = e.getBoundingClientRect();
    return { top: e.scrollTop, height: e.scrollHeight, x: r.x + r.width / 2, y: r.y + r.height / 2 };
  });
  const expand = screen.getByRole("button", "Expand big.ts", { exact: true });
  await expand.waitFor({ state: "visible" });
  await expand.tap();
  // Wait for the file's real diff content before using the wheel.
  await browser.locator("[data-diff-copy-path]").first().waitFor({ state: "visible" });
  let position;
  for (let attempt = 0; attempt < 60; attempt++) {
    try { position = await surface(); break; } catch { await new Promise(resolve => setTimeout(resolve, 250)); }
  }
  if (!position) throw new Error("Long diff did not load");
  await browser.mouse.move(position.x, position.y);
  await browser.mouse.wheel(0, 4000);
  await new Promise(resolve => setTimeout(resolve, 600));
  const saved = await surface();
  if (saved.top < 3500) throw new Error(`Wheel did not scroll the diff: ${saved.top}`);
  await app.screenshot("alpha-before-switch");
  await screen.getByRole("button", "Review beta, Done, beta", { exact: true }).tap();
  if (!(await screen.getByRole("region", "Workspace panel: Diff", { exact: true }).isVisible())) {
    await screen.getByRole("button", "Toggle right panel", { exact: true }).tap();
    await screen.getByText("Diff", { exact: true }).first().tap();
  }
  await screen.getByRole("button", "Review alpha", { exact: false }).first().tap();
  await new Promise(resolve => setTimeout(resolve, 1500));
  await app.screenshot("alpha-after-round-trip");
  await expect.poll(async () => Math.abs((await surface()).top - saved.top)).toBeLessThan(80);
});
