// OPE-27 — auto-compaction GUI: the Settings card's two overrides + summarizer-model
// pin POST through, and the "context compacted" divider renders inline mid-session
// (driven by the fixtures' scripted `compacted` event) without touching the transcript.
import { expect } from "@playwright/test";
import { test } from "./fixtures";

test("Settings: Context compaction card edits threshold, cap, and summarizer model", async ({
  page,
}) => {
  await page.goto("/");
  await page.getByTestId("account-row").click();
  await page.getByRole("button", { name: "Settings", exact: true }).click();
  await page.getByRole("button", { name: "Models", exact: true }).click();

  const card = page.getByTestId("compaction-card");
  await expect(card).toBeVisible();
  await expect(card.getByText("Context compaction")).toBeVisible();

  // Defaults render when the backend doesn't send the fields (older-backend robustness).
  await expect(card.getByTestId("compaction-threshold")).toHaveValue("80");
  await expect(card.getByTestId("compaction-cap")).toHaveValue("250000");
  await expect(card.getByTestId("compaction-model")).toHaveValue("");

  // Threshold edits POST as a fraction, clamped to 10–95%.
  const [req] = await Promise.all([
    page.waitForRequest(
      (r) => r.url().endsWith("/v1/settings/compaction") && r.method() === "POST",
    ),
    card.getByTestId("compaction-threshold").fill("70"),
  ]);
  expect(req.postDataJSON()).toEqual({ compaction_threshold_pct: 0.7 });

  const [req2] = await Promise.all([
    page.waitForRequest(
      (r) => r.url().endsWith("/v1/settings/compaction") && r.method() === "POST",
    ),
    card.getByTestId("compaction-cap").fill("100000"),
  ]);
  expect(req2.postDataJSON()).toEqual({ compaction_cap_tokens: 100000 });

  // Summarizer pin: the picker offers the session-default plus the configured models.
  const [req3] = await Promise.all([
    page.waitForRequest(
      (r) => r.url().endsWith("/v1/settings/compaction") && r.method() === "POST",
    ),
    card.getByTestId("compaction-model").selectOption("gpt-4o-mini"),
  ]);
  expect(req3.postDataJSON()).toEqual({ compaction_model: "gpt-4o-mini" });
});

test("the compacted divider renders mid-session and the transcript stays intact", async ({
  page,
}) => {
  await page.goto("/");
  await page.getByText("Draft the launch note").first().click();
  const box = page.getByPlaceholder(/Ask the coworker/);

  // An earlier exchange that must survive the compaction marker (transcript intact).
  await box.fill("remember the launch date");
  await box.press("Enter");
  await expect(page.getByText("Echo: remember the launch date").first()).toBeVisible({
    timeout: 10_000,
  });

  await box.fill("compact the context");
  await box.press("Enter");
  // The transient signal shows while the summarizer runs, then yields to the divider.
  await expect(page.getByText("Compacting context…").first()).toBeVisible({
    timeout: 10_000,
  });
  await expect(
    page.getByText("Context compacted — earlier turns were summarized").first(),
  ).toBeVisible({ timeout: 10_000 });
  await expect(page.getByText("Compacting context…")).toHaveCount(0);
  await expect(
    page.getByText("Still on it — continuing where I left off.").first(),
  ).toBeVisible();
  // Outbound-only: everything before the divider is still on screen.
  await expect(page.getByText("Echo: remember the launch date").first()).toBeVisible();
});
