import * as NodeCrypto from "@effect/platform-node/NodeCrypto";
import * as Net from "@t3tools/shared/Net";
import { readFile } from "node:fs/promises";
import { setTimeout as delay } from "node:timers/promises";
import { expect } from "e2e";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import * as Option from "effect/Option";
import * as Auth from "../../apps/server/src/auth/EnvironmentAuth.ts";
import * as Config from "../../apps/server/src/config.ts";
import { resolveCliAuthConfig } from "../../apps/server/src/cli/config.ts";
import { mcpToolSession } from "../../apps/server/src/mcp/AcpMcpStdioBridge.ts";
import { readLiveServerRuntimeState } from "../../apps/server/src/serverRuntimeState.ts";
import { T3_HOME } from "../e2e.config.ts";
import { test, WEB, runPromise } from "./t3.ts";

test("Interruption label shares the reason baseline at wide and wrapped widths", WEB, async ({ t3, app, screen, browser }) => {
  const project = await t3.project("Footer alignment");
  await t3.thread({ project, title: "Stopped task", messages: ["Review the sample project"], model: "showcase" });
  await t3.open();
  await screen.getByRole("button", "Stopped task, Done, Footer alignment").tap();
  await screen.getByRole("textbox").fill("Continue the review");
  await screen.getByRole("textbox").press("Enter");
  await screen.getByRole("button", "Stop generation").waitFor({ state: "visible" });
  await runPromise(Effect.gen(function* () {
    const config = yield* resolveCliAuthConfig({ baseDir: Option.some(T3_HOME) }, Option.none()).pipe(Effect.provide(Net.layer));
    yield* Effect.gen(function* () {
      const auth = yield* Auth.EnvironmentAuth;
      const issued = yield* Effect.acquireRelease(auth.issueMcpClientSession({ label: "Scenario", access: "full-access", peerLink: false, client: { deviceType: "bot" } }), s => auth.revokeSession(s.sessionId));
      const runtime = yield* readLiveServerRuntimeState(config.serverRuntimeStatePath);
      const session = yield* mcpToolSession({ endpoint: new URL("/mcp", Option.getOrThrow(runtime).origin).href, authorization: `Bearer ${issued.token}`, clientName: "scenario" });
      const listed: any = yield* session.call("t3_thread_list", { allProjects: true });
      if (!listed.structuredContent) throw new Error(JSON.stringify(listed));
      const thread = listed.structuredContent.threads.find((t: any) => t.title === "Stopped task");
      const result: any = yield* session.call("t3_thread_interrupt", { threadId: thread.threadId ?? thread.id, reason: "Enough information is available; preserve the findings for the final response.", stop: true });
      if (result.isError) throw new Error(JSON.stringify(result));
    }).pipe(Effect.scoped, Effect.provide(Auth.layerRuntime.pipe(Layer.provide(Config.layer(config)))));
  }).pipe(Effect.provide(NodeCrypto.layer)));
  await screen.getByText("Run interrupted", { exact: true }).first().waitFor({ state: "visible" });
  const offsets: number[] = [];
  for (const [label, width] of [["wide", 1600], ["wrapped", 640]] as const) {
    await browser.setViewport({ width, height: 800 });
    let stable = false;
    for (let attempt = 0; attempt < 5; attempt++) {
      const a = await app.screenshot(`${label}-stability-a-${attempt}`);
      await delay(500);
      const b = await app.screenshot(`${label}-stability-b-${attempt}`);
      if ((await readFile(a)).equals(await readFile(b))) { stable = true; break; }
    }
    if (!stable) throw new Error("Capture did not settle");
    await app.screenshot(label);
    offsets.push(await browser.evaluate(() => {
      const label = Array.from(document.querySelectorAll("span")).find(e => e.textContent === "Run interrupted")!;
      const detail = label.nextElementSibling!;
      const textRect = (el: Element) => { const node = Array.from(el.childNodes).find(n => n.nodeType === Node.TEXT_NODE && n.textContent!.trim()); const r = document.createRange(); r.setStart(node!, 0); r.setEnd(node!, Math.min(1, node!.textContent!.length)); return r.getBoundingClientRect(); };
      return Math.abs(textRect(label).bottom - textRect(detail).bottom);
    }));
  }
  console.log("Baseline offsets (wide, wrapped):", offsets);
  expect(Math.max(...offsets)).toBeLessThan(1);
});
