import { test, expect } from '@playwright/test';
import { execSync } from 'child_process';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

const baseUrl = process.env.PLAYWRIGHT_BASE_URL || 'http://localhost:4173';
const urlMatch = baseUrl.match(/:(\d+)$/);
const PORT = urlMatch ? urlMatch[1] : '4173';
const ALPHA_URL = `http://ecole-alpha.classeo.local:${PORT}`;
const TENANT_ID = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890';

const ADMIN_EMAIL = 'e2e-student-creation-admin@example.com';
const ADMIN_PASSWORD = 'StudentCreationTest123';

const UNIQUE_SUFFIX = Date.now();

const projectRoot = join(__dirname, '../..');
const composeFile = join(projectRoot, 'compose.yaml');

function runCommand(sql: string) {
	execSync(
		`docker compose -f "${composeFile}" exec -T php php bin/console dbal:run-sql "${sql}" 2>&1`,
		{ encoding: 'utf-8' }
	);
}

function clearCache() {
	try {
		execSync(
			`docker compose -f "${composeFile}" exec -T php php bin/console cache:pool:clear paginated_queries.cache 2>&1`,
			{ encoding: 'utf-8' }
		);
	} catch {
		// Cache pool may not exist in all environments
	}
}

function resolveDeterministicIds(): { schoolId: string; academicYearId: string } {
	const output = execSync(
		`docker compose -f "${composeFile}" exec -T php php -r '` +
			`require "/app/vendor/autoload.php"; ` +
			`$t="${TENANT_ID}"; $ns="6ba7b814-9dad-11d1-80b4-00c04fd430c8"; ` +
			`echo Ramsey\\Uuid\\Uuid::uuid5($ns,"school-$t")->toString()."\\n"; ` +
			`$m=(int)date("n"); $s=$m>=9?(int)date("Y"):(int)date("Y")-1; $e=$s+1; ` +
			`echo Ramsey\\Uuid\\Uuid::uuid5($ns,"$t:$s-$e")->toString();` +
			`' 2>&1`,
		{ encoding: 'utf-8' }
	).trim();
	const [schoolId, academicYearId] = output.split('\n');
	return { schoolId, academicYearId };
}

async function loginAsAdmin(page: import('@playwright/test').Page) {
	await page.goto(`${ALPHA_URL}/login`);
	await page.locator('#email').fill(ADMIN_EMAIL);
	await page.locator('#password').fill(ADMIN_PASSWORD);
	await Promise.all([
		page.waitForURL(/\/dashboard/, { timeout: 30000 }),
		page.getByRole('button', { name: /se connecter/i }).click()
	]);
}

async function waitForStudentsPage(page: import('@playwright/test').Page) {
	await expect(
		page.getByRole('heading', { name: /gestion des élèves/i })
	).toBeVisible({ timeout: 15000 });
	await expect(
		page.locator('.empty-state, .students-table, .alert-error')
	).toBeVisible({ timeout: 15000 });
}

let testClassId: string;
let testClassId2: string;

function createBulkStudents(count: number, tenantId: string, classId: string, academicYearId: string) {
	for (let i = 0; i < count; i++) {
		const suffix = UNIQUE_SUFFIX.toString().slice(-8);
		const paddedI = String(i).padStart(4, '0');
		const userId = `00000000-e2e0-4000-8000-${suffix}${paddedI}`;
		const assignmentId = `00000001-e2e0-4000-8000-${suffix}${paddedI}`;
		try {
			runCommand(
				`INSERT INTO users (id, tenant_id, email, first_name, last_name, roles, hashed_password, statut, school_name, date_naissance, created_at, activated_at, invited_at, blocked_at, blocked_reason, consentement_parent_id, consentement_eleve_id, consentement_date, consentement_ip, image_rights_status, image_rights_updated_at, image_rights_updated_by, student_number, updated_at) VALUES ('${userId}', '${tenantId}', NULL, 'Pagination${i}', 'Student-${UNIQUE_SUFFIX}', '[\\"ROLE_ELEVE\\"]', NULL, 'inscrit', 'E2E Test School', NULL, NOW(), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'not_specified', NULL, NULL, NULL, NOW()) ON CONFLICT (id) DO NOTHING`
			);
			runCommand(
				`INSERT INTO class_assignments (id, tenant_id, user_id, school_class_id, academic_year_id, assigned_at, created_at, updated_at) VALUES ('${assignmentId}', '${tenantId}', '${userId}', '${classId}', '${academicYearId}', NOW(), NOW(), NOW()) ON CONFLICT (id) DO NOTHING`
			);
		} catch {
			// Student may already exist
		}
	}
}

