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

test("OMP asks two questions with inline free-text answers", WEB, async ({ t3, app, screen }) => {
  const captureComposer = async (label: string) => {
    const file = await app.screenshot(label);
    const cropped = await sharp(file).extract({ left: 290, top: 440, width: 690, height: 350 }).png().toBuffer();
    await writeFile(file, cropped);
    return file;
  };
  const stableScreenshot = async (label: string) => {
    for (let attempt = 0; attempt < 12; attempt++) {
      const before = await captureComposer(`${label}-stability`);
      await new Promise(resolve => setTimeout(resolve, 500));
      const after = await captureComposer(label);
      if ((await readFile(before)).equals(await readFile(after))) return;
    }
    throw new Error(`Capture did not settle: ${label}`);
  };
  // Replay the exact optional choice + __other shape emitted by OMP askDialog.
  const fixture = join(APP_DIR, "apps/server/scripts/dev-replay/showcase_transcript.ndjson");
  const original = await readFile(fixture, "utf8");
  const properties = {
    q0: { type: "string", title: "Which database should we use?", description: "Database", oneOf: [{ const: "Postgres", title: "Postgres" }, { const: "SQLite", title: "SQLite" }] },
    q0__other: { type: "string", title: "Other (type your own)" },
    q1: { type: "string", title: "Where should we deploy the app?", description: "Deployment", oneOf: [{ const: "Cloud", title: "Cloud" }, { const: "Self-hosted", title: "Self-hosted" }] },
    q1__other: { type: "string", title: "Other (type your own)" },
  };
  const frames = [
    { type: "expect_outbound", frame: { kind: "request", method: "session/prompt" } },
    { type: "emit_inbound", frame: { kind: "request", method: "elicitation/create", params: { sessionId: "replay", mode: "form", message: "Answer 2 questions", requestedSchema: { type: "object", properties } } } },
    { type: "emit_inbound", frame: { kind: "response", method: "session/prompt", result: { stopReason: "end_turn" } } },
  ];
  await writeFile(fixture, frames.map(frame => JSON.stringify(frame)).join("\n") + "\n");
  try {
    const project = await t3.project("Question demo");
    await t3.thread({ project, title: "Choose database and deployment", messages: ["Help choose the database and deployment."], model: "showcase" });
    await t3.open();
    await screen.getByTestId("sidebar-row-card").first().press("Enter");
    await screen.getByRole("button", "Postgres", { exact: false }).waitFor();
    await stableScreenshot("first-question");
    await screen.getByRole("button", "Postgres", { exact: false }).tap();
    await screen.getByText("2/", { exact: false }).waitFor();
    await stableScreenshot("second-question");
    await expect(screen.getByText("2/2")).toBeVisible();
    await expect(screen.getByText("Where should we deploy the app?")).toBeVisible();
    await expect(screen.getByRole("button", "Cloud", { exact: false })).toBeVisible();
    await expect(screen.getByRole("textbox")).toBeVisible();
  } finally {
    await writeFile(fixture, original);
  }
});
