const { test, expect } = require('@playwright/test');
const {
  buildGrpcSessionOperationPayload,
  buildRestAsyncJobOperationPayload,
  buildRestWindowOperationPayload,
  initializeMcpSession,
  login,
  mcpToolCall,
  setupPublishedAgent,
  uniqueName,
} = require('./helpers');

test('rest window tool executes through MCP', async ({ page }) => {
  await login(page);

  const operationName = uniqueName('playwright_window_logs');
  const agentSlug = uniqueName('sales_window');
  const payload = buildRestWindowOperationPayload(operationName);

  const bundle = await setupPublishedAgent(page, {
    operationPayload: payload,
    agentSlug,
    toolName: operationName,
    toolTitle: 'Playwright Window Logs',
    toolDescription: 'Collects a bounded SSE log window from the local fixture.',
  });

  const mcp = await initializeMcpSession({
    workspaceSlug: bundle.workspace.slug,
    agentSlug,
    apiKey: bundle.apiKeySecret,
  });
  const result = await mcpToolCall(mcp, operationName, {});

  expect(result.window_complete).toBe(true);
  expect(result.has_more).toBe(false);
  expect(Array.isArray(result.items)).toBe(true);
  expect(result.items).toHaveLength(3);
  expect(result.items[0].message).toBe('billing started');
  expect(result.items[2].message).toBe('invoice timeout');
});

test('grpc session tools create persisted stream sessions visible in UI', async ({ page }) => {
  await login(page);

  const operationName = uniqueName('playwright_echo_session');
  const agentSlug = uniqueName('sales_session');
  const payload = buildGrpcSessionOperationPayload(operationName);

  const bundle = await setupPublishedAgent(page, {
    operationPayload: payload,
    agentSlug,
    toolName: operationName,
    toolTitle: 'Playwright gRPC Session',
    toolDescription: 'Streams gRPC echo messages through a bounded MCP session tool family.',
  });

  const mcp = await initializeMcpSession({
    workspaceSlug: bundle.workspace.slug,
    agentSlug,
    apiKey: bundle.apiKeySecret,
  });

  const started = await mcpToolCall(mcp, `${operationName}_start`, { message: 'hello' });
  const sessionId = started.session_id;
  expect(started.status).toBe('running');

  const polled = await mcpToolCall(mcp, `${operationName}_poll`, { session_id: sessionId });
  expect(polled.session_id).toBe(sessionId);
  expect(Array.isArray(polled.items)).toBe(true);
  expect(polled.items[0].message).toContain('hello');

  await page.goto('/stream-sessions');
  const sessionCard = page.locator(`.resource-card[data-session-id="${sessionId}"]`);
  await expect(sessionCard).toBeVisible();
  await sessionCard.locator('[data-action="toggle"]').click();
  await expect(sessionCard.locator('.resource-detail-pre')).toBeVisible();
  await sessionCard.locator('[data-action="stop"]').click();
  await expect(sessionCard.locator('[data-action="stop"]')).toHaveCount(0);
});

test('async job tools complete and expose results in UI', async ({ page }) => {
  await login(page);

  const operationName = uniqueName('playwright_async_lead');
  const agentSlug = uniqueName('sales_async');
  const payload = buildRestAsyncJobOperationPayload(operationName);

  const bundle = await setupPublishedAgent(page, {
    operationPayload: payload,
    agentSlug,
    toolName: operationName,
    toolTitle: 'Playwright Async Lead',
    toolDescription: 'Creates a lead through the async job MCP tool family.',
  });

  const mcp = await initializeMcpSession({
    workspaceSlug: bundle.workspace.slug,
    agentSlug,
    apiKey: bundle.apiKeySecret,
  });

  const started = await mcpToolCall(mcp, `${operationName}_start`, { email: 'user@example.com' });
  const jobId = started.job_id;
  expect(started.status).toBe('running');

  let status = null;
  for (let attempt = 0; attempt < 20; attempt += 1) {
    status = await mcpToolCall(mcp, `${operationName}_status`, { job_id: jobId });
    if (status.status === 'completed') {
      break;
    }
    await page.waitForTimeout(50);
  }

  expect(status.status).toBe('completed');
  const result = await mcpToolCall(mcp, `${operationName}_result`, { job_id: jobId });
  expect(result.id).toBe('lead_123');

  await page.goto('/async-jobs');
  const jobCard = page.locator(`.resource-card[data-job-id="${jobId}"]`);
  await expect(jobCard).toBeVisible();
  await jobCard.locator('[data-action="toggle"]').click();
  await expect(page.locator(`[data-result-for="${jobId}"]`)).toContainText('lead_123');
});
