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

test("Held dictation ends when activation modifiers are released without D keyup", WEB, async ({ t3, app, screen, browser }) => {
  await browser.addInitScript(() => {
    Object.defineProperty(navigator, "platform", { get: () => "MacIntel" });
    // Synthetic microphone input only; MediaRecorder and the speech pipeline stay real.
    navigator.mediaDevices.getUserMedia = async () => {
      const context = new AudioContext();
      await context.resume();
      const tone = context.createOscillator();
      const gain = context.createGain();
      gain.gain.value = 0.02;
      const destination = context.createMediaStreamDestination();
      tone.connect(gain).connect(destination);
      tone.start();
      return destination.stream;
    };
  });
  const project = await t3.project("Dictation proof");
  const thread = await t3.thread({ project, title: "Modifier release", messages: ["Ready for dictation"] });
  await t3.open("/settings/voice");
  await screen.getByRole("combobox", "Transcribe with").tap();
  await screen.getByRole("option", "Scenario", { exact: true }).tap();
  await screen.getByRole("combobox", "Dictation shortcut mode").tap();
  await screen.getByRole("option", /Hold/).tap();
  const model = browser.locator('div[class~="@container/model"]').filter({ hasText: "Parakeet Unified English 0.6B" });
  await model.getByRole("button", "Download", { exact: true }).tap();
  await model.getByRole("button", "Selected", { exact: true }).waitFor({ timeout: 180_000 });
  await app.screenshot("voice-setup");
  await t3.open(thread);
  await screen.getByRole("button", "New thread in Dictation proof", { exact: true }).tap();
  const draftPath = new URL(await browser.url()).pathname;
  const composer = browser.locator('[contenteditable="true"]').first();
  await composer.tap();
  await browser.keyboard.type("draft before dictation");
  const pause = (ms: number) => browser.evaluate((ms) => new Promise<null>(resolve => setTimeout(() => resolve(null), ms)), ms);
  const start = async () => {
    await composer.tap();
    await browser.keyboard.down("Meta");
    await browser.keyboard.down("Shift");
    await browser.keyboard.down("d");
    await screen.getByRole("button", "Finish voice input", { exact: true }).waitFor();
  };
  const release = async (letter: boolean) => {
    if (letter) await browser.keyboard.up("d");
    await browser.keyboard.up("Shift");
    await browser.keyboard.up("Meta");
  };
  const recording = () => browser.evaluate(() => !!document.querySelector('button[aria-label="Finish voice input"]'));
  const mode = async (name: string) => {
    await t3.open("/settings/voice");
    await screen.getByRole("combobox", "Dictation shortcut mode").tap();
    await screen.getByRole("option", new RegExp("^" + name)).tap();
    await t3.open(draftPath);
  };
  // Control: the ordinary initiating-letter keyup stops Hold.
  await start();
  await pause(2500);
  await release(true);
  await screen.getByRole("button", "Finish voice input", { exact: true }).waitFor({ state: "hidden" });
  await pause(3000);
  await browser.keyboard.press("Escape");
  const results: boolean[] = [];
  for (const name of ["Hold", "Auto"]) {
    if (name === "Auto") await mode(name);
    await start();
    await pause(2500);
    await app.screenshot(name.toLowerCase() + "-held");
    // Emulate the reported macOS stream: no initiating-letter keyup.
    await release(false);
    await pause(6000);
    await app.screenshot(name.toLowerCase() + "-six-seconds-after-modifier-release");
    results.push(await recording());
    await browser.keyboard.up("d");
    await browser.keyboard.press("Escape");
    await pause(1000);
  }
  // Auto tap remains recording after release.
  await composer.tap();
  await browser.keyboard.down("Meta");
  await browser.keyboard.down("Shift");
  await browser.keyboard.down("d");
  await release(false);
  await screen.getByRole("button", "Finish voice input", { exact: true }).waitFor();
  await pause(6000);
  await app.screenshot("auto-tap-keeps-recording");
  const autoTap = await recording();
  await browser.keyboard.up("d");
  await browser.keyboard.press("Escape");
  await pause(1000);
  await mode("Toggle");
  await start();
  await pause(2500);
  await release(false);
  await pause(6000);
  await app.screenshot("toggle-keeps-recording");
  const toggle = await recording();
  await browser.keyboard.up("d");
  await browser.keyboard.press("Escape");
  await expect({ heldRecordingAfterRelease: results, autoTap, toggle }).toEqual({ heldRecordingAfterRelease: [false, false], autoTap: true, toggle: true });
});