test.describe('Student Creation & Management (Story 3.0)', () => {
	test.describe.configure({ mode: 'serial' });

	test.beforeAll(async () => {
		// Create admin user
		execSync(
			`docker compose -f "${composeFile}" exec -T php php bin/console app:dev:create-test-user --tenant=ecole-alpha --email=${ADMIN_EMAIL} --password=${ADMIN_PASSWORD} --role=ROLE_ADMIN 2>&1`,
			{ encoding: 'utf-8' }
		);

		// Create a test class for student assignment
		const { schoolId, academicYearId } = resolveDeterministicIds();
		testClassId = `e2e-class-${UNIQUE_SUFFIX}`.substring(0, 36).padEnd(36, '0');
		// Use a valid UUID format
		testClassId = `00000000-0000-0000-0000-${UNIQUE_SUFFIX.toString().padStart(12, '0')}`;

		try {
			runCommand(
				`INSERT INTO school_classes (id, tenant_id, school_id, academic_year_id, name, level, capacity, status, created_at, updated_at) VALUES ('${testClassId}', '${TENANT_ID}', '${schoolId}', '${academicYearId}', 'E2E Test Class ${UNIQUE_SUFFIX}', 'CM2', 30, 'active', NOW(), NOW()) ON CONFLICT (id) DO NOTHING`
			);
		} catch {
			// Class may already exist
		}

		// Create a second test class for change-class tests
		testClassId2 = `00000001-0000-0000-0000-${UNIQUE_SUFFIX.toString().padStart(12, '0')}`;
		try {
			runCommand(
				`INSERT INTO school_classes (id, tenant_id, school_id, academic_year_id, name, level, capacity, status, created_at, updated_at) VALUES ('${testClassId2}', '${TENANT_ID}', '${schoolId}', '${academicYearId}', 'E2E Test Class 2 ${UNIQUE_SUFFIX}', 'CE2', 30, 'active', NOW(), NOW()) ON CONFLICT (id) DO NOTHING`
			);
		} catch {
			// Class may already exist
		}

		// Create 31 students for pagination tests (itemsPerPage = 30)
		createBulkStudents(31, TENANT_ID, testClassId, academicYearId);

		clearCache();
	});

	// ============================================================================
	// Navigation
	// ============================================================================
	test.describe('Navigation', () => {
		test('students page is accessible from admin nav', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/students`);

			await expect(page.getByRole('heading', { name: /gestion des élèves/i })).toBeVisible({
				timeout: 10000
			});
		});

		test('page title is set correctly', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/students`);

			await expect(page).toHaveTitle(/gestion des élèves/i);
		});

		test('nav menu shows Élèves link', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/students`);

			// Hover "Personnes" category to reveal dropdown with "Élèves" link
			const nav = page.locator('.desktop-nav');
			await nav.getByRole('button', { name: /personnes/i }).hover();
			await expect(nav.getByRole('menuitem', { name: /élèves/i })).toBeVisible({
				timeout: 10000
			});
		});
	});

	// ============================================================================
	// AC1: Create Student Form
	// ============================================================================
	test.describe('AC1 - Create Student Modal', () => {
		test('can open create student modal', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/students`);
			await waitForStudentsPage(page);

			await page.getByRole('button', { name: /nouvel élève/i }).click();

			const dialog = page.getByRole('dialog');
			await expect(dialog).toBeVisible({ timeout: 5000 });
			await expect(
				dialog.getByRole('heading', { name: /nouvel élève/i })
			).toBeVisible();
		});

		test('modal has all required fields', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/students`);
			await waitForStudentsPage(page);

			await page.getByRole('button', { name: /nouvel élève/i }).click();
			const dialog = page.getByRole('dialog');
			await expect(dialog).toBeVisible({ timeout: 5000 });

			// Required fields
			await expect(dialog.locator('#student-lastname')).toBeVisible();
			await expect(dialog.locator('#student-firstname')).toBeVisible();
			await expect(dialog.locator('#student-class')).toBeVisible();

			// Optional fields
			await expect(dialog.locator('#student-email')).toBeVisible();
			await expect(dialog.locator('#student-dob')).toBeVisible();
			await expect(dialog.locator('#student-ine')).toBeVisible();
		});

		test('class dropdown uses optgroup by level', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/students`);
			await waitForStudentsPage(page);

			await page.getByRole('button', { name: /nouvel élève/i }).click();
			const dialog = page.getByRole('dialog');
			await expect(dialog).toBeVisible({ timeout: 5000 });

			// Wait for classes to load in the dropdown (optgroup elements inside select are not "visible" per Playwright)
			await expect(dialog.locator('#student-class optgroup')).not.toHaveCount(0, { timeout: 10000 });

			// Check optgroups exist in the class select
			const optgroups = dialog.locator('#student-class optgroup');
			const count = await optgroups.count();
			expect(count).toBeGreaterThanOrEqual(1);
		});

		test('can close modal with cancel button', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/students`);
			await waitForStudentsPage(page);

			await page.getByRole('button', { name: /nouvel élève/i }).click();
			const dialog = page.getByRole('dialog');
			await expect(dialog).toBeVisible({ timeout: 5000 });

			await dialog.getByRole('button', { name: /annuler/i }).click();
			await expect(dialog).not.toBeVisible();
		});

		test('can close modal with Escape key', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/students`);
			await waitForStudentsPage(page);

			await page.getByRole('button', { name: /nouvel élève/i }).click();
			const dialog = page.getByRole('dialog');
			await expect(dialog).toBeVisible({ timeout: 5000 });

			// Focus the modal so the keydown handler receives the event
			await dialog.focus();
			await page.keyboard.press('Escape');
			await expect(dialog).not.toBeVisible();
		});
	});

	// ============================================================================
	// AC2: Create student with class assignment
	// ============================================================================
	test.describe('AC2 - Student Creation', () => {
		test('can create a student without email', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/students`);
			await waitForStudentsPage(page);

			await page.getByRole('button', { name: /nouvel élève/i }).click();
			const dialog = page.getByRole('dialog');
			await expect(dialog).toBeVisible({ timeout: 5000 });

			// Fill required fields
			await dialog.locator('#student-lastname').fill(`Dupont-${UNIQUE_SUFFIX}`);
			await dialog.locator('#student-firstname').fill('Marie');

			// Select first available class
			await dialog.locator('#student-class').selectOption({ index: 1 });

			// Submit
			await dialog.getByRole('button', { name: /créer l'élève/i }).click();

			// Success message should appear
			await expect(page.locator('.alert-success')).toBeVisible({ timeout: 10000 });
			await expect(page.locator('.alert-success')).toContainText(/inscrit/i);

			// Student should appear in the list
			await expect(page.locator('.students-table')).toBeVisible({ timeout: 5000 });
			await expect(
				page.locator('td', { hasText: `Dupont-${UNIQUE_SUFFIX}` })
			).toBeVisible();
		});

		test('can create a student with email', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/students`);
			await waitForStudentsPage(page);

			await page.getByRole('button', { name: /nouvel élève/i }).click();
			const dialog = page.getByRole('dialog');
			await expect(dialog).toBeVisible({ timeout: 5000 });

			await dialog.locator('#student-lastname').fill(`Martin-${UNIQUE_SUFFIX}`);
			await dialog.locator('#student-firstname').fill('Jean');
			await dialog.locator('#student-email').fill(`jean.martin.${UNIQUE_SUFFIX}@example.com`);
			await dialog.locator('#student-class').selectOption({ index: 1 });

			await dialog.getByRole('button', { name: /créer l'élève/i }).click();

			await expect(page.locator('.alert-success')).toBeVisible({ timeout: 10000 });
			await expect(page.locator('.alert-success')).toContainText(/invitation/i);
		});

		test('"Créer un autre" keeps modal open', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/students`);
			await waitForStudentsPage(page);

			await page.getByRole('button', { name: /nouvel élève/i }).click();
			const dialog = page.getByRole('dialog');
			await expect(dialog).toBeVisible({ timeout: 5000 });

			// Check "Créer un autre élève"
			await dialog.locator('input[type="checkbox"]').check();

			await dialog.locator('#student-lastname').fill(`Bernard-${UNIQUE_SUFFIX}`);
			await dialog.locator('#student-firstname').fill('Luc');
			await dialog.locator('#student-class').selectOption({ index: 1 });

			await dialog.getByRole('button', { name: /créer l'élève/i }).click();

			// Success should appear but modal stays open
			await expect(page.locator('.alert-success')).toBeVisible({ timeout: 10000 });
			await expect(dialog).toBeVisible();

			// Form fields should be cleared
			await expect(dialog.locator('#student-lastname')).toHaveValue('');
			await expect(dialog.locator('#student-firstname')).toHaveValue('');

			// Close the modal
			await dialog.getByRole('button', { name: /annuler/i }).click();
		});
	});

	// ============================================================================
	// AC3: Data validation
	// ============================================================================
	test.describe('AC3 - Validation', () => {
		test('[P0] INE validation shows error for invalid format', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/students`);
			await waitForStudentsPage(page);

			await page.getByRole('button', { name: /nouvel élève/i }).click();
			const dialog = page.getByRole('dialog');
			await expect(dialog).toBeVisible({ timeout: 5000 });

			// Fill required fields
			await dialog.locator('#student-firstname').fill('Test');
			await dialog.locator('#student-lastname').fill('INEValidation');
			await dialog.locator('#student-class').selectOption({ index: 1 });

			// Enter invalid INE (too short)
			await dialog.locator('#student-ine').fill('ABC');

			// Error message should appear
			await expect(dialog.locator('.field-error')).toBeVisible();
			await expect(dialog.locator('.field-error')).toContainText(/11 caractères/i);

			// Submit button should be disabled
			await expect(
				dialog.getByRole('button', { name: /créer l'élève/i })
			).toBeDisabled();

			// Fix INE to valid format (11 alphanumeric chars)
			await dialog.locator('#student-ine').fill('12345678901');

			// Error should disappear
			await expect(dialog.locator('.field-error')).not.toBeVisible();

			// Submit button should be enabled
			await expect(
				dialog.getByRole('button', { name: /créer l'élève/i })
			).toBeEnabled();

			// Close modal without creating
			await dialog.getByRole('button', { name: /annuler/i }).click();
		});

		test('[P0] shows error when email is already used', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/students`);
			await waitForStudentsPage(page);

			await page.getByRole('button', { name: /nouvel élève/i }).click();
			const dialog = page.getByRole('dialog');
			await expect(dialog).toBeVisible({ timeout: 5000 });

			// Use the same email as the student created in AC2
			await dialog.locator('#student-firstname').fill('Doublon');
			await dialog.locator('#student-lastname').fill('Email');
			await dialog
				.locator('#student-email')
				.fill(`jean.martin.${UNIQUE_SUFFIX}@example.com`);
			await dialog.locator('#student-class').selectOption({ index: 1 });

			await dialog.getByRole('button', { name: /créer l'élève/i }).click();

			// Error should appear (from API)
			await expect(page.locator('.alert-error')).toBeVisible({ timeout: 10000 });
			await expect(page.locator('.alert-error')).toContainText(/email/i);

			// Close modal
			await dialog.getByRole('button', { name: /annuler/i }).click();
		});

		test('[P0] shows duplicate warning for same name in same class', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/students`);
			await waitForStudentsPage(page);

			await page.getByRole('button', { name: /nouvel élève/i }).click();
			const dialog = page.getByRole('dialog');
			await expect(dialog).toBeVisible({ timeout: 5000 });

			// Use same name as student created in AC2
			await dialog.locator('#student-firstname').fill('Marie');
			await dialog.locator('#student-lastname').fill(`Dupont-${UNIQUE_SUFFIX}`);
			await dialog.locator('#student-class').selectOption({ index: 1 });

			// Submit — should trigger duplicate check
			await dialog.getByRole('button', { name: /créer l'élève/i }).click();

			// Duplicate warning should appear
			await expect(dialog.locator('.duplicate-warning')).toBeVisible({
				timeout: 10000
			});
			await expect(dialog.locator('.duplicate-warning')).toContainText(/existe déjà/i);

			// Click "Annuler" — warning disappears
			await dialog
				.locator('.duplicate-warning')
				.getByRole('button', { name: /annuler/i })
				.click();
			await expect(dialog.locator('.duplicate-warning')).not.toBeVisible();

			// Submit again — warning reappears
			await dialog.getByRole('button', { name: /créer l'élève/i }).click();
			await expect(dialog.locator('.duplicate-warning')).toBeVisible({
				timeout: 10000
			});

			// Click "Continuer" — creation succeeds despite duplicate
			await dialog
				.locator('.duplicate-warning')
				.getByRole('button', { name: /continuer/i })
				.click();

			await expect(page.locator('.alert-success')).toBeVisible({ timeout: 10000 });
		});
	});

	// ============================================================================
	// AC4: Students listing page
	// ============================================================================
	test.describe('AC4 - Students List', () => {
		test('displays students in a table', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/students`);
			await waitForStudentsPage(page);

			// Table should have headers
			await expect(page.locator('.students-table th', { hasText: /nom/i })).toBeVisible();
			await expect(page.locator('.students-table th', { hasText: /classe/i })).toBeVisible();
			await expect(page.locator('.students-table th', { hasText: /statut/i })).toBeVisible();
		});

		test('search filters students by name', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/students`);
			await waitForStudentsPage(page);

			// Search for a student created earlier
			const searchInput = page.locator('input[type="search"]');
			await searchInput.fill(`Dupont-${UNIQUE_SUFFIX}`);
			await page.waitForTimeout(500);
			await page.waitForLoadState('networkidle');

			// Should find the student (use .first() because AC3 duplicate test creates a second one)
			await expect(
				page.locator('td', { hasText: `Dupont-${UNIQUE_SUFFIX}` }).first()
			).toBeVisible({ timeout: 10000 });
		});

		test('rows are clickable and navigate to student detail', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/students`);
			await waitForStudentsPage(page);

			// Search for specific student
			const searchInput = page.locator('input[type="search"]');
			await searchInput.fill(`Dupont-${UNIQUE_SUFFIX}`);
			await page.waitForTimeout(500);
			await page.waitForLoadState('networkidle');

			// Click on the row (use .first() because AC3 duplicate test creates a second one)
			const row = page.locator('.clickable-row', {
				hasText: `Dupont-${UNIQUE_SUFFIX}`
			}).first();
			await row.click();

			// Should navigate to student detail page
			await expect(page).toHaveURL(/\/admin\/students\/[a-f0-9-]+/);
			await expect(
				page.getByRole('heading', { name: /fiche élève/i })
			).toBeVisible({ timeout: 10000 });
		});

		test('[P1] pagination appears when more than 30 students and navigation works', async ({
			page
		}) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/students`);
			await waitForStudentsPage(page);

			// Pagination nav should be visible (31 students created in beforeAll)
			const paginationNav = page.locator('nav[aria-label="Pagination"]');
			await expect(paginationNav).toBeVisible({ timeout: 10000 });

			// "Précédent" button should be disabled on page 1
			await expect(
				paginationNav.getByRole('button', { name: /précédent/i })
			).toBeDisabled();

			// Page 1 button should be active
			await expect(
				paginationNav.getByRole('button', { name: 'Page 1', exact: true })
			).toHaveAttribute('aria-current', 'page');

			// Click "Suivant" to go to page 2
			await paginationNav.getByRole('button', { name: /suivant/i }).click();
			await page.waitForLoadState('networkidle');

			// URL should contain page=2
			await expect(page).toHaveURL(/page=2/);

			// Page 2 button should now be active
			await expect(
				paginationNav.getByRole('button', { name: 'Page 2', exact: true })
			).toHaveAttribute('aria-current', 'page');

			// "Précédent" should now be enabled
			await expect(
				paginationNav.getByRole('button', { name: /précédent/i })
			).toBeEnabled();

			// Table or content should still be visible (not error)
			await expect(
				page.locator('.students-table, .empty-state')
			).toBeVisible({ timeout: 10000 });
		});
	});

	// ============================================================================
	// AC5: Change student class
	// ============================================================================
	test.describe('AC5 - Change Student Class', () => {
		test('[P1] can change class via modal with confirmation and optimistic update', async ({
			page
		}) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/students`);
			await waitForStudentsPage(page);

			// Search for a student created earlier
			const searchInput = page.locator('input[type="search"]');
			await searchInput.fill(`Dupont-${UNIQUE_SUFFIX}`);
			await page.waitForTimeout(500);
			await page.waitForLoadState('networkidle');

			// Find the student row and click "Changer de classe" (use .first() because AC3 duplicate test creates a second one)
			const row = page.locator('.clickable-row', {
				hasText: `Dupont-${UNIQUE_SUFFIX}`
			}).first();
			await expect(row).toBeVisible({ timeout: 10000 });
			await row.locator('button', { hasText: /changer de classe/i }).click();

			// Change class modal should open
			const dialog = page.locator('[role="alertdialog"]');
			await expect(dialog).toBeVisible({ timeout: 5000 });
			await expect(
				dialog.getByRole('heading', { name: /changer de classe/i })
			).toBeVisible();

			// Description should mention the student name
			await expect(dialog.locator('#change-class-description')).toContainText(
				`Dupont-${UNIQUE_SUFFIX}`
			);

			// Select a different class
			await dialog.locator('#change-class-select').selectOption({ index: 1 });

			// Confirmation text should appear
			await expect(dialog.locator('.change-confirm-info')).toBeVisible();
			await expect(dialog.locator('.change-confirm-info')).toContainText(/transférer/i);

			// Click "Confirmer le transfert"
			await dialog.getByRole('button', { name: /confirmer le transfert/i }).click();

			// Success message should appear
			await expect(page.locator('.alert-success')).toBeVisible({ timeout: 10000 });
			await expect(page.locator('.alert-success')).toContainText(/transféré/i);

			// Modal should close
			await expect(dialog).not.toBeVisible();
		});
	});

	// ============================================================================
	// AC6: Filter by class
	// ============================================================================
	test.describe('AC6 - Class Filter', () => {
		test('class filter dropdown exists with optgroups', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/students`);
			await waitForStudentsPage(page);

			const filterSelect = page.locator('#filter-class');
			await expect(filterSelect).toBeVisible();

			// Should have optgroups
			const optgroups = filterSelect.locator('optgroup');
			const count = await optgroups.count();
			expect(count).toBeGreaterThanOrEqual(1);
		});

		test('[P2] selecting a class filters the student list', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/students`);
			await waitForStudentsPage(page);

			// Select a class in the filter
			const filterSelect = page.locator('#filter-class');
			await filterSelect.selectOption({ index: 1 });

			// Wait for the list to reload
			await page.waitForLoadState('networkidle');

			// URL should contain classId parameter
			await expect(page).toHaveURL(/classId=/);

			// The page should still show the table or empty state (not an error)
			await expect(
				page.locator('.students-table, .empty-state')
			).toBeVisible({ timeout: 10000 });

			// Reset filter
			await filterSelect.selectOption({ value: '' });
			await page.waitForLoadState('networkidle');

			// classId should be removed from URL (polling assertion for reliability)
			await expect(page).not.toHaveURL(/classId=/, { timeout: 10000 });
		});
	});
});
