import { expect, type Page, test } from '@playwright/test';

/**
 * Scoped provisioning e2e (Workstream 8 / §3.4, §3.7). Proves the onboarding
 * contract: when a system admin creates an `owner` user with no organization,
 * the backend auto-creates the company and links the owner to it.
 *
 * Requires the backend running with the database migrated + seeded, and the
 * seed passwords in the environment.
 */
const ADMIN_PASSWORD = 'flatlogicAdmin123!';
const ADMIN_EMAIL = 'admin@flatlogic.com';

const BACKEND_API_URL =
  process.env.VITE_BACKEND_API_URL || 'http://localhost:8080/api';

interface RoleRow {
  readonly id: string;
  readonly name: string | null;
}
interface UserRow {
  readonly id: string;
  readonly email: string | null;
  readonly organizationId: string | null;
}

async function login(page: Page, email: string, password: string): Promise<void> {
  await page.goto('/login');
  await page.getByPlaceholder('you@school.edu').fill(email);
  await page.getByPlaceholder('Enter your password').fill(password);
  await page.getByRole('button', { name: 'Sign In', exact: true }).click();
  await page.waitForURL((url) => !url.pathname.startsWith('/login'), {
    timeout: 10_000,
  });
}

test.describe('Scoped provisioning', () => {
  test('creating an owner auto-creates and links the company', async ({
    page,
  }) => {
    await login(page, ADMIN_EMAIL, ADMIN_PASSWORD);

    // Resolve the seeded `owner` role id.
    const rolesRes = await page.request.get(`${BACKEND_API_URL}/roles`);
    expect(rolesRes.status()).toBe(200);
    const rolesBody = (await rolesRes.json()) as { rows?: RoleRow[] };
    const ownerRole = (rolesBody.rows ?? []).find((r) => r.name === 'owner');
    expect(ownerRole, 'seeded owner role must exist').toBeTruthy();

    // Create a brand-new owner with no organization.
    const email = `provisioned-owner-${Date.now()}@example.com`;
    const createRes = await page.request.post(`${BACKEND_API_URL}/users`, {
      data: { data: { email, app_role: ownerRole!.id } },
    });
    expect(createRes.ok()).toBe(true);

    // The owner now belongs to an auto-created company.
    const lookupRes = await page.request.get(
      `${BACKEND_API_URL}/users?email=${encodeURIComponent(email)}`,
    );
    expect(lookupRes.status()).toBe(200);
    const lookupBody = (await lookupRes.json()) as { rows?: UserRow[] };
    const created = (lookupBody.rows ?? []).find((u) => u.email === email);
    expect(created, 'the provisioned owner must exist').toBeTruthy();
    expect(
      created!.organizationId,
      'owner-create must auto-create and link a company',
    ).toBeTruthy();
  });
});
