// Phase 5 UI test — scenario: list
// Test ID: {{testId}}
// Renders one CRUD list page after logging in as a given role, asserting
// no 4xx/5xx responses and that the expected table testId is rendered.
// Final result: ONE console.log(JSON.stringify({...})) on stdout.
// Trace and intermediate logs go to console.warn (stderr).

const page = await browser.getPage("main");

const httpRequests = [];
const consoleErrors = [];

page.on("response", (r) => {
  try {
    httpRequests.push({
      url: r.url(),
      status: r.status(),
      method: r.request().method(),
    });
  } catch (e) {
    console.warn("response listener threw:", e && e.message ? e.message : String(e));
  }
});

page.on("console", (m) => {
  try {
    if (m.type() === "error") consoleErrors.push(m.text());
  } catch (e) {
    /* ignore listener errors */
  }
});

let result;

try {
  // ─── 1. Login as the role under test ────────────────────────────
  console.warn("[ui-test] login as " + "{{user.email}}");
  await page.goto("{{frontendUrl}}/login", { waitUntil: "domcontentloaded" });

  // Login form selectors. data-testid is the SmartStack convention; the
  // component scaffolder MUST emit these. If the test is failing here with
  // "selector not found", the scaffolded login page is missing testIds.
  const emailInput = page.locator('[data-testid="login-email"]');
  const passwordInput = page.locator('[data-testid="login-password"]');
  const submitBtn = page.locator('[data-testid="login-submit"]');

  await emailInput.waitFor({ state: "visible", timeout: 10000 });
  await emailInput.fill("{{user.email}}");
  await passwordInput.fill("{{user.password}}");
  await submitBtn.click();

  // After submit we expect a redirect away from /login. URL doesn't matter,
  // just that we leave login (which proves auth succeeded).
  await page.waitForURL((u) => !u.pathname.endsWith("/login"), { timeout: 10000 });

  // ─── 2. Navigate to the list page ───────────────────────────────
  console.warn("[ui-test] navigate to {{page}}");
  await page.goto("{{frontendUrl}}{{page}}", { waitUntil: "domcontentloaded" });

  // Give the page a beat to fire its initial GET. Without this the network
  // log can be empty by the time we inspect it.
  await page.waitForTimeout(1500);

  // ─── 3. Assertions ──────────────────────────────────────────────
  // 3a. No 4xx / 5xx on any request fired since login.
  const bad = httpRequests.find((r) =>
    [400, 401, 403, 404, 500, 502, 503].indexOf(r.status) !== -1,
  );

  // 3b. Expected element renders.
  let hasExpected = true;
  {{#if expectations.rendersTestId}}
  hasExpected = (await page.locator('[data-testid="{{expectations.rendersTestId}}"]').count()) > 0;
  {{/if}}

  // 3c. No console errors (when expectations.noConsoleError is true).
  {{#if expectations.noConsoleError}}
  const hasConsoleError = consoleErrors.length > 0;
  {{else}}
  const hasConsoleError = false;
  {{/if}}

  let status = "pass";
  let reason = "ok";
  if (bad) {
    status = "fail";
    reason = `HTTP ${bad.status} on ${bad.method} ${bad.url}`;
  } else if (!hasExpected) {
    status = "fail";
    reason = `expected testId "{{expectations.rendersTestId}}" not rendered`;
  } else if (hasConsoleError) {
    status = "fail";
    reason = `console errors detected: ${consoleErrors[0]}`;
  }

  // ─── 4. Always capture a screenshot ─────────────────────────────
  const screenshotRelPath = "{{captureDir}}/{{testId}}.png";
  try {
    const buf = await page.screenshot({ fullPage: false });
    await saveScreenshot(buf, screenshotRelPath);
  } catch (e) {
    console.warn("screenshot failed:", e && e.message ? e.message : String(e));
  }

  result = {
    status: status,
    reason: reason,
    capture: {
      httpRequests: httpRequests,
      consoleErrors: consoleErrors,
      screenshotRelPath: screenshotRelPath,
    },
  };
} catch (err) {
  result = {
    status: "fail",
    reason: "script-exception: " + (err && err.message ? err.message : String(err)),
    capture: {
      httpRequests: httpRequests,
      consoleErrors: consoleErrors,
    },
  };
}

console.log(JSON.stringify(result));
