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

test("new optimistic session first turn does not submit local thr_* as upstream thread", async ({ page }) => {
  await gotoWorkbench(page);
  await page.locator(selectors.sessionCreate).click();
  const activeTab = page.locator('.session-tab[data-active="true"]');
  await expect(activeTab).toHaveAttribute("data-session-id", /^ses_/u);
  const sessionId = await activeTab.getAttribute("data-session-id");
  expect(sessionId).toBeTruthy();

  await page.locator(selectors.commandInput).fill("web-probe D601 v0.3 smoke: reply with exactly OK.");
  await expect(page.locator(selectors.commandSend)).toBeEnabled();
  await page.locator(selectors.commandSend).click();

  await expect.poll(async () => ((await fakeServerState(page)).chatRequests as unknown[]).length).toBe(1);
  const state = await fakeServerState(page);
  const request = (state.chatRequests as Record<string, unknown>[])[0];
  if (!request) throw new Error("expected one chat request");
  expect(request.conversationId).toBeUndefined();
  expect(request.projectId).toBeUndefined();
  expect(request.workspaceId).toBeUndefined();
  expect(request.sessionId).toBe(sessionId);
  expect(request.threadId ?? null).toBeNull();
  expect((state.legacyRequestLedger as unknown[]).length).toBe(0);
});

test.describe("server authoritative session create", () => {
  test.use({ scenarioId: "server-authoritative-create" });

  test("new session adopts backend selected conversation before submit", async ({ page }) => {
    await gotoWorkbench(page);
    await page.locator(selectors.sessionCreate).click();

    await expect(page).toHaveURL(/\/workbench\/sessions\/ses_server_created/u);
    await expect(page.locator('.session-tab[data-session-id="ses_server_created"]')).toHaveAttribute("data-active", "true");
    await expect(page.locator('.session-tab[data-session-id="ses_server_created"]')).toHaveAttribute("data-running", "false");

    await page.locator(selectors.commandInput).fill("server authoritative create smoke");
    await expect(page.locator(selectors.commandSend)).toBeEnabled();
    await page.locator(selectors.commandSend).click();

    await expect.poll(async () => ((await fakeServerState(page)).chatRequests as unknown[]).length).toBe(1);
    const state = await fakeServerState(page);
    const request = (state.chatRequests as Record<string, unknown>[])[0];
    expect(request?.conversationId).toBeUndefined();
    expect(request?.projectId).toBeUndefined();
    expect(request?.workspaceId).toBeUndefined();
    expect(request?.sessionId).toBe("ses_server_created");
    expect((state.legacyRequestLedger as unknown[]).length).toBe(0);
  });
});

test.describe("session create while old route is still loading", () => {
  test.use({ scenarioId: "create-while-route-loading" });

  test("created session owns URL, active tab, and composer while old running session refreshes", async ({ page }) => {
    await gotoWorkbench(page, "/workbench/sessions/ses_running");

    const created = page.waitForResponse((response) => response.request().method() === "POST" && new URL(response.url()).pathname === "/v1/agent/sessions");
    await page.locator(selectors.sessionCreate).click();
    expect((await created).status()).toBe(201);

    await expect(page).toHaveURL(/\/workbench\/sessions\/ses_created_while_running/u, { timeout: 500 });
    await expect(page.locator(sessionTab("ses_created_while_running"))).toHaveAttribute("data-active", "true");
    await expect(page.locator(sessionTab("ses_running"))).toHaveAttribute("data-active", "false");
    await expect(page.locator(sessionTab("ses_running"))).toHaveAttribute("data-running", "true");
    await expect(page.locator(selectors.commandSend)).toHaveAttribute("data-action", "turn");

    const state = await fakeServerState(page);
    expect((state.legacyRequestLedger as unknown[]).length).toBe(0);
  });
});

test.describe("session create read-side failure authority", () => {
  test.use({ scenarioId: "created-session-read-failure" });

  test("created session keeps active projection when detail/messages read fails", async ({ page }) => {
    await gotoWorkbench(page, "/workbench/sessions/ses_running");

    const created = page.waitForResponse((response) => response.request().method() === "POST" && new URL(response.url()).pathname === "/v1/agent/sessions");
    await page.locator(selectors.sessionCreate).click();
    expect((await created).status()).toBe(200);

    const createdTab = page.locator(sessionTab("ses_created_read_failure"));
    await expect(page).toHaveURL(/\/workbench\/sessions\/ses_created_read_failure/u);
    await expect(createdTab).toHaveAttribute("data-active", "true");
    await expect(page.locator(sessionTab("ses_running"))).toHaveAttribute("data-active", "false");
    await expect(page.locator(sessionTab("ses_running"))).toHaveAttribute("data-running", "true");
    await expect(page.locator(".conversation-error-hint")).toContainText(/unavailable/u);
    await expect(page.locator(".composer-mode")).toContainText("turn / 新请求");
    await expect(page.locator(".composer-warning")).toHaveCount(0);

    await page.locator(selectors.commandInput).fill("created session projection must survive read failure");
    await expect(page.locator(selectors.commandSend)).toBeEnabled();
    await page.waitForTimeout(800);
    await expect(createdTab).toHaveAttribute("data-active", "true");
    await expect(page.locator(".composer-mode")).toContainText("turn / 新请求");

    const state = await fakeServerState(page);
    expect((state.legacyRequestLedger as unknown[]).length).toBe(0);
  });
});

test.describe("session create and delete authority", () => {
  test.use({ scenarioId: "server-authoritative-create" });

  test("created session becomes active and deleted session stays archived after reload", async ({ page }) => {
    await gotoWorkbench(page);
    await page.locator(selectors.sessionCreate).click();
    await expect(page).toHaveURL(/\/workbench\/sessions\/ses_server_created/u);
    await expect(page.locator('.session-tab[data-session-id="ses_server_created"]')).toHaveAttribute("data-active", "true");
    await expect(page.locator(selectors.commandSend)).toBeDisabled();

    await page.locator(selectors.sessionDelete).click();
    await expect(page.locator('.session-tab[data-session-id="ses_server_created"]')).toHaveCount(0);
    await page.reload();
    await expect(page.locator('.session-tab[data-session-id="ses_server_created"]')).toHaveCount(0);
    const state = await fakeServerState(page);
    const deleted = (state.sessions as Array<{ sessionId?: string; status?: string }>).find((item) => item.sessionId === "ses_server_created");
    expect(deleted?.status).toBe("archived");
  });
});
