import { test, expect } from "./fixtures.js";

/**
 * E2E tests for services deduplication.
 * Verifies that service names are unique in both admin services list
 * and in the booking service picker.
 */

const MOCK_SERVICES = [
  { id: "svc-1", name: "Full Groom", description: "Bath and haircut", basePriceCents: 7500, durationMinutes: 90, isActive: true },
  { id: "svc-2", name: "Bath Only", description: "Just the bath", basePriceCents: 3500, durationMinutes: 45, isActive: true },
  { id: "svc-3", name: "Nail Trim", description: "Just nails", basePriceCents: 1500, durationMinutes: 15, isActive: true },
];

test.describe("Services Deduplication", () => {
  test.beforeEach(async ({ page }) => {
    // Mock services endpoint FIRST before navigation
    // Also mock /api/book/services used by the booking wizard
    await page.route("**/api/services**", (route) =>
      route.fulfill({ json: MOCK_SERVICES })
    );
    await page.route("**/api/book/services**", (route) =>
      route.fulfill({ json: MOCK_SERVICES })
    );

    // Login as staff
    await page.goto("/login");
    await page.getByText("Alice Groomer").click();
    await expect(page).toHaveURL("/admin");
  });

  test("admin services page shows no duplicate service names", async ({ page }) => {
    await page.goto("/admin/services");

    // Wait for services to load
    await page.waitForTimeout(1_000);

    // Collect all service names from the table
    const serviceNameCells = page.locator("table tbody tr td:first-child");
    const count = await serviceNameCells.count();

    const names: string[] = [];
    for (let i = 0; i < count; i++) {
      const text = await serviceNameCells.nth(i).textContent();
      if (text) names.push(text.trim());
    }

    // Check for duplicates
    const duplicates = names.filter((name, index) => names.indexOf(name) !== index);

    // Assert no duplicate names
    expect(duplicates, `Found duplicate service names: ${duplicates.join(", ")}`).toHaveLength(0);

    // Verify all names are unique using Set comparison
    const uniqueNames = new Set(names);
    expect(uniqueNames.size).toBe(names.length);
  });

  test("admin services page renders all services", async ({ page }) => {
    await page.goto("/admin/services");

    // Wait for table to render
    await expect(page.locator("table")).toBeVisible({ timeout: 10_000 });

    // Should show the heading
    await expect(page.locator("h1")).toContainText("Services");

    // Should show all unique services
    const rowCount = await page.locator("table tbody tr").count();
    expect(rowCount).toBeGreaterThan(0);
  });

  test("booking service picker shows no duplicates", async ({ page }) => {
    await page.goto("/admin/book");

    // Wait for services to load in the booking wizard
    await page.waitForTimeout(1_000);

    // Collect service names from the picker
    const serviceCards = page.locator("text=/Full Groom|Bath Only|Nail Trim/");
    const serviceNames: string[] = [];

    // Get all text content that looks like service names
    const allText = await page.locator("body").textContent();
    if (allText) {
      const matches = allText.match(/(?:Full Groom|Bath Only|Nail Trim)/g);
      if (matches) {
        serviceNames.push(...matches);
      }
    }

    // Check for duplicates in the booking picker
    const duplicates = serviceNames.filter((name, index) => serviceNames.indexOf(name) !== index);

    expect(duplicates, `Found duplicate service names in booking picker: ${duplicates.join(", ")}`).toHaveLength(0);
  });

  test("booking wizard step 1 shows services", async ({ page }) => {
    await page.goto("/admin/book");

    // Should show at least one service
    await expect(page.getByText("Full Groom")).toBeVisible({ timeout: 10_000 });
  });
});