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

test("Repeated tool-call diffs render and collapse independently", WEB, async ({t3, app, screen, browser}) => {
  const capture = async (label: string) => {
    await browser.evaluate(async () => {
      const bodies = [...document.querySelectorAll("diffs-container")].flatMap(host =>
        [...(host.shadowRoot?.querySelectorAll("[data-diff], [data-file]") ?? [])]);
      await Promise.all(bodies.flatMap(body => body.getAnimations({subtree:true}).map(animation => animation.finished.catch(() => {}))));
      return true;
    });
    await app.screenshot(label);
  };
  const oldText = "export function sum(a: number, b: number) {\n  return a + b;\n}\n";
  const firstText = oldText + "\nexport function clamp(value: number, min: number, max: number) {\n  return Math.min(Math.max(value, min), max);\n}\n";
  const secondText = firstText.replace("return a + b;", "return Number(a) + Number(b);");
  const diffs = [
    {type: "diff", path: "src/math.ts", oldText, newText: firstText},
    {type: "diff", path: "src/math.ts", oldText: firstText, newText: secondText},
    {type: "diff", path: "src/math.ts", oldText: firstText, newText: secondText},
  ];
  const notification = (update: unknown) => ({type:"emit_inbound",frame:{kind:"notification",method:"session/update",params:{sessionId:"repeated-diff-session",update}}});
  const fixture = [
    {type:"expect_outbound",frame:{kind:"request",method:"session/prompt",params:"<any>"}},
    notification({sessionUpdate:"tool_call",toolCallId:"repeated-edit",kind:"edit",title:"Edit src/math.ts",status:"pending",rawInput:{path:"src/math.ts"},content:diffs}),
    notification({sessionUpdate:"tool_call_update",toolCallId:"repeated-edit",status:"completed",content:diffs}),
    notification({sessionUpdate:"agent_message_chunk",content:{type:"text",text:"Added clamp and refined sum. Three same-file diff blocks are included in this edit."}}),
    {type:"emit_inbound",frame:{kind:"response",method:"session/prompt",result:{stopReason:"end_turn"}}},
  ].map(x=>JSON.stringify(x)).join("\n")+"\n";
  // Replace only the replay input; both app revisions execute their own adapters and viewer.
  const fixturePath = `${APP_DIR}/apps/server/scripts/dev-replay/showcase_transcript.ndjson`;
  const original = await readFile(fixturePath,"utf8");
  const project = await t3.project("Repeated diffs", {"src/math.ts":oldText});
  let thread;
  try {
    await writeFile(fixturePath,fixture);
    thread = await t3.thread({project,title:"Repeated same-file edits",messages:["Add clamp and refine sum"],model:"showcase"});
  } finally { await writeFile(fixturePath,original); }
  await t3.open(thread);
  await screen.getByRole("button", /^Worked for/).tap();
  await screen.getByRole("button", /Changed 1 file/).tap();
  await screen.getByRole("button", "Open diff").tap();
  await browser.locator('diffs-container, h1:has-text("Something went wrong")').first().waitFor({state:"visible"});
  await capture("repeated-diffs-open");
  await expect(browser.locator("diffs-container")).toHaveCount(3);
  await expect(screen.getByText("Something went wrong",{exact:false})).toBeHidden();
  await screen.getByRole("button", "Expand all files").tap();
  await expect(browser.locator("diffs-container [data-diff]")).toHaveCount(3);
  await capture("all-occurrences-expanded");
  await browser.locator("diffs-container [data-diffs-header]").nth(1).tap();
  await expect(browser.locator("diffs-container:nth-of-type(1) [data-diff]")).toHaveCount(1);
  await expect(browser.locator("diffs-container:nth-of-type(2) [data-diff]")).toHaveCount(0);
  await expect(browser.locator("diffs-container:nth-of-type(3) [data-diff]")).toHaveCount(1);
  await capture("second-occurrence-collapsed");
  await screen.getByRole("button", "Expand src/math.ts").tap();
  await expect(browser.locator("diffs-container [data-diff]")).toHaveCount(3);
  await capture("second-occurrence-expanded");
  await browser.locator("diffs-container [data-title] bdi").nth(1).tap();
  await expect(screen.getByRole("button", "math.ts")).toBeVisible();
  await browser.locator(".file-preview-virtualizer [data-line]").filter({hasText:"return a + b;"}).first().waitFor({state:"visible"});
  await capture("filename-opens-source");
});
