import { expect } from "e2e";
import { run } from "./shell.ts";
import { runPromise, test, WEB } from "./t3.ts";

test("Open in and composer PR suggestions remain available", WEB, async ({ t3, app, screen, browser }) => {
  const project = await t3.project("Review demo", { "README.md": "Synthetic review workspace\n" });
  await runPromise(run("git", ["remote", "add", "origin", "https://github.com/example/repo.git"], { cwd: project }));
  const thread = await t3.thread({ project, title: "Coverage comparison", messages: ["Ready for review"] });
  await t3.open(thread);
  await expect(screen.getByText("first fixture turn complete", { exact: false })).toBeVisible();
  await browser.evaluate(async (threadId) => {
    const socket = new WebSocket(`${location.origin.replace(/^http/, "ws")}/ws?orchestrationProtocol=2`);
    await new Promise<void>((resolve, reject) => { socket.onopen = () => resolve(); socket.onerror = () => reject(new Error("seed socket failed")); });
    let counter = 0;
    const dispatch = (payload: object) => new Promise<void>((resolve, reject) => {
      const id = String(++counter);
      const onMessage = (event: MessageEvent) => {
        for (const message of [JSON.parse(event.data)].flat()) {
          if (message._tag === "Ping") socket.send(JSON.stringify({ _tag: "Pong" }));
          if (message._tag !== "Exit" || String(message.requestId) !== id) continue;
          socket.removeEventListener("message", onMessage);
          if (message.exit._tag === "Success") resolve(); else reject(new Error(JSON.stringify(message.exit)));
        }
      };
      socket.addEventListener("message", onMessage);
      socket.send(JSON.stringify({ _tag: "Request", id, tag: "orchestration.dispatchCommand", payload: { commandId: crypto.randomUUID(), threadId, ...payload }, headers: [] }));
    });
    for (const number of [42, ...Array.from({ length: 25 }, (_, index) => 4200 + index), 42]) {
      const key = { host: "github.com", repository: "example/repo", number };
      await dispatch({ type: "thread.pull-request.link", ...key, url: `https://github.com/example/repo/pull/${number}`, source: "agent" });
      await dispatch({ type: "thread.pull-request-link.sync", ...key, stack: null, snapshot: { state: "open", title: number === 42 ? "Older exact match" : `Recent ${number}`, headBranch: `review-${number}`, baseBranch: "main", isDraft: false, updatedAt: number === 42 ? "2025-01-01T00:00:00.000Z" : "2026-01-01T00:00:00.000Z", syncedAt: "2026-11-15T00:00:00.000Z" } });
    }
    socket.close();
  }, thread.threadId);
  await expect(screen.getByText(/(?:Loading|Syncing) messages/)).toBeHidden();
  await screen.getByRole("button", "Choose editor", { exact: true }).tap();
  await expect(screen.getByText(/(?:Loading|Syncing) messages/)).toBeHidden();
  await app.screenshot("local-open-in");
  await browser.keyboard.press("Escape");
  await screen.getByRole("textbox").fill("#42");
  await expect(screen.getByRole("option")).toHaveCount(12);
  await expect(screen.getByRole("option").first()).toContainText("Older exact match");
  await app.screenshot("old-exact-pr-first-twelve-results");
  await screen.getByRole("textbox").fill("#4200");
  await expect(screen.getByRole("option")).toHaveCount(1);
  await expect(screen.getByRole("option").first()).toContainText("#4200");
  await app.screenshot("recent-pr-one-row");
  await browser.keyboard.press("Escape");
  await screen.getByRole("textbox").fill("");
  await app.screenshot("menus-dismissed");
});
