import { expect } from "e2e";
import { readdir, readFile, writeFile } from "node:fs/promises";
import { join } from "node:path";
import { test, WEB, makeState, runPromise } from "./t3.ts";
import { T3_HOME } from "../e2e.config.ts";

test("Editing a queued message cleans only its removed attachment", WEB, async ({ t3, app, screen, browser }) => {
  const settingsPath = join(T3_HOME, "userdata/settings.json");
  const settings = JSON.parse(await readFile(settingsPath, "utf8"));
  await writeFile(settingsPath, JSON.stringify({ ...settings, defaultRuntimeMode: "approval-required" }));
  const project = await t3.project("attachment-demo");
  const thread = await t3.thread({ project, title: "Queued attachment cleanup", model: "approval", messages: ["Start"] });
  await t3.open(thread);
  const { cli } = makeState(T3_HOME);
  await runPromise(cli(["thread", "send", thread.threadId, "queued message with attachments", "--json"]));
  await screen.getByRole("button", "Edit queued message").tap();
  const keep = join(T3_HOME, "keep-me.txt");
  const drop = join(T3_HOME, "drop-me.txt");
  await writeFile(keep, "KEEP ME - retained attachment\n");
  await writeFile(drop, "DROP ME - removed attachment\n");
  await browser.locator('input[type="file"]').setInputFiles([keep, drop]);
  await screen.getByRole("button", "Update queued message").tap();
  await screen.getByRole("button", "Edit queued message").tap();
  await app.screenshot("both-attached");
  await screen.getByRole("button", "Remove drop-me.txt").tap();
  await screen.getByRole("button", "Update queued message").tap();
  await screen.getByRole("button", "Edit queued message").tap();
  const storage = async () => {
    const files = await readdir(join(T3_HOME, "userdata/attachments"), { recursive: true });
    const contents = await Promise.all(files.map(async file => { try { return await readFile(join(T3_HOME, "userdata/attachments", file), "utf8"); } catch { return ""; } }));
    return { retained: contents.some(s => s.includes("KEEP ME - retained attachment")), removed: contents.some(s => s.includes("DROP ME - removed attachment")) };
  };
  // The backend effect is asynchronous. Display observed disk contents beside the real editor.
  try { await expect.poll(async () => (await storage()).removed, { timeout: 10000 }).toBe(false); }
  finally {
    const observed = await storage();
    await browser.evaluate((value) => {
      const panel = document.createElement("div");
      panel.style.cssText = "position:fixed;top:80px;right:24px;z-index:99999;background:#101827;color:white;border:2px solid #64748b;padding:20px;font:16px monospace;white-space:pre;";
      panel.textContent = "REAL SERVER STORAGE CHECK\n\nkeep-me.txt: " + (value.retained ? "PRESENT" : "MISSING") + "\ndrop-me.txt: " + (value.removed ? "PRESENT (orphan)" : "DELETED") + "\n\nQueued editor below retains keep-me.txt";
      document.body.append(panel);
    }, observed);
    await app.screenshot("after-removing-attachment");
  }
  expect((await storage()).retained).toBe(true);
});
