import { execFileSync } from "node:child_process";
import { expect } from "e2e";
import { test, WEB } from "./t3.ts";

// A controlled 12-second transport delay makes a pending local status read repeatable.
// The app, RPC handlers, Git repository, and checkout are real and unmodified.
test("Picking a branch starts checkout while the opening status read is pending", WEB,
  async ({ t3, app, screen, browser }) => {
    const project = await t3.project("branch-timing", { "README.md": "Synthetic branch timing fixture.\n" });
    execFileSync("git", ["branch", "feature/ready"], { cwd: project });
    await t3.thread({ project, title: "Branch checkout timing", messages: ["Ready for branch switching"] });
    await browser.addInitScript(() => {
      const state = { armed: false, pending: false, switchedWhilePending: false, refreshes: 0 };
      (window as any).__pickerProof = state;
      const original = WebSocket.prototype.send;
      WebSocket.prototype.send = function (data) {
        let messages: any[] = [];
        try {
          const parsed = JSON.parse(String(data));
          messages = Array.isArray(parsed) ? parsed : [parsed];
        } catch {}
        if (messages.some((message) => message.tag === "vcs.switchRef") && state.pending) {
          state.switchedWhilePending = true;
        }
        if (state.armed && messages.some((message) => message.tag === "vcs.refreshStatus")) {
          state.armed = false;
          state.pending = true;
          state.refreshes++;
          setTimeout(() => {
            original.call(this, data);
            state.pending = false;
          }, 12000);
          return;
        }
        return original.call(this, data);
      };
    });
    await t3.open();
    await screen.getByTestId("sidebar-row-card").tap();
    const picker = screen.getByRole("region", "Version Control").getByRole("combobox");
    // Action auto-waiting allows initial branch loading to settle before arming the delay.
    await picker.tap();
    await browser.keyboard.press("Escape");
    await browser.evaluate(() => { (window as any).__pickerProof.armed = true; });
    await picker.tap();
    await screen.getByPlaceholder("Search refs...").fill("feature/ready");
    await screen.getByRole("option", /^feature\/\s*ready(?: current)?$/).waitFor();
    await browser.evaluate(() => new Promise((resolve) => setTimeout(resolve, 13000)));
    await browser.keyboard.press("Enter");
    await browser.evaluate(() => new Promise((resolve) => setTimeout(resolve, 2000)));
    await app.screenshot("waited-for-refresh-control");
    await picker.tap();
    await screen.getByPlaceholder("Search refs...").fill("main");
    await screen.getByRole("option", /^main$/).waitFor();
    await browser.keyboard.press("Enter");
    await browser.evaluate(() => new Promise((resolve) => setTimeout(resolve, 2000)));
    if (execFileSync("git", ["branch", "--show-current"], { cwd: project, encoding: "utf8" }).trim() !== "main") {
      throw new Error("Fixture reset did not return the real Git checkout to main");
    }
    await browser.evaluate(() => {
      (window as any).__pickerProof.armed = true;
      (window as any).__pickerProof.switchedWhilePending = false;
    });
    await picker.tap();
    await screen.getByPlaceholder("Search refs...").fill("feature/ready");
    await screen.getByRole("option", /^feature\/\s*ready(?: current)?$/).waitFor();
    await browser.keyboard.press("Enter");
    await browser.evaluate(() => new Promise((resolve) => setTimeout(resolve, 2000)));
    await app.screenshot("two-seconds-after-immediate-selection");
    const observation = await browser.evaluate(() => ({ ...(window as any).__pickerProof }));
    const actualGitBranch = execFileSync("git", ["branch", "--show-current"], { cwd: project, encoding: "utf8" }).trim();
    console.log("ORDERING_PROOF", JSON.stringify({ ...observation, actualGitBranch }));
    if (!observation.pending) throw new Error("The controlled status delay expired before the capture");
    await browser.evaluate(() => new Promise((resolve) => setTimeout(resolve, 13000)));
    await app.screenshot("after-status-delay-released");
    // The assertion concerns the broken ordering, rather than a subjective speed threshold.
    expect(observation.switchedWhilePending).toBe(true);
  });
