import { expect } from "e2e";
import { test, WEB } from "./t3.ts";

test("Message search omits rolled-back turns and removed queued prompts", WEB, async ({t3, app, screen, browser}) => {
  const project = await t3.project("Search demo");
  const thread = await t3.thread({project, title: "Search demo", messages: ["Start"], model: "showcase"});
  const stoppedThread = await t3.thread({project, title: "Stopped search demo", messages: ["Start"], model: "multi-turn"});
  await browser.addInitScript((workspace: string) => {
    const redact = () => {
      const walker = document.createTreeWalker(document, NodeFilter.SHOW_TEXT);
      for (let node = walker.nextNode(); node; node = walker.nextNode()) {
        if (node.parentElement?.closest("script,style")) continue;
        if (node.textContent?.includes(workspace)) node.textContent = node.textContent.replaceAll(workspace, "/workspace/Search demo");
      }
    };
    new MutationObserver(redact).observe(document, {subtree: true, childList: true, characterData: true});
  }, project);
  await t3.open(thread);
  const composer = screen.getByRole("textbox");
  const stop = screen.getByRole("button", "Stop generation");
  const send = async (text: string) => {
    await screen.getByRole("button", "Submit message", {exact: true}).waitFor();
    await composer.fill(text);
    await composer.press("Enter");
    await stop.waitFor();
    await stop.waitFor({state: "hidden"});
  };
  await send("third turn mentions heronfeather");
  await send("fifth turn mentions puffinlark");
  const search = async (word: string, prompt: string) => {
    await browser.keyboard.press("Control+k");
    await browser.locator('input[placeholder="Search commands, projects, and threads..."]').fill(word);
    await screen.getByText(new RegExp(`${prompt}|No matching commands, projects, or threads\\.`)).first().waitFor();
    await screen.getByText("Searching messages…", {exact:true}).waitFor({state:"hidden"});
    await screen.getByText("Searching thread messages…", {exact:true}).waitFor({state:"hidden"});
  };
  await search("puffinlark", "You: fifth turn mentions puffinlark");
  await app.screenshot("before-rollback-search");
  await browser.keyboard.press("Escape");
  await screen.getByRole("button", "Edit from here").last().tap();
  await screen.getByRole("button", "Revert and keep changes").tap();
  await screen.getByRole("region", "Conversation", {exact:true}).getByText("fifth turn mentions puffinlark", {exact:true}).waitFor({state:"hidden"});
  await composer.filter({hasText: "fifth turn mentions puffinlark"}).waitFor();
  await composer.fill("");
  await search("puffinlark", "You: fifth turn mentions puffinlark");
  await app.screenshot("rollback-reopened-search");
  await expect.soft(screen.getByRole("option").filter({hasText: "fifth turn mentions puffinlark"})).toHaveCount(0);
  await browser.keyboard.press("Escape");
  await browser.reload();
  await screen.getByRole("button", "Submit message", {exact:true}).waitFor();
  await search("puffinlark", "You: fifth turn mentions puffinlark");
  await app.screenshot("rollback-reloaded-search");
  await expect.soft(screen.getByRole("option").filter({hasText: "fifth turn mentions puffinlark"})).toHaveCount(0);
  await browser.keyboard.press("Escape");
  await composer.fill("normal running turn");
  await composer.press("Enter");
  await stop.waitFor();
  await composer.fill("queued prompt mentions skuaharbor");
  await composer.press("Control+Enter");
  await screen.getByRole("button", "Remove queued message").tap();
  await screen.getByRole("button", "Remove queued message").waitFor({state:"hidden"});
  await stop.waitFor({state:"hidden"});
  await browser.reload();
  await screen.getByRole("button", "Submit message", {exact:true}).waitFor();
  await search("skuaharbor", "You: queued prompt mentions skuaharbor");
  await app.screenshot("cancelled-queue-reloaded-search");
  await expect.soft(screen.getByRole("option").filter({hasText: "queued prompt mentions skuaharbor"})).toHaveCount(0);
  await browser.keyboard.press("Escape");
  await search("heronfeather", "You: third turn mentions heronfeather");
  await expect.soft(screen.getByRole("option").filter({hasText: "third turn mentions heronfeather"})).toBeVisible();
  await app.screenshot("visible-prompt-retained");
  await browser.keyboard.press("Escape");
  await t3.open(stoppedThread);
  await screen.getByRole("button", "Multi turn", {exact:true}).tap();
  await browser.locator('input[placeholder="Search models..."]').fill("Showcase");
  await screen.getByRole("option").filter({hasText: "Showcase"}).tap();
  await composer.fill("stopped prompt mentions shearwaterkeep");
  await composer.press("Enter");
  await screen.getByText("The project has a single math module.", {exact:false}).waitFor();
  await stop.tap();
  await stop.waitFor({state:"hidden"});
  await screen.getByRole("button", "Resume thread", {exact:true}).waitFor();
  await app.screenshot("stopped-turn-timeline");
  await browser.reload();
  await screen.getByRole("button", "Resume thread", {exact:true}).waitFor();
  await search("shearwaterkeep", "You: stopped prompt mentions shearwaterkeep");
  await expect.soft(screen.getByRole("option").filter({hasText: "stopped prompt mentions shearwaterkeep"})).toBeVisible();
  await app.screenshot("stopped-prompt-retained");
  await browser.keyboard.press("Escape");
  await search("single math module", "The project has a single math module");
  await expect.soft(screen.getByRole("option").filter({hasText: "Stopped search demo"})).toBeVisible();
  await app.screenshot("stopped-assistant-retained");

});
