/**
 * Sidebar session paging: each group displays at most SIDEBAR_PAGE_SIZE (20) rows and the
 * store fetches per Agent with limit+1 pages — 21 seeded sessions must load as one page of
 * 20 plus a "更多" row; clicking it reveals the loaded rows AND fetches the next server
 * page, after which all 21 rows are visible and the "更多" row disappears (no more hidden
 * rows, no more server pages).
 *
 * A list taller than the viewport must scroll INSIDE the sidebar: the document itself
 * stays unscrollable before and after "更多". Each row's sr-only Agent name is
 * position:absolute, and without a positioned scroller those boxes anchored to the
 * initial containing block, stretched the document, and let the whole page scroll (the
 * composer could be pushed up, leaving blank space below).
 *
 * Standalone spec: shares one server with the other specs, so it registers its own user
 * (auto-provisions a default Project) and seeds sessions via the API.
 */
import { test, expect } from "@playwright/test";
import { provisionAndLogin } from "./auth.mjs";

const BASE = process.env.BASE_URL;
const MOCK = process.env.MOCK_URL;
const U = "pageuser";
const P = "password123";
const TOTAL = 21; // one past the 20-row page

test("sidebar shows 20 sessions plus a More row; More loads the 21st and then disappears", async ({
  page,
}) => {
  await provisionAndLogin(page.request, U, P);
  const projects = await (await page.request.get(`${BASE}/api/projects`)).json();
  const projectId = projects.projects[0].projectId;

  const put = await page.request.put(`${BASE}/api/projects/${projectId}/models`, {
    data: {
      defaultModel: { provider: "custom", modelId: "claude-4-8" },
      models: [
        {
          provider: "custom",
          modelId: "claude-4-8",
          apiKey: "sk-mock",
          baseUrl: MOCK,
          contextWindow: 200000,
        },
      ],
    },
  });
  expect(put.ok(), "put models").toBeTruthy();

  // Seed 21 sessions (each gets its own temporary Workspace; the sidebar merges them into
  // the single temporary-workspace group, so the display cap applies to one group).
  for (let i = 0; i < TOTAL; i++) {
    const res = await page.request.post(
      `${BASE}/api/projects/${projectId}/agents/default_agent/sessions`,
      { data: {} },
    );
    expect(res.ok(), `create session ${i}: ${await res.text()}`).toBeTruthy();
  }

  await page.goto(`${BASE}/chat`);
  const sidebar = page.getByRole("complementary");
  // Untitled rows all read "新对话" (distinct from the nav's "新建对话", which is not matched
  // by substring). One page: exactly 20 rows.
  const rows = sidebar.getByText("新对话");
  await expect(rows).toHaveCount(20);
  const more = sidebar.getByRole("button", { name: "更多" });
  await expect(more).toBeVisible();

  // The 20-row list already exceeds the 720px viewport: it must scroll inside the
  // sidebar, never stretch the document (the sr-only regression described up top).
  const docScrollable = () =>
    page.evaluate(
      () => document.documentElement.scrollHeight > document.documentElement.clientHeight + 1,
    );
  expect(await docScrollable(), "document scrollable before 更多").toBe(false);

  // More: raises the display cap and fetches the next server page → all 21 rows, no More left.
  await more.click();
  await expect(rows).toHaveCount(TOTAL);
  await expect(more).toHaveCount(0);

  // Still only the sidebar scrolls after the list grew past one page.
  expect(await docScrollable(), "document scrollable after 更多").toBe(false);
});
