/**
 * Shared login helper for Playwright @playwright/test spec files.
 * Uses the project baseURL (http://localhost:3000) from playwright.config.ts.
 */
import { type Page, expect } from "@playwright/test";

export interface Credentials {
  email: string;
  password: string;
}

export const USERS = {
  TECH:      { email: "tech@pelagia.local",      password: "tech1234"     },
  MANNING:   { email: "manning@pelagia.local",    password: "manning1234"  },
  ACCOUNTS:  { email: "accounts@pelagia.local",   password: "accounts1234" },
  MANAGER:   { email: "manager@pelagia.local",    password: "manager1234"  },
  SUPERUSER: { email: "superuser@pelagia.local",  password: "super1234"    },
  AUDITOR:   { email: "auditor@pelagia.local",    password: "audit1234"    },
  ADMIN:     { email: "admin@pelagia.local",       password: "admin1234"    },
} satisfies Record<string, Credentials>;

export async function login(page: Page, creds: Credentials): Promise<void> {
  await page.goto("/login");
  await page.getByLabel(/email address/i).fill(creds.email);
  await page.getByLabel(/password/i).fill(creds.password);
  await page.getByRole("button", { name: /sign in/i }).click();
  await expect(page).not.toHaveURL(/\/login/, { timeout: 20_000 });
  console.log(`✓ Logged in as ${creds.email}`);
}

export async function fillPoHeader(page: Page, title: string): Promise<void> {
  await page.waitForSelector('input[name="title"]', { timeout: 15_000 });
  await page.locator('input[name="title"]').fill(title);
  await page.locator('select[name="vesselId"]').selectOption({ index: 1 });
  await page.locator('select[name="accountId"]').selectOption({ index: 1 });
}

export async function fillFirstLineItem(
  page: Page,
  {
    name,
    quantity,
    unitPrice,
    description,
  }: {
    name: string;
    quantity: string;
    unitPrice: string;
    description?: string;
  }
): Promise<void> {
  const lineItems = page.locator("section").filter({
    has: page.getByRole("heading", { name: /line items/i }),
  });
  const firstRow = lineItems.locator("tbody tr").first();

  await firstRow.getByPlaceholder("Item name *").fill(name);
  if (description) {
    await firstRow.getByPlaceholder("Description (optional)").fill(description);
  }
  await firstRow.locator('input[type="number"]').first().fill(quantity);
  await firstRow.locator('input[placeholder="0.00"]').fill(unitPrice);
}

/**
 * Create a minimal draft PO and return the absolute PO URL.
 * Uses name-based selectors since the PO form labels have no htmlFor binding.
 */
export async function createDraftPo(page: Page, title: string): Promise<string> {
  await page.goto("/po/new");
  await fillPoHeader(page, title);
  await fillFirstLineItem(page, {
    name: "Test item",
    quantity: "1",
    unitPrice: "100",
  });
  await page.getByRole("button", { name: /save as draft/i }).click();
  await expect(page).toHaveURL(/\/po\//, { timeout: 20_000 });
  return page.url();
}

/** Create a PO and submit it for approval; returns the PO URL. */
export async function submitPo(page: Page, title: string): Promise<string> {
  await page.goto("/po/new");
  await fillPoHeader(page, title);
  await fillFirstLineItem(page, {
    name: "Engine gasket",
    quantity: "2",
    unitPrice: "250",
  });
  await page.getByRole("button", { name: /submit for approval/i }).click();
  await expect(page).toHaveURL(/\/po\//, { timeout: 20_000 });
  return page.url();
}
