import { expect } from "e2e";
import { execFileSync } from "node:child_process";
import { writeFileSync } from "node:fs";
import { test, WEB } from "./t3.ts";

test("Pending diff metadata preserves added deleted and renamed status", WEB, async ({ t3, app, screen, browser }) => {
  const files: Record<string, string> = { "z-removed.ts": "export const removed = 1;\nexport const old = 2;\n" };
  for (let i=1;i<=30;i++) files[`a${String(i).padStart(2,"0")}.ts`] = `export const value = ${i};\n`;
  files["old-pure.ts"] = Array.from({length:20},(_,i)=>`export const pure${i} = ${i};`).join("\n")+"\n";
  files["old-changed.ts"] = Array.from({length:20},(_,i)=>`export const changed${i} = ${i};`).join("\n")+"\n";
  const project = await t3.project("Diff metadata proof", files);
  const thread = await t3.thread({project, title:"Review pending file statuses", messages:["Prepare review"]});
  const git = (...args: string[]) => execFileSync("git",args,{cwd:project});
  for(let i=1;i<=30;i++) writeFileSync(`${project}/a${String(i).padStart(2,"0")}.ts`,`export const value = ${i+100};\n`);
  writeFileSync(`${project}/y-untracked.ts`,"export const added = 1;\nexport const fresh = 2;\n");
  git("rm","z-removed.ts");
  git("mv","old-pure.ts","x-renamed-pure.ts");
  git("mv","old-changed.ts","w-renamed-changed.ts");
  writeFileSync(`${project}/w-renamed-changed.ts`,files["old-changed.ts"].replace("changed0 = 0","changed0 = 100"));
  git("add","w-renamed-changed.ts");
  await t3.open(thread);
  await screen.getByRole("button", /Changes.*Uncommitted/).tap();
  await screen.getByRole("button", "Maximize panel", {exact:true}).tap();
  await screen.getByRole("button", "Show file tree", {exact:true}).tap();
  await browser.locator('[data-item-path="y-untracked.ts"]').waitFor({state:"attached"});
  await browser.evaluate(async () => { await new Promise(resolve => setTimeout(resolve, 1200)); });
  await browser.evaluate(() => {
    function visit(root: Document | ShadowRoot) {
      for(const el of root.querySelectorAll("*")) {
        if(el.getAttribute("data-item-path") === "z-removed.ts" || el.getAttribute("aria-label") === "Expand z-removed.ts") el.scrollIntoView({block:"end"});
        if(el.shadowRoot) visit(el.shadowRoot);
      }
    } visit(document);
  });
  await browser.evaluate(async () => { await new Promise(resolve => setTimeout(resolve, 600)); });
  await app.screenshot("pending-file-metadata");
  const statuses = await browser.evaluate(() => {
    const all: Record<string,string|null> = {};
    function visit(root: Document | ShadowRoot) {
      for(const el of root.querySelectorAll("*")) {
        const path=el.getAttribute("data-item-path");
        if(path) all[path]=el.getAttribute("data-item-git-status");
        if(el.shadowRoot) visit(el.shadowRoot);
      }
    }
    visit(document); return all;
  });
  console.log("PENDING_STATUSES", JSON.stringify(statuses));
  for (const name of ["y-untracked.ts", "z-removed.ts", "x-renamed-pure.ts", "w-renamed-changed.ts"]) {
    await browser.locator(`[data-item-path="${name}"]`).tap();
    await browser.evaluate(async () => { await new Promise(resolve => setTimeout(resolve, 1500)); });
    await app.screenshot(`opened-${name.replace(".ts", "")}`);
  }
  await expect(statuses["y-untracked.ts"]).toEqual("added");
  await expect(statuses["z-removed.ts"]).toEqual("deleted");
  await expect(statuses["x-renamed-pure.ts"]).toEqual("renamed");
  await expect(statuses["w-renamed-changed.ts"]).toEqual("renamed");
});
