/**
 * Page load smoke tests — verifies every main route renders without crashing
 * and shows its expected heading/content.
 */
import { expect, test } from "@playwright/test";
import {
  f,
  mockCommonApis,
  mockSchedulerApis,
  mockTaskSearch,
  mockWorkflowSearch,
} from "./helpers/mockApi";

test.describe("Page load smoke tests", () => {
  // ── Executions ──────────────────────────────────────────────────────────────

  test("Workflow Executions — home page loads", async ({ page }) => {
    await mockCommonApis(page);
    await mockWorkflowSearch(page);
    await page.goto("/");
    await expect(page.getByText("Search Executions")).toBeVisible();
    await expect(page.getByText("Page 1 of 1")).toBeVisible();
  });

  test("Workflow Executions — /executions route loads", async ({ page }) => {
    await mockCommonApis(page);
    await mockWorkflowSearch(page);
    await page.goto("/executions");
    await expect(page.getByText("Search Executions")).toBeVisible();
  });

  test("Task Executions — /search/tasks loads", async ({ page }) => {
    await mockCommonApis(page);
    await mockTaskSearch(page);
    await page.goto("/search/tasks");
    await expect(page.getByText("Search Executions")).toBeVisible();
    await expect(page.getByText("Task Name")).toBeVisible();
    await expect(
      page.getByText("There are no records to display")
    ).toBeVisible();
  });

  // ── Definitions ─────────────────────────────────────────────────────────────

  test("Workflow Definitions — /workflowDefs loads", async ({ page }) => {
    await mockCommonApis(page);
    await page.route("**/api/metadata/workflow", (route) =>
      route.fulfill({ path: f("metadataWorkflow.json") })
    );
    await page.goto("/workflowDefs");
    await expect(
      page.getByRole("heading", { name: "Definitions" })
    ).toBeVisible();
    await expect(
      page.getByRole("tab", { name: "Workflows" }).first()
    ).toBeVisible();
    await expect(
      page.getByRole("button", { name: /New Workflow Definition/i })
    ).toBeVisible();
  });

  test("Task Definitions — /taskDefs loads", async ({ page }) => {
    await mockCommonApis(page);
    await page.goto("/taskDefs");
    await expect(
      page.getByRole("heading", { name: "Definitions" })
    ).toBeVisible();
    await expect(
      page.getByRole("button", { name: /New Task Definition/i })
    ).toBeVisible();
  });

  test("Event Handler Definitions — /eventHandlerDefs loads", async ({
    page,
  }) => {
    await mockCommonApis(page);
    await page.route("**/api/event**", (route) =>
      route.fulfill({ path: f("eventHandlers.json") })
    );
    await page.goto("/eventHandlerDefs");
    await expect(
      page.getByRole("heading", { name: "Definitions" })
    ).toBeVisible();
    await expect(
      page.getByRole("button", { name: /New Event Handler Definition/i })
    ).toBeVisible();
  });

  test("Scheduler Definitions — /schedulerDefs loads", async ({ page }) => {
    await mockCommonApis(page);
    await mockSchedulerApis(page);
    await page.goto("/schedulerDefs");
    await expect(
      page.getByRole("heading", { name: "Definitions" })
    ).toBeVisible();
    await expect(
      page.getByRole("button", { name: /New Schedule/i })
    ).toBeVisible();
  });

  // ── Scheduler Executions ─────────────────────────────────────────────────────

  test("Scheduler Executions — /schedulerExecs loads", async ({ page }) => {
    await mockCommonApis(page);
    // mockSchedulerApis mocks both /schedules (needed by ScheduleNameInput) and
    // /search/executions. Without the schedules mock, serve -s returns index.html,
    // causing data.map() to throw and crash the component before the heading renders.
    await mockSchedulerApis(page);
    await page.goto("/schedulerExecs");
    await expect(
      page.getByRole("heading", { name: "Scheduler Executions" })
    ).toBeVisible();
    await expect(
      page.getByRole("columnheader", { name: "Schedule Name" })
    ).toBeVisible();
  });

  // ── Task Queue ───────────────────────────────────────────────────────────────

  test("Task Queues — /taskQueue loads", async ({ page }) => {
    await mockCommonApis(page);
    await page.goto("/taskQueue");
    await expect(
      page.getByRole("heading", { name: "Task Queues" })
    ).toBeVisible();
    await expect(page.getByText(/Select a Task Name/i)).toBeVisible();
  });

  test("Task Queues — poll data loads after selecting task", async ({
    page,
  }) => {
    await mockCommonApis(page);
    await page.route("**/api/tasks/queue/polldata**", (route) =>
      route.fulfill({ path: f("taskPollData.json") })
    );
    // Each /queue/size request is per-domain and expects a plain number in response.
    // Returning an object would crash the queueSize column renderer (React child error).
    await page.route("**/api/tasks/queue/size**", (route) =>
      route.fulfill({ body: "5", contentType: "application/json" })
    );
    await page.goto("/taskQueue");
    await page.locator(".MuiAutocomplete-inputRoot input").first().click();
    await page
      .locator("li.MuiAutocomplete-option")
      .filter({ hasText: "example_task_1" })
      .click();
    // Wait for the client-side navigation to /taskQueue/example_task_1 to settle
    // before asserting on the poll data table.
    await page.waitForURL("**/taskQueue/example_task_1");
    await expect(page.getByText("Poll Status by Domain")).toBeVisible();
    await expect(
      page.locator(".rdt_TableCell").filter({ hasText: "DEFAULT" }).first()
    ).toBeVisible();
  });

  // ── Workbench ────────────────────────────────────────────────────────────────

  test("Workbench — /workbench loads", async ({ page }) => {
    await mockCommonApis(page);
    await page.goto("/workbench");
    await expect(page.getByText("Workflow Workbench")).toBeVisible();
    await expect(page.getByText("Workflow Name")).toBeVisible();
  });
});
