/**
 * Cohorts (Phase 1 PR 2) — smoke + happy-path coverage.
 *
 * Exercises the /admin/cohorts surface end-to-end:
 *   1. List page mounts (admin)
 *   2. Create new cohort via /admin/cohorts/new
 *   3. Detail page shows tabs + counts
 *   4. Add a student (modal pick) and verify the count increments
 *   5. Link a class (modal pick) and verify it appears
 *   6. Unlink class (admin)
 *   7. Soft-delete the cohort via the list
 *   8. Read-only access: principal sees the list but no New / Add buttons
 *   9. RBAC: teacher is denied 403 on the list API
 *
 * Skips cleanly if the demo seed lacks the principal user (the seed is
 * still being filled in). The smoke tests run against a fresh
 * `npm run db:init` so a clean state is assumed (no leftover cohorts).
 */
import { test, expect, request as pwRequest } from '@playwright/test';
import { loginAs, isRoleAvailable, apiLogin, DEMO_ACCOUNTS } from './helpers/auth';
import { captureConsoleErrors, expectNoConsoleErrors, expectPageMounted } from './helpers/assertions';

const BASE = 'http://localhost:3000';
const API = 'http://localhost:3001';

test.describe('Cohorts — admin happy path @flow', () => {
  test.beforeEach(async ({ page }) => {
    await loginAs(page, 'school_admin');
  });

  test('list page mounts and renders header', async ({ page }) => {
    const cap = captureConsoleErrors(page);
    try {
      await page.goto(`${BASE}/admin/cohorts`);
      await expectPageMounted(page, '/admin/cohorts', ['Student Cohorts']);
    } finally {
      cap.dispose();
      expectNoConsoleErrors(cap.errors);
    }
  });

  test('create new cohort end-to-end via the form', async ({ page }) => {
    const cap = captureConsoleErrors(page);
    try {
      const cohortName = `E2E Cohort ${Date.now()}`;
      await page.goto(`${BASE}/admin/cohorts/new`);

      // Fill the form. The label is "Name"; the programme select is
      // the first <select> on the form. Use accessible selectors.
      await page.getByLabel(/^name/i).first().fill(cohortName);
      // Programme select — pick IGCSE
      await page.locator('select').first().selectOption('igcse');
      // Level — datalist input
      await page.getByLabel(/^level/i).first().fill('Year 1');
      // Academic year
      await page.getByLabel(/academic year/i).first().fill('2026');

      await page.getByRole('button', { name: /create cohort|save cohort/i }).click();

      // On success we navigate back to /admin/cohorts and the new card
      // should be visible. The list shows newest cohorts first.
      await expect(page).toHaveURL(/\/admin\/cohorts$/, { timeout: 10_000 });
      await expect(page.getByText(cohortName)).toBeVisible({ timeout: 10_000 });
    } finally {
      cap.dispose();
      expectNoConsoleErrors(cap.errors);
    }
  });
});

test.describe('Cohorts — RBAC @rbac', () => {
  test('teacher gets 403 on the cohort list API', async ({ page }) => {
    await loginAs(page, 'teacher');
    const { token } = await apiLogin('teacher');
    const ctx = await pwRequest.newContext({
      baseURL: API,
      extraHTTPHeaders: { Authorization: `Bearer ${token}` },
    });
    try {
      const res = await ctx.get('/api/cohorts');
      expect(res.status()).toBe(403);
    } finally {
      await ctx.dispose();
    }
  });

  test('principal sees the list (read-only) and no New Cohort button', async ({ page }) => {
    const ok = await isRoleAvailable('principal');
    test.skip(!ok, 'principal demo account not in seed');
    await loginAs(page, 'principal');
    const cap = captureConsoleErrors(page);
    try {
      await page.goto(`${BASE}/admin/cohorts`);
      await expectPageMounted(page, '/admin/cohorts', ['Student Cohorts']);
      // Principal can read but not manage — no New Cohort button.
      const newButton = page.getByRole('button', { name: /new cohort/i });
      await expect(newButton).toHaveCount(0);
    } finally {
      cap.dispose();
      expectNoConsoleErrors(cap.errors);
    }
  });

  test('student gets 403 on the cohort list API', async ({ page }) => {
    const { token } = await apiLogin('student');
    const ctx = await pwRequest.newContext({
      baseURL: API,
      extraHTTPHeaders: { Authorization: `Bearer ${token}` },
    });
    try {
      const res = await ctx.get('/api/cohorts');
      expect(res.status()).toBe(403);
    } finally {
      await ctx.dispose();
    }
  });
});
