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

test.use({ scenarioId: "event-replay" });

test("SSE terminal event and REST gap fill replay to the same terminal UI", async ({ page }, testInfo) => {
  await gotoWorkbench(page);
  await expect(page.locator(`${selectors.messageCard}[data-role="agent"][data-status="running"]`)).toBeVisible();
  await expect(page.locator(`${selectors.traceTimeline}[data-status="running"]`)).toBeVisible();

  await expect(page.locator(`${selectors.messageCard}[data-role="agent"][data-status="completed"]`)).toContainText("事件重放后完成");
  await expect(page.locator(`${selectors.traceTimeline}[data-status="completed"]`)).toBeVisible();
  await expect(page.locator(selectors.commandSend)).toHaveAttribute("data-action", "turn");
  await saveScreenshot(page, testInfo, "event-replay-terminal");

  await page.reload();
  await expect(page.locator(`${selectors.messageCard}[data-role="agent"][data-status="completed"]`)).toContainText("事件重放后完成");
  await expect(page.locator(`${selectors.traceTimeline}[data-status="completed"]`)).toBeVisible();
});

test.describe("terminal completed without final response", () => {
  test.use({ scenarioId: "terminal-completed-no-final-response" });

  test("keeps the assistant final response area empty", async ({ page }, testInfo) => {
    await gotoWorkbench(page);
    const agentCard = page.locator(`${selectors.messageCard}[data-role="agent"]`).last();
    await expect(agentCard).toHaveAttribute("data-status", "running");
    await expect(agentCard).toHaveAttribute("data-status", "completed");
    await expect(page.locator(`${selectors.traceTimeline}[data-status="completed"]`)).toBeVisible();

    const snapshot = await agentCard.evaluate((element) => {
      const placeholder = "Code Agent 已完成，但没有返回可展示的 final response。";
      return {
        status: element.getAttribute("data-status"),
        messageTexts: Array.from(element.querySelectorAll(".message-markdown.message-text")).map((item) => (item.textContent ?? "").trim()),
        bodyHasPlaceholder: document.body.textContent?.includes(placeholder) === true
      };
    });
    expect(snapshot.status).toBe("completed");
    expect(snapshot.messageTexts.filter(Boolean)).toEqual([]);
    expect(snapshot.bodyHasPlaceholder).toBe(false);
    await saveScreenshot(page, testInfo, "terminal-completed-no-final-response");
  });
});

test.describe("terminal assistant event final response", () => {
  test.use({ scenarioId: "terminal-assistant-event-final-response" });

  test("renders the sealed Workbench final response from the authoritative terminal assistant event", async ({ page }, testInfo) => {
    const sessionId = "ses_terminal_assistant_final";
    const traceId = "trc_terminal_assistant_final";
    const messagesResponse = await page.request.get(`/v1/workbench/sessions/${sessionId}/messages?limit=100`);
    expect(messagesResponse.status()).toBe(200);
    const messagesPayload = await messagesResponse.json();
    const agentMessage = messagesPayload.messages.find((message: { role?: string }) => message.role === "agent");
    expect(agentMessage?.text).toContain("全部六份数据到手");
    expect(agentMessage?.finalResponse?.text).toBe(agentMessage?.text);

    const turnResponse = await page.request.get(`/v1/workbench/turns/${traceId}`);
    expect(turnResponse.status()).toBe(200);
    const turnPayload = await turnResponse.json();
    expect(turnPayload.turn.finalResponse.text).toBe(agentMessage?.text);

    const traceResponse = await page.request.get(`/v1/workbench/traces/${traceId}/events?limit=20`);
    expect(traceResponse.status()).toBe(200);
    const tracePayload = await traceResponse.json();
    const finalEvent = tracePayload.events.find((event: { label?: string; final?: boolean }) => event.label === "agentrun:assistant:message" && event.final === true);
    expect(finalEvent?.replyAuthority).toBe(true);
    expect(finalEvent?.message).toBe(agentMessage?.text);

    await gotoWorkbench(page, `/workbench/sessions/${sessionId}`);
    const card = page.locator(`${selectors.messageCard}[data-role="agent"][data-status="completed"]`).last();
    await expect(card.locator(".message-markdown.message-text")).toContainText("全部六份数据到手");
    await expect(card.locator(".message-markdown.message-text table")).toHaveCount(1);
    await card.locator("summary.trace-disclosure-summary").click();
    await expect(card.locator(".trace-row-markdown table")).toHaveCount(1);
    await saveScreenshot(page, testInfo, "terminal-assistant-event-final-response");
  });
});

