import { expect } from "e2e";
import { spawn, execFileSync } from "node:child_process";
import { mkdir, readFile, writeFile } from "node:fs/promises";
import { createWriteStream, watch } from "node:fs";
import { createServer } from "node:net";
import { APP_DIR, T3_HOME } from "../e2e.config.ts";
import { test, WEB } from "./t3.ts";

const port = () => new Promise<number>((resolve, reject) => {
  const server = createServer();
  server.on("error", reject);
  server.listen(0, "127.0.0.1", () => {
    const address = server.address();
    const value = typeof address === "object" && address ? address.port : 0;
    server.close(() => resolve(value));
  });
});

test("Ignored files beyond the first 200 can be found and copied", WEB, async ({ t3, app, screen, browser }) => {
  const files: Record<string, string> = {
    ".gitignore": "*.secret\n",
    ".git/config": '[core]\nrepositoryformatversion = 0\nbare = false\n[remote "origin"]\nurl = https://example.com/copy-picker-demo.git\nfetch = +refs/heads/*:refs/remotes/origin/*\n',
  };
  for (let n = 1; n <= 205; n++) {
    const folder = `folder-${String(n).padStart(3, "0")}`;
    files[`${folder}/anchor.txt`] = "Tracked anchor\n";
    files[`${folder}/local.secret`] = `Synthetic secret ${n}\n`;
  }
  const workspace = await t3.project("copy-picker-demo", files);
  const remote = `${workspace}-remote.git`;
  execFileSync("git", ["clone", "--bare", workspace, remote]);
  const secondHome = `${T3_HOME}/destination`;
  const destination = `${secondHome}/copy-picker-demo`;
  await t3.open();
  const origin = await browser.evaluate(() => location.origin);
  const secondPort = await port();
  await mkdir(`${secondHome}/userdata`, { recursive: true });
  await writeFile(`${secondHome}/userdata/settings.json`, await readFile(`${T3_HOME}/userdata/settings.json`));
  const logPath = `${secondHome}-server.log`;
  const second = spawn(process.execPath, ["scripts/dev-runner.ts", "dev:server", "--home-dir", secondHome, "--no-seed", "--port", String(secondPort), "--dev-url", origin], {
    cwd: APP_DIR,
    env: { ...process.env, PATH: `${T3_HOME}/bin:${process.env.PATH}`, T3CODE_DEV_ALLOWED_ORIGINS: origin, T3CODE_DEV_SEED: "0", GIT_CONFIG_COUNT: "1", GIT_CONFIG_KEY_0: `url.file://${remote}.insteadOf`, GIT_CONFIG_VALUE_0: "https://example.com/copy-picker-demo.git" },
    stdio: ["ignore", "pipe", "pipe"],
  });
  const logFile = createWriteStream(logPath);
  second.stdout.pipe(logFile, { end: false });
  second.stderr.pipe(logFile, { end: false });
  const secondExit = new Promise<void>((resolve) => second.once("exit", () => resolve()));
  let log = "";
  second.stdout.on("data", (data) => { log += data; });
  second.stderr.on("data", (data) => { log += data; });
  try {
    // Wait for the isolated destination stack, without recording any pairing credential.
    await new Promise<void>((resolve, reject) => {
      const deadline = setTimeout(() => { clearInterval(check); reject(new Error(log.slice(-4000))); }, 180000);
      second.once("exit", (code) => { clearInterval(check); clearTimeout(deadline); reject(new Error(`Destination exited ${code}: ${log.slice(-4000)}`)); });
      const check = setInterval(async () => {
        try {
          const response = await fetch(`http://127.0.0.1:${secondPort}/.well-known/t3/environment`);
          if (response.ok) { clearInterval(check); clearTimeout(deadline); resolve(); }
        } catch {}
      }, 500);
    });
    const startupUrl = /pairingUrl:\s*(\S+)/.exec(log)?.[1];
    if (!startupUrl) throw new Error("Destination emitted no pairing URL");
    const paired = new URL(startupUrl);
    const pairingUrl = `http://127.0.0.1:${secondPort}${paired.pathname}${paired.search}${paired.hash}`;
    await browser.evaluate(async (url: string) => {
      const { appAtomRegistry } = await import("/src/rpc/atomRegistry.ts");
      const { connectPairing } = await import("/src/connection/onboarding.ts");
      const result = await connectPairing.run(appAtomRegistry, { pairingUrl: url });
      if (result._tag === "Failure") throw new Error("Destination pairing failed");
    }, pairingUrl);
    // Hide only synthetic workspace paths in public evidence; leave the picker unchanged.
    await browser.evaluate(() => {
      const style = document.createElement("style");
      style.textContent = '[role="dialog"] .font-mono.text-muted-foreground.text-xs { visibility:hidden } [role="dialog"] input:not([aria-label="Search ignored files"]) { color:transparent }';
      document.head.append(style);
    });
    await screen.getByRole("heading", "What should we build", { exact: false }).getByRole("combobox").tap();
    await screen.getByText("copy-picker-demo", { exact: true }).tap();
    await screen.getByRole("combobox", "Run on").tap();
    await screen.getByText("Add to another machine", { exact: true }).tap();
    const dialog = screen.getByRole("dialog");
    await dialog.getByText("Copy ignored files", { exact: true }).waitFor();
    await dialog.getByText("folder-001/local.secret", { exact: true }).waitFor();
    await app.screenshot("initial-cutoff");
    const search = screen.getByRole("searchbox", "Search ignored files");
    const canSearch = await search.isVisible();
    if (canSearch) {
      await search.fill("folder-205");
      await screen.getByText("folder-205/local.secret", { exact: true }).waitFor();
    } else {
      await browser.evaluate(() => {
        const list = document.querySelector('[role="dialog"] .overflow-y-auto.rounded-md');
        if (list) list.scrollTop = list.scrollHeight;
      });
    }
    await app.screenshot("find-folder-205");
    await expect(screen.getByText("folder-205/local.secret", { exact: true })).toBeVisible();
    await screen.getByRole("checkbox", "folder-205/local.secret", { exact: false }).check();
    await search.fill("folder-204");
    await screen.getByRole("checkbox", "folder-204/local.secret", { exact: false }).check();
    await search.fill("");
    await screen.getByText("folder-001/local.secret", { exact: true }).waitFor();
    await app.screenshot("selections-retained");
    await expect(dialog.getByText("2 selected", { exact: false })).toBeVisible();
    await dialog.getByRole("textbox").fill(destination);
    const copied = new Promise<void>((resolve, reject) => {
      const watcher = watch(secondHome, { recursive: true }, async () => {
        try {
          await readFile(`${destination}/folder-205/local.secret`);
          await readFile(`${destination}/folder-204/local.secret`);
          watcher.close(); clearTimeout(deadline); resolve();
        } catch {}
      });
      const deadline = setTimeout(() => { watcher.close(); reject(new Error("Selected destination files were not copied")); }, 60000);
    });
    await dialog.getByRole("button", "Clone to Scenario").tap();
    await copied;
    await expect(await readFile(`${destination}/folder-205/local.secret`, "utf8")).toBe("Synthetic secret 205\n");
    await expect(await readFile(`${destination}/folder-204/local.secret`, "utf8")).toBe("Synthetic secret 204\n");
    const transcript = ["Destination after clone:", `folder-205/local.secret: ${(await readFile(`${destination}/folder-205/local.secret`, "utf8")).trim()}`, `folder-204/local.secret: ${(await readFile(`${destination}/folder-204/local.secret`, "utf8")).trim()}`, "Both selected files copied successfully."].join("\n");
    await writeFile(new URL("../.e2e/destination-transcript.txt", import.meta.url), transcript);
    console.log(transcript);
    await app.screenshot("clone-complete");
  } finally {
    second.kill("SIGTERM");
    await secondExit;
    logFile.end();
    await writeFile(logPath, log);
  }
});
