import { Page, expect } from '@playwright/test';
import { E2E } from '../../playwright.config';

/**
 * The backoffice side of a flow.
 *
 * Every registration test needs an officer to act on what the applicant filed,
 * and the only account the IAM seed creates is the super admin — which holds
 * every permission, so it can claim, return, reject and approve without a
 * fixture inventing a position first.
 *
 * That breadth is also a limitation worth naming: these tests prove the actions
 * work, not that a *review officer* specifically may perform them. Per-role
 * authorisation needs its own accounts and belongs in its own spec.
 */
export const OFFICER = {
  email: process.env.E2E_OFFICER_EMAIL ?? 'superadmin@tria.com',
  password: process.env.E2E_OFFICER_PASSWORD ?? 'password@tria',
};

/** Signs the officer into the backoffice, which is a separate origin. */
export async function logInAsOfficer(page: Page): Promise<void> {
  await page.goto(`${E2E.backofficeUrl}/login`);
  await page.getByLabel(/email/i).fill(OFFICER.email);
  await page.getByLabel(/password/i).fill(OFFICER.password);
  await page.getByRole('button', { name: /sign in|log in|login/i }).click();

  await expect(page).not.toHaveURL(/\/login/, { timeout: 30_000 });
}

/**
 * Opens one application's review screen by its application number.
 *
 * Goes through the seafarer registration queue rather than deep-linking by id:
 * the queue is what an officer actually uses, and a test that skips it would
 * not notice the application failing to appear there at all.
 */
export async function openInQueue(
  page: Page,
  applicationNumber: string,
): Promise<void> {
  await page.goto(`${E2E.backofficeUrl}/seafarer-registrations`);
  // Oldest first and paged, so the newest registration is rarely on page one.
  await page.getByPlaceholder(/search/i).fill(applicationNumber);
  const row = page.getByRole('row', { name: new RegExp(applicationNumber, 'i') });
  await expect(row).toBeVisible({ timeout: 30_000 });
  await row.click();
}

/**
 * Clicks a workflow action and waits for the status to settle.
 *
 * Actions live behind buttons whose labels the design owns, so each is matched
 * by a loose pattern rather than an exact string — a rename should not read as
 * a broken workflow.
 */
export async function act(
  page: Page,
  action: RegExp,
  confirm: RegExp = /confirm|submit|yes|save|approve|reject|send/i,
): Promise<void> {
  await page.getByRole('button', { name: action }).first().click();

  // Most actions raise a modal; some apply directly. Either is fine.
  const dialog = page.getByRole('dialog');
  if (await dialog.isVisible({ timeout: 3_000 }).catch(() => false)) {
    const button = dialog.getByRole('button', { name: confirm }).first();
    if (await button.isVisible().catch(() => false)) await button.click();
  }
}
