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

test("Opening a failed thread acknowledges its row and collapsed folder", WEB, async ({ t3, app, screen }) => {
  const capture = async (label: string) => {
    await screen.getByText("Syncing messages...", { exact: false }).waitFor({ state: "hidden" });
    await new Promise((resolve) => setTimeout(resolve, 750));
    await app.screenshot(label);
  };
  const settingsPath = `${T3_HOME}/userdata/settings.json`;
  const settings = JSON.parse(await readFile(settingsPath, "utf8"));
  settings.providerInstances.devReplay.config.customModels = ["no-such-scenario"];
  await writeFile(settingsPath, JSON.stringify(settings));
  const project = await t3.project("Failure demo");
  const otherProject = await t3.project("Other work");
  const other = await t3.thread({ project: otherProject, title: "Other thread", messages: ["hello"], model: "showcase" });
  const good = await t3.thread({ project, title: "Good thread", messages: ["hello"], model: "showcase" });
  const { cli } = makeState(T3_HOME);
  const started = await runPromise(cli(["thread", "start", project, "Fail please", "--title", "Failing thread", "--provider", "devReplay", "--model", "no-such-scenario", "--wait", "--json"], [0,1,2]));
  if (!started.stdout.trim()) throw new Error(started.stderr);
  const failed = JSON.parse(started.stdout);
  await t3.open(other);
  await screen.getByRole("button", /Other thread/).first().waitFor();
  await capture("01-unopened-failed-row");
  await t3.open(good);
  await screen.getByRole("button", /Other thread/).first().waitFor();
  await t3.open(other);
  await screen.getByRole("button", /Other thread/).first().waitFor();
  await t3.open("/settings/labs");
  await screen.getByRole("switch", "Boring sidebar (group by project)").tap();
  await t3.open(other);
  await screen.getByRole("button", /Other thread/).first().waitFor();
  await screen.getByRole("button", "Failure demo", { exact: true }).tap();
  await capture("02-unopened-folder-dot");
  await t3.open(failed);
  await screen.getByText("Provider session failed to open", { exact: false }).first().waitFor();
  await capture("03-open-failure-details");
  await t3.open(other);
  await screen.getByRole("button", /Other thread/).first().waitFor();
  await capture("04-acknowledged-folder-dot");
  await expect.soft(screen.getByRole("button", /Failure demo.*failed/)).not.toBeVisible({ timeout: 1500 });
  await screen.getByRole("button", /Failure demo/).first().tap();
  await capture("05-acknowledged-failed-row");
  await expect.soft(screen.getByRole("button", /Failing thread/).first()).not.toContainText("Failed", { timeout: 1500 });
  await t3.open(other);
  await screen.getByRole("button", /Other thread/).first().waitFor();
  await capture("06-after-reload");
  await expect.soft(screen.getByRole("button", /Failing thread/).first()).not.toContainText("Failed", { timeout: 1500 });
  await runPromise(cli(["thread", "send", failed.threadId, "Fail again", "--wait", "--json"], [0,1,2]));
  await t3.open(other);
  await screen.getByRole("button", /Other thread/).first().waitFor();
  await capture("07-subsequent-failure");
  await screen.getByRole("button", /Failure demo/).first().tap();
  await capture("08-subsequent-failure-folder");
});
