import { readFile } from "node:fs/promises";
import { setTimeout } from "node:timers/promises";
import { expect } from "e2e";
import { T3_HOME } from "../e2e.config.ts";
import { makeState, runPromise, test, WEB } from "./t3.ts";

// Synthetic ACP recording, replayed through the real provider adapter and server.
test("One earlier-history action stops at the agent opener", { ...WEB, timeout: 600_000, video: "off" }, async ({ t3, app, screen, browser }) => {
    const stableScreenshot = async (label: string) => {
      let previous = await app.screenshot(`${label}-stability-check`);
      for (let attempt = 0; attempt < 12; attempt++) {
        await setTimeout(500);
        const current = await app.screenshot(`${label}-stable-${attempt}`);
        if ((await readFile(previous)).equals(await readFile(current))) return current;
        previous = current;
      }
      throw new Error("The page did not settle for its capture");
    };
    const project = await t3.project("History demonstration");
    await t3.thread({ project, title: "Earlier agent work", messages: ["Archived request"] });
    const cli = makeState(T3_HOME).cli;
    const listed = JSON.parse((await runPromise(cli(["thread", "list", "--project", project, "--json"]))).stdout);
    const threadId = listed[0].threadId;
    await t3.open();
    await screen.getByText("Earlier agent work", { exact: true }).first().waitFor({ state: "visible", timeout: 180_000 });
    await app.open(await browser.evaluate((id: string) => { const row = document.querySelector(`[data-thread-item$=":${id}"]`); if (!row) throw new Error("Thread row missing"); return "/" + row.getAttribute("data-thread-item")!.replace(":", "/"); }, threadId));
    await screen.getByRole("textbox").fill("Older human history — retain for a later click");
    await screen.getByRole("textbox").press("Enter");
    await screen.getByText("Older human request complete.", { exact: false }).first().waitFor({ state: "visible", timeout: 180_000 });
    await screen.getByRole("button", "Stop generation").waitFor({ state: "hidden" });
    // Leave the thread while history is generated so the first opening uses a bounded snapshot.
    await app.open("/");
    await runPromise(cli(["thread", "send", threadId, "Agent inspection run — stop loading here", "--wait", "--json"]));
    await screen.getByText("Earlier agent work", { exact: true }).first().waitFor({ state: "visible", timeout: 180_000 });
    await app.open(await browser.evaluate((id: string) => { const row = document.querySelector(`[data-thread-item$=":${id}"]`); if (!row) throw new Error("Thread row missing"); return "/" + row.getAttribute("data-thread-item")!.replace(":", "/"); }, threadId));
    for (let i = 1; i <= 10; i++) {
      await screen.getByRole("textbox").fill(`Recent human request ${i}`);
      await screen.getByRole("textbox").press("Enter");
      await screen.getByText(`Recent request ${i} complete.`, { exact: false }).first().waitFor({ state: "visible", timeout: 180_000 });
      await screen.getByRole("button", "Stop generation").waitFor({ state: "hidden" });
    }
    await app.open("/");
    await browser.evaluate(async () => { for (const db of await indexedDB.databases()) if (db.name) indexedDB.deleteDatabase(db.name); });
    await app.open("/");
    await screen.getByText("Earlier agent work", { exact: true }).first().waitFor({ state: "visible", timeout: 180_000 });
    await app.open(await browser.evaluate((id: string) => { const row = document.querySelector(`[data-thread-item$=":${id}"]`); if (!row) throw new Error("Thread row missing"); return "/" + row.getAttribute("data-thread-item")!.replace(":", "/"); }, threadId));
    const top = async () => browser.evaluate(() => { for (const el of document.querySelectorAll("*")) if (el.scrollHeight > el.clientHeight + 100 && ["auto", "scroll"].includes(getComputedStyle(el).overflowY)) el.scrollTop = 0; });
    await top();
    const earlier = screen.getByRole("button", "Load earlier turns");
    await earlier.scrollIntoView();
    await stableScreenshot("before-one-click");
    await app.startRecording();
    await earlier.tap();
    await screen.getByText("Agent inspection run — stop loading here", { exact: false }).first().waitFor({ state: "visible", timeout: 180_000 });
    await screen.getByText("Loading earlier turns…", { exact: true }).waitFor({ state: "hidden" });
    await top();
    await stableScreenshot("after-one-click");
    await app.stopRecording();
    await expect(earlier).toBeVisible();
    await expect(screen.getByText("Older human history — retain for a later click", { exact: false })).toBeHidden();
});
