import { createServer } from "node:http";
import { chromium } from "playwright-core";
import { expect } from "e2e";
import { test, WEB } from "./t3.ts";

test("IME commit Enter preserves the edited browser URL until a second Enter", WEB, async ({ t3, app, screen, browser }) => {
  let visited = "/";
  const server = createServer((request, response) => {
    if (request.url !== "/favicon.ico") visited = request.url ?? "/";
    response.setHeader("Content-Type", "text/html");
    response.end(`<html><head><title>${request.url === "/" ? "HOME" : "PAGE ABC"}</title></head><body style="font:32px sans-serif;padding:40px"><h1>${request.url === "/" ? "HOME" : "PAGE ABC"}</h1><p>Address bar IME demonstration</p></body></html>`);
  });
  await new Promise<void>((resolve) => server.listen(18731, "127.0.0.1", resolve));
  const connection = await chromium.connectOverCDP("http://127.0.0.1:19222");
  try {
    const project = await t3.project("Browser IME demo");
    await t3.thread({ project, title: "Address bar demonstration", messages: ["Ready"] });
    await t3.open();
    await browser.locator("[data-thread-item]").first().tap();
    await browser.keyboard.press("Control+Shift+J");
    const address = screen.getByRole("textbox", "Search or enter URL");
    await address.fill("http://127.0.0.1:18731/");
    await address.press("Enter");
    const origin = new URL(await browser.url()).origin;
    const page = connection.contexts().flatMap(context => context.pages()).find(page => page.url().startsWith(origin));
    if (!page) throw new Error("Scenario page not found");
    await page.waitForFunction(() => document.querySelector('[data-preview-url-input]')?.getAttribute('value') === 'http://127.0.0.1:18731/');
    // Let the real browser's initial navigation finish before beginning the composition.
    await new Promise<void>((resolve) => { const check = () => visited === "/" ? resolve() : setTimeout(check, 50); check(); });
    await app.screenshot("initial-page");
    await address.tap();
    await browser.keyboard.press("End");
    const cdp = await page.context().newCDPSession(page);
    for (const text of ["p", "pa", "pageabc"]) {
      await cdp.send("Input.imeSetComposition", { text, selectionStart: text.length, selectionEnd: text.length });
    }
    await app.screenshot("composing-url");
    await cdp.send("Input.dispatchKeyEvent", { type: "keyDown", key: "Enter", code: "Enter", windowsVirtualKeyCode: 229, nativeVirtualKeyCode: 229, isComposing: true });
    await cdp.send("Input.insertText", { text: "pageabc" });
    await cdp.send("Input.dispatchKeyEvent", { type: "keyUp", key: "Enter", code: "Enter", windowsVirtualKeyCode: 13 });
    // Observe the settled result of the same IME interaction on both commits.
    await page.waitForTimeout(1800);
    await app.screenshot("after-ime-commit");
    await expect(address).toHaveValue("http://127.0.0.1:18731/pageabc");
    await expect(address).toBeFocused();
    expect(visited).toBe("/");
    await address.press("Enter");
    await expect.poll(() => visited).toBe("/pageabc");
    await page.waitForTimeout(1200);
    await app.screenshot("after-navigation-enter");
    await expect(address).toHaveValue("http://127.0.0.1:18731/pageabc");
  } finally {
    await connection.close();
    await new Promise<void>((resolve, reject) => server.close(error => error ? reject(error) : resolve()));
  }
});
