/// <reference lib="dom" />
import { expect } from "e2e";
import { run } from "./shell.ts";
import { runPromise, test, WEB } from "./t3.ts";
const H = "0cd3702f060909d3161d1095b8347d4d07671427";
const OLD = "92bc5c58";
const cases = [
  ["Control line 255", `4330/diffs#${H}_250_255`, "255"],
  ["File anchor", `4330/diffs#diff-content-${H}`, "file"],
  ["File query", `4330/diffs?file=${H}`, "file"],
  ["Rapid Diffs line 253", `4330/diffs#line_${H.slice(0,9)}_A253`, "253"],
  ["Removed old line 107", `4330/diffs#92bc5c585cbecd1fbb0bea92f45a5e7bf927a435_107_106`, "old"],
  ["Commit excludes other changes", "4420/diffs?commit_id=4652e8fa455dcfd3bcea96947ea5f2533834431c", "commit"],
] as const;
test("GitLab MR links reveal files, correct line sides and commit changes", WEB, async ({ t3, app, browser, screen }) => {
  const project = await t3.project("gitlab-cli");
  await runPromise(run("git", ["remote", "add", "origin", "https://gitlab.com/gitlab-org/cli.git"], { cwd: project }));
  await runPromise(run("git", ["fetch", "--depth=1", "origin", "main"], { cwd: project }));
  await runPromise(run("git", ["reset", "--hard", "FETCH_HEAD"], { cwd: project }));
  const threads = [];
  for (const [label, path] of cases) threads.push(await t3.thread({ project, title: label, messages: [`[${label}](https://gitlab.com/gitlab-org/cli/-/merge_requests/${path})`] }));
  const results = [];
  for (const [i, [label, , kind]] of cases.entries()) {
    await t3.open(threads[i]);
    await screen.getByRole("button", /^Agent /).first().tap();
    await screen.getByRole("link", label).tap();
    await screen.getByRole("button", /^Diff scope:/).waitFor({ state: "visible", timeout: 120000 });
    if (await screen.getByRole("button", "Maximize panel", { exact: true }).count()) await screen.getByRole("button", "Maximize panel", { exact: true }).tap();
    await screen.getByText(/^[123] files?$/).first().waitFor({ state: "visible", timeout: 120000 });
    await browser.evaluate(() => { document.body.dispatchEvent(new MouseEvent("pointermove", { bubbles: true, clientX: 10, clientY: 400 })); });
    await new Promise(resolve => setTimeout(resolve, 1500));
    const state = await browser.evaluate(() => {
      const roots = Array.from(document.querySelectorAll("*")).flatMap(h => h.shadowRoot ? [h.shadowRoot] : []);
      return {
        lines: roots.flatMap(r => Array.from(r.querySelectorAll("[data-line]"), l => l.textContent ?? "")),
        selected: roots.flatMap(r => Array.from(r.querySelectorAll("[data-selected-line]"), l => ({ text: l.textContent, attrs: Array.from(l.attributes, a => [a.name,a.value]) }))),
        headers: roots.flatMap(r => Array.from(r.querySelectorAll("[data-title]"), l => l.textContent ?? "")),
        text: document.body.innerText,
      };
    });
    await app.screenshot(`${i+1}-${label.toLowerCase().replaceAll(" ", "-")}`);
    results.push({ label, kind, state });
  }
  await runPromise(run("python3", ["-c", "import sys;print(sys.argv[1])", JSON.stringify(results)], { echo: true }));
  expect(results.filter(r => r.kind === "file").every(r => r.state.lines.some(l => l.includes("Test_listIssueNotes")))).toBe(true);
  expect(results.find(r => r.kind === "253")?.state.selected.some(l => l.text === "253")).toBe(true);
  expect(results.find(r => r.kind === "old")?.state.selected.some(l => l.text === "107")).toBe(true);
  expect(results.find(r => r.kind === "commit")?.state.text).toContain("1 file");
  expect(results.find(r => r.kind === "commit")?.state.headers.join("\n")).not.toContain("orbit_test.go");
});