test.describe("non-terminal tool completed event", () => {
  test.use({ scenarioId: "tool-completed-projection-running" });

  test("keeps turn, session card, and trace header running", async ({ page }, testInfo) => {
    await gotoWorkbench(page, "/workbench/sessions/ses_running");

    const turn = await page.request.get("/v1/workbench/turns/trc_running");
    expect(turn.status()).toBe(200);
    const turnBody = await turn.json();
    expect(turnBody.turn.status).toBe("running");
    expect(turnBody.turn.trace.status).toBe("completed");

    const trace = await page.request.get("/v1/workbench/traces/trc_running/events");
    expect(trace.status()).toBe(200);
    const traceBody = await trace.json();
    expect(traceBody.traceStatus).toBe("completed");
    expect(traceBody.events.at(-1).status).toBe("completed");
    expect(traceBody.events.at(-1).terminal).toBe(false);

    const tab = page.locator(sessionTab("ses_running"));
    await expect(tab).toHaveAttribute("data-running", "true");
    await expect(tab).toHaveAttribute("data-status", "running");

    const agentCard = page.locator(`${selectors.messageCard}[data-role="agent"]`).last();
    await expect(agentCard).toHaveAttribute("data-status", "running");
    const timeline = agentCard.locator(`${selectors.traceTimeline}[data-status="running"]`);
    await expect(timeline).toBeVisible();
    await timeline.locator("summary.trace-disclosure-summary").click();
    const toolRow = timeline.locator(`${selectors.traceRow}[data-row-kind="tool"]`).filter({ hasText: "commandExecution" });
    await expect(toolRow).toHaveAttribute("data-terminal", "false");
    await expect(toolRow).toContainText("ls -ld .");

    const snapshot = await agentCard.evaluate((element) => ({
      status: element.getAttribute("data-status"),
      messageTexts: Array.from(element.querySelectorAll(".message-markdown.message-text")).map((item) => (item.textContent ?? "").trim()).filter(Boolean),
      bodyText: document.body.textContent ?? ""
    }));
    expect(snapshot.status).toBe("running");
    expect(snapshot.messageTexts).toEqual([]);
    expect(snapshot.bodyText).not.toContain("Code Agent 已完成，但没有返回可展示的 final response。");
    await saveScreenshot(page, testInfo, "tool-completed-projection-running");
  });
});

test("fresh deep link replays completed turn from the session authority", async ({ page }, testInfo) => {
  const detail = await page.request.get("/v1/workbench/sessions/ses_completed");
  expect(detail.status()).toBe(200);
  const detailBody = await detail.json();
  expect(detailBody.session.sessionId).toBe("ses_completed");

  const turn = await page.request.get("/v1/workbench/turns/trc_completed");
  expect(turn.status()).toBe(200);
  expect((await turn.json()).turn.status).toBe("completed");

  const trace = await page.request.get("/v1/workbench/traces/trc_completed/events");
  expect(trace.status()).toBe(200);
  expect((await trace.json()).traceStatus).toBe("completed");

  await gotoWorkbench(page, "/workbench/sessions/ses_completed");
  await expect(page.locator(sessionTab("ses_completed"))).toHaveAttribute("data-active", "true");
  await expect(page.locator(`${selectors.messageCard}[data-role="agent"][data-status="completed"]`)).toContainText("构建和 Trace 渲染检查完成");
  await expect(page.locator(`${selectors.traceTimeline}[data-status="completed"]`)).toBeVisible();
  await expect.poll(async () => await page.locator(selectors.traceRow).count()).toBeGreaterThan(0);
  await saveScreenshot(page, testInfo, "completed-deeplink-authority");
});

test.describe("completed replay unavailable", () => {
  test.use({ scenarioId: "completed-replay-detail-404" });

  test("detail or turn 404 renders diagnostic state instead of an empty conversation", async ({ page }) => {
    await gotoWorkbench(page, "/workbench/sessions/ses_completed");
    await expect(page.locator(".conversation-error-hint")).toContainText(/session URL not found|replay|unavailable/u);
    await expect(page.locator(selectors.messageCard)).toHaveCount(0);
    await expect(page.locator(selectors.sessionTabs)).not.toHaveAttribute("data-loading", "true");
  });
});
