import { expect, fakeServerState, gotoWorkbench, saveScreenshot, test } from "../fixtures/test";
import { selectors, sessionTab } from "../fixtures/selectors";

test.use({ scenarioId: "session-rail-many" });

test("session rail does not issue per-tab status requests", async ({ page }) => {
  await gotoWorkbench(page);
  await expect(page.locator(".session-tab")).toHaveCount(20);
  await page.waitForTimeout(1200);
  const state = await fakeServerState(page);
  const requests = state.requestLedger as Array<{ method?: string; path?: string }>;
  const sessionStatusRequests = requests.filter((request) => /^\/v1\/agent\/sessions\/ses_/u.test(String(request.path ?? "")));
  const uniquePaths = new Set(sessionStatusRequests.map((request) => request.path));
  expect(sessionStatusRequests.length).toBeLessThanOrEqual(3);
  expect(uniquePaths.size).toBeLessThanOrEqual(1);
  expect((state.legacyRequestLedger as unknown[]).length).toBe(0);
  await expect(page.locator(selectors.commandInput)).toBeVisible();
});

test("session rail loads historical pages and keeps deep-linked old sessions visible", async ({ page }, testInfo) => {
  const firstPage = await page.request.get("/v1/workbench/sessions?limit=20");
  expect(firstPage.ok()).toBeTruthy();
  const firstBody = await firstPage.json() as { count?: number; hasMore?: boolean; nextCursor?: string | null; sessions?: Array<{ sessionId?: string }> };
  expect(firstBody.count).toBe(20);
  expect(firstBody.hasMore).toBe(true);
  expect(firstBody.nextCursor).toBe("idx:20");

  await gotoWorkbench(page, "/workbench/sessions/ses_completed");
  await expect(page.locator(".session-tab")).toHaveCount(20);
  await expect(page.locator("#session-load-more")).toBeVisible();
  const page1Ids = await visibleSessionIds(page);
  expect(new Set(page1Ids).size).toBe(20);
  const messageCountBefore = await page.locator(selectors.messageCard).count();
  expect(messageCountBefore).toBeGreaterThan(0);
  await saveScreenshot(page, testInfo, "session-pagination-first-page");

  await page.locator("#session-load-more").click();
  await expect(page.locator(".session-tab")).toHaveCount(40);
  await expect(page.locator(selectors.messageCard)).toHaveCount(messageCountBefore);
  const page2Ids = await visibleSessionIds(page);
  expect(new Set(page2Ids).size).toBe(40);
  for (const sessionId of page1Ids) expect(page2Ids).toContain(sessionId);
  await saveScreenshot(page, testInfo, "session-pagination-second-page");

  await page.locator("#session-load-more").click();
  await expect(page.locator(".session-tab")).toHaveCount(55);
  await expect(page.locator("#session-list-complete")).toBeVisible();
  await expect(page.locator("#session-load-more")).toHaveCount(0);
  const allIds = await visibleSessionIds(page);
  expect(new Set(allIds).size).toBe(55);
  expect(allIds).toContain("ses_many_42");
  await saveScreenshot(page, testInfo, "session-pagination-no-more");

  await gotoWorkbench(page, "/workbench/sessions/ses_many_42");
  const oldTab = page.locator(sessionTab("ses_many_42"));
  await expect(oldTab).toBeVisible();
  await expect(oldTab).toHaveAttribute("data-active", "true");
  await saveScreenshot(page, testInfo, "session-pagination-deep-link");
});

async function visibleSessionIds(page: { locator: (selector: string) => { evaluateAll: <T>(callback: (nodes: Element[]) => T) => Promise<T> } }): Promise<string[]> {
  return await page.locator(".session-tab").evaluateAll((nodes) => nodes.map((node) => node.getAttribute("data-session-id") || ""));
}
