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

test("First sends avoid forced docking commits on desktop", WEB, async ({ t3, app, screen, browser }) => {
  await browser.emulateMedia({ reducedMotion: "reduce", colorScheme: "dark" });
  await browser.addInitScript(() => {
    (Error as any).stackTraceLimit = 100;
    const w = window as any;
    // Redact synthetic workspace absolute paths printed by Replay's tool rows.
    document.addEventListener("DOMContentLoaded", () => new MutationObserver(() => {
      const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);
      while (walker.nextNode()) {
        const node = walker.currentNode;
        if (node.textContent?.includes("/home/")) node.parentElement?.style.setProperty("visibility", "hidden", "important");
      }
    }).observe(document.documentElement, {subtree:true, childList:true, characterData:true}));
    w.probe = { start: 0, events: [], samples: [], active: false, mobileSnapshots: [] };
    if (document.startViewTransition) {
      const start = document.startViewTransition.bind(document);
      document.startViewTransition = ((update: any) => start(async () => {
        await update();
        const overlay = document.querySelector('[data-chat-composer-overlay="true"]');
        const composer = document.querySelector('[data-chat-composer-stack="true"]');
        const rect = composer?.getBoundingClientRect();
        w.probe.mobileSnapshots.push({ committedDock: overlay?.classList.contains("bottom-0") ?? false, top: rect?.top ?? null, bottom: rect?.bottom ?? null, height: innerHeight });
      })) as any;
    }
    const record = (kind: string, stack = "") => {
      const p = w.probe;
      if (!p.active) return;
      p.events.push({ kind, ms: +(performance.now() - p.start).toFixed(1), docking: /runMobileComposerTransition/.test(stack), forced: /flushSync/.test(stack), stack });
    };
    w.__REACT_DEVTOOLS_GLOBAL_HOOK__ = {
      supportsFiber: true, renderers: new Map(),
      inject(renderer: unknown) { this.renderers.set(1, renderer); return 1; },
      onCommitFiberRoot() { record("React commit", new Error().stack ?? ""); },
      onCommitFiberUnmount() {}, checkDCE() {},
    };
    document.addEventListener("keydown", (e) => {
      if (e.key === "Enter" && !e.shiftKey) {
        w.probe.start = performance.now(); w.probe.events = []; w.probe.active = true;
      }
    }, true);
    const send = WebSocket.prototype.send;
    WebSocket.prototype.send = function(data) {
      if (typeof data === "string" && data.includes("orchestration.launchThread")) record("launchThread sent");
      return send.call(this, data);
    };
  });
  await t3.project("Composer demo");
  await t3.open();
  const results: any[] = [];
  for (let sample = 1; sample <= 8; sample++) {
    await screen.getByRole("button", "New thread in Composer demo").first().tap();
    await screen.getByRole("textbox").fill(`sample ${sample}`);
    if (sample === 1) await app.screenshot("centered-draft");
    await screen.getByRole("textbox").press("Enter");
    const result = await browser.evaluate(async () => {
      await new Promise(resolve => setTimeout(resolve, 2500));
      const p = (window as any).probe;
      p.active = false;
      const launch = p.events.find((e: any) => e.kind === "launchThread sent");
      const forced = p.events.filter((e: any) => e.kind === "React commit" && e.docking && e.forced && (!launch || e.ms < launch.ms));
      return { launchMs: launch?.ms ?? null, forced: forced.length, commits: p.events.filter((e: any) => e.kind === "React commit").slice(0, 6).map((e: any) => ({ms:e.ms, docking:e.docking, forced:e.forced})), stack: (forced[0] ?? p.events.find((e: any) => e.kind === "React commit"))?.stack?.split("\n").map((s: string) => s.replace(/https?:\/\/[^ )]+/g, "[source]")).join("\n") ?? "" };
    });
    results.push(result);
    await browser.evaluate(({results, sample}) => {
      let panel = document.getElementById("first-send-evidence");
      if (!panel) { panel = document.createElement("aside"); panel.id = "first-send-evidence"; document.body.append(panel); }
      panel.style.cssText = "position:fixed;right:20px;top:75px;z-index:2147483647;width:620px;padding:20px;background:#101827;color:#e5edf9;border:2px solid #7891b9;border-radius:12px;font:15px/1.5 monospace;pointer-events:none;box-shadow:0 8px 40px #0009";
      panel.textContent = "";
      const title = document.createElement("h2"); title.textContent = "First-send runtime probe · desktop 1280×800"; title.style.cssText="font:bold 17px sans-serif;margin:0 0 12px"; panel.append(title);
      const detail = document.createElement("div"); detail.textContent = "Reduced motion · Replay showcase · 2.5 s per sample"; panel.append(detail);
      const pre = document.createElement("pre"); pre.style.cssText="white-space:pre-wrap;font:inherit";
      pre.textContent = "Sample   Forced docking commits   Launch sent (ms)\n" + results.map((r: any, i: number) => `${String(i+1).padEnd(9)}${String(r.forced).padEnd(25)}${r.launchMs ?? "NOT OBSERVED"}`).join("\n"); panel.append(pre);
      const last = results[results.length-1]; const events = document.createElement("div");
      events.textContent = `Sample ${sample} first commits: ` + last.commits.map((e: any) => `${e.ms}ms${e.docking && e.forced ? " [forced docking]" : ""}`).join(" → "); panel.append(events);
      if (last.stack) { const stack = document.createElement("pre"); stack.style.cssText="font:11px/1.5 monospace;white-space:pre-wrap"; stack.textContent=last.stack.split("\n").filter((s: string) => /flushSync|runMobileComposerTransition|onSendWithRouting|useComposerSend/.test(s)).slice(0,7).join("\n"); panel.append(stack); }
    }, { results, sample });
    await app.screenshot(`sample-${sample}-runtime`);
  }
  await screen.getByRole("button", "New thread in Composer demo").first().tap();
  await browser.evaluate(async () => {
    document.getElementById("first-send-evidence")?.remove();
    const settings = await import("/src/hooks/useSettings.ts");
    await settings.updateClientSettings({ panelAnimationDurationMs: 200 });
  });
  await browser.setViewport({width:390, height:844});
  await browser.emulateMedia({reducedMotion:"no-preference"});
  await screen.getByRole("textbox").fill("mobile snapshot sample");
  await app.screenshot("mobile-centered-draft");
  await screen.getByRole("textbox").press("Enter");
  const mobile = await browser.evaluate(async () => {
    await new Promise(resolve => setTimeout(resolve,2500));
    const p=(window as any).probe;
    p.active=false;
    const snapshots=p.mobileSnapshots;
    const panel=document.createElement("aside");
    panel.style.cssText="position:fixed;top:80px;left:10px;right:10px;z-index:2147483647;padding:16px;background:#101827;color:#e5edf9;border:2px solid #7891b9;border-radius:12px;font:14px/1.6 monospace;pointer-events:none";
    panel.textContent="Mobile 390×844 · motion 200ms\nNative view-transition update snapshot:\n" + JSON.stringify(snapshots,null,2);
    panel.style.whiteSpace="pre-wrap";
    document.body.append(panel);
    return snapshots;
  });
  await app.screenshot("mobile-committed-snapshot");
  console.log("MOBILE_SNAPSHOT " + JSON.stringify(mobile));
  console.log("FIRST_SEND_RESULTS " + JSON.stringify(results));
  expect(mobile.some((s: any) => s.committedDock)).toBe(true);
  expect(results.every(r => r.launchMs !== null && r.forced === 0)).toBe(true);
});
