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

/**
 * Authenticated RBAC access e2e (Workstream 8 / §3.6). Uses the seeded per-role
 * fixture users (Workstream 4). Requires the backend running with the database
 * migrated + seeded, and the seed passwords in the environment.
 */
const ADMIN_PASSWORD = 'flatlogicAdmin123!';
const USER_PASSWORD = 'flatlogicUser123!';

const ADMIN_EMAIL = 'admin@flatlogic.com';

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

// Seeded fixture user ids (see backend `shared/constants/seed-fixtures.ts`).
const OWNER_ID = 'b1a7c0de-0000-4000-8000-000000000012';

/** Denied responses may be 400 (permission middleware) or 403 (relational policy). */
const DENIED = [400, 401, 403];

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();
  // AuthGuard admits the shell; IndexRedirect lands on the first accessible module.
  await page.waitForURL((url) => !url.pathname.startsWith('/login'), {
    timeout: 10_000,
  });
}

test.describe('RBAC route access', () => {
  test('unauthenticated visitors are redirected to /login', async ({ page }) => {
    await page.goto('/dashboard');
    await expect(page).toHaveURL(/\/login/);
  });

  test('the super admin can open the director dashboard', async ({ page }) => {
    await login(page, ADMIN_EMAIL, ADMIN_PASSWORD);
    await page.goto('/director-dashboard');
    await expect(page).toHaveURL(/director-dashboard/);
    await expect(page.getByText('404')).toHaveCount(0);
  });

  test('a teacher cannot open the director dashboard (404)', async ({ page }) => {
    await login(page, 'teacher@flatlogic.com', USER_PASSWORD);
    await page.goto('/director-dashboard');
    await expect(page.getByText('404')).toBeVisible();
  });

  test('a student lands on an external page and is blocked from the dashboard', async ({
    page,
  }) => {
    await login(page, 'student@flatlogic.com', USER_PASSWORD);
    // Role-aware landing: the first module a student can access is Community.
    await expect(page).toHaveURL(/community-partnerships/);

    // Allowed external pages.
    await page.goto('/vocational-opportunities');
    await expect(page.getByText('404')).toHaveCount(0);
    await page.goto('/esa-funding');
    await expect(page.getByText('404')).toHaveCount(0);

    // Staff-only page is forbidden.
    await page.goto('/dashboard');
    await expect(page.getByText('404')).toBeVisible();
  });
});

test.describe('RBAC API enforcement', () => {
  test('the super admin can list users', async ({ page }) => {
    await login(page, ADMIN_EMAIL, ADMIN_PASSWORD);
    const res = await page.request.get(`${BACKEND_API_URL}/users`);
    expect(res.status()).toBe(200);
  });

  test('a teacher cannot create a user', async ({ page }) => {
    await login(page, 'teacher@flatlogic.com', USER_PASSWORD);
    const res = await page.request.post(`${BACKEND_API_URL}/users`, {
      data: { data: { email: 'should-not-exist@example.com' } },
    });
    expect(DENIED).toContain(res.status());
  });

  test('a superintendent cannot delete the owner (relational policy)', async ({
    page,
  }) => {
    await login(page, 'superintendent@flatlogic.com', USER_PASSWORD);
    const res = await page.request.delete(`${BACKEND_API_URL}/users/${OWNER_ID}`);
    expect(DENIED).toContain(res.status());
  });
});
