import { readFileSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { expect } from "e2e";
import { APP_DIR } from "../e2e.config.ts";
import { test, WEB } from "./t3.ts";

const tex = String.raw`R_e=\underbrace{\frac{1.0176}{32}}_{\text{3.18% dividend yield}}
+\underbrace{6\%}_{\text{growth}}
=\boxed{9.18\%}`;
const reply = `Reported equation:\n\\[\n${tex}\n\\]\n\nMalformed control:\n\\[\n\\frac{1}{\n\\]\n\nValid control: \\(1+1=2\\).\n\nEquation complete.`;

test("A completed equation with a bare percent typesets and preserves copied TeX", WEB, async ({ t3, app, screen, browser }) => {
  // Replace only replay data; both app commits receive the identical authored response.
  const frames = [
    { type: "expect_outbound", frame: { kind: "request", method: "session/prompt", params: "<any>" } },
    { type: "emit_inbound", frame: { kind: "notification", method: "session/update", params: { sessionId: "replay", update: { sessionUpdate: "agent_message_chunk", content: { type: "text", text: reply } } } } },
    { type: "emit_inbound", frame: { kind: "response", method: "session/prompt", result: { stopReason: "end_turn" } } },
  ];
  writeFileSync(join(APP_DIR, "apps/server/scripts/dev-replay/showcase_transcript.ndjson"), frames.map(x => JSON.stringify(x)).join("\n") + "\n");
  const project = await t3.project("Equation demo");
  await t3.thread({ project, title: "Dividend yield equation", messages: ["Show the reported dividend yield equation and a malformed control."], model: "showcase" });
  await t3.open();
  await screen.getByRole("button", "Dividend yield equation, Done, Equation demo").waitFor({ state: "visible" });
  await app.open("/settings/appearance");
  const toggle = screen.getByRole("switch", "Render math");
  if (!(await toggle.isChecked())) await toggle.tap();
  await app.open("/");
  await screen.getByRole("button", "Dividend yield equation, Done, Equation demo").tap();
  await screen.getByText("Equation complete.", { exact: false }).waitFor({ state: "visible" });
  await browser.locator('[data-markdown-math="inline"] .katex').waitFor({ state: "visible" });
  await screen.getByText("Syncing messages...", { exact: false }).waitFor({ state: "hidden" });
  await browser.evaluate(async () => { await document.fonts.ready; });
  let previous = await app.screenshot("settling");
  for (let attempt = 0; attempt < 10; attempt++) {
    await new Promise(resolve => setTimeout(resolve, 500));
    const current = await app.screenshot("completed-equation");
    if (readFileSync(previous).equals(readFileSync(current))) break;
    previous = current;
  }
  await expect(browser.locator('[data-markdown-math="display"]').nth(1)).toContainText(String.raw`\frac{1}{`);
  await browser.evaluate(() => {
    const equation = document.querySelector('[data-markdown-math="display"]')!;
    const range = document.createRange(); range.selectNodeContents(equation);
    const selection = window.getSelection()!; selection.removeAllRanges(); selection.addRange(range);
  });
  await browser.keyboard.press("Control+c");
  await screen.getByRole("textbox").tap();
  await browser.keyboard.press("Control+v");
  const copied = await browser.evaluate(() => (document.querySelector('[data-testid="composer-editor"]') as HTMLElement).innerText);
  expect(copied).toContain(tex);
  expect(copied).toContain("3.18% dividend yield");
  await app.screenshot("copied-original-source");
  await expect(browser.locator('[data-markdown-math="display"] .katex').first()).toBeVisible();
});
