<script lang="ts">
	import { goto } from '$app/navigation';
	import { page } from '$app/state';
	import Pagination from '$lib/components/molecules/Pagination/Pagination.svelte';
	import SearchInput from '$lib/components/molecules/SearchInput/SearchInput.svelte';
	import { SCHOOL_LEVEL_OPTIONS } from '$lib/constants/schoolLevels';
	import {
		fetchStudents as apiFetchStudents,
		fetchClasses as apiFetchClasses,
		createStudent as apiCreateStudent,
		changeStudentClass as apiChangeStudentClass,
		type Student,
		type SchoolClass
	} from '$lib/features/students/api/students';
	import { untrack } from 'svelte';

	// State
	let students = $state<Student[]>([]);
	let classes = $state<SchoolClass[]>([]);
	let isLoading = $state(true);
	let error = $state<string | null>(null);
	let successMessage = $state<string | null>(null);

	// Filters
	let filterClassId = $state<string>(page.url.searchParams.get('classId') ?? '');

	// Pagination & Search
	let currentPage = $state(Number(page.url.searchParams.get('page')) || 1);
	let searchTerm = $state(page.url.searchParams.get('search') ?? '');
	let totalItems = $state(0);
	const itemsPerPage = 30;
	let totalPages = $derived(Math.ceil(totalItems / itemsPerPage));

	// Create modal state
	let showCreateModal = $state(false);
	let newFirstName = $state('');
	let newLastName = $state('');
	let newEmail = $state('');
	let newClassId = $state('');
	let newDateNaissance = $state('');
	let newStudentNumber = $state('');
	let newParentalConsent = $state(false);
	let isSubmitting = $state(false);
	let duplicateWarning = $state<string | null>(null);
	let duplicateConfirmed = $state(false);
	let createAnother = $state(false);

	let needsParentalConsent = $derived(() => {
		if (!newDateNaissance) return false;
		const birth = new Date(newDateNaissance + 'T00:00:00');
		const now = new Date();
		let age = now.getFullYear() - birth.getFullYear();
		const monthDiff = now.getMonth() - birth.getMonth();
		if (monthDiff < 0 || (monthDiff === 0 && now.getDate() < birth.getDate())) {
			age--;
		}
		return age < 15;
	});

	// Change class modal state
	let showChangeClassModal = $state(false);
	let changeClassTarget = $state<Student | null>(null);
	let newClassForChange = $state('');
	let isChangingClass = $state(false);
	let changeClassError = $state<string | null>(null);

	// Classes grouped by level for optgroup
	let classesByLevel = $derived.by(() => {
		const groups: Record<string, SchoolClass[]> = {};
		const noLevel: SchoolClass[] = [];
		for (const cls of classes) {
			if (cls.level) {
				const existing = groups[cls.level];
				if (existing) {
					existing.push(cls);
				} else {
					groups[cls.level] = [cls];
				}
			} else {
				noLevel.push(cls);
			}
		}
		// Order groups by SCHOOL_LEVEL_OPTIONS order
		const ordered: { level: string; classes: SchoolClass[] }[] = [];
		for (const opt of SCHOOL_LEVEL_OPTIONS) {
			const group = groups[opt.value];
			if (group) {
				ordered.push({ level: opt.label, classes: group });
			}
		}
		if (noLevel.length > 0) {
			ordered.push({ level: 'Autre', classes: noLevel });
		}
		return ordered;
	});

	// Load data on mount
	let loadAbortController: AbortController | null = null;

	$effect(() => {
		untrack(() => {
			loadStudents();
			loadClasses();
		});
	});

	async function loadStudents() {
		loadAbortController?.abort();
		const controller = new AbortController();
		loadAbortController = controller;

		try {
			isLoading = true;
			error = null;
			const result = await apiFetchStudents({
				page: currentPage,
				itemsPerPage,
				search: searchTerm || undefined,
				classId: filterClassId || undefined,
				signal: controller.signal
			});

			if (controller.signal.aborted) return;

			students = result.members;
			totalItems = result.totalItems;
		} catch (e) {
			if (e instanceof DOMException && e.name === 'AbortError') return;
			error = e instanceof Error ? e.message : 'Erreur inconnue';
			students = [];
			totalItems = 0;
		} finally {
			if (!controller.signal.aborted) {
				isLoading = false;
			}
		}
	}

	async function loadClasses() {
		try {
			classes = await apiFetchClasses();
		} catch {
			// Non-blocking: classes will just be empty
		}
	}

	function updateUrl() {
		const params = new URLSearchParams();
		if (currentPage > 1) params.set('page', String(currentPage));
		if (searchTerm) params.set('search', searchTerm);
		if (filterClassId) params.set('classId', filterClassId);
		const query = params.toString();
		goto(`?${query}`, { replaceState: true, noScroll: true, keepFocus: true });
	}

	function handleSearch(value: string) {
		searchTerm = value;
		currentPage = 1;
		updateUrl();
		loadStudents();
	}

	function handlePageChange(newPage: number) {
		currentPage = newPage;
		updateUrl();
		loadStudents();
	}

	function handleFilterClass() {
		currentPage = 1;
		updateUrl();
		loadStudents();
	}

	function resetFilters() {
		filterClassId = '';
		searchTerm = '';
		currentPage = 1;
		updateUrl();
		loadStudents();
	}

	// --- Create student ---

	function openCreateModal() {
		showCreateModal = true;
		newFirstName = '';
		newLastName = '';
		newEmail = '';
		newClassId = '';
		newDateNaissance = '';
		newStudentNumber = '';
		newParentalConsent = false;
		duplicateWarning = null;
		duplicateConfirmed = false;
		createAnother = false;
		error = null;
	}

	function closeCreateModal() {
		showCreateModal = false;
	}

	async function checkDuplicate(): Promise<boolean> {
		if (duplicateConfirmed) return false;
		const first = newFirstName.trim().toLowerCase();
		const last = newLastName.trim().toLowerCase();

		try {
			const result = await apiFetchStudents({
				page: 1,
				itemsPerPage: 100,
				search: newLastName.trim(),
				classId: newClassId
			});
			const duplicate = result.members.find(
				(s) => s.firstName.toLowerCase() === first && s.lastName.toLowerCase() === last
			);
			if (duplicate) {
				duplicateWarning = `Un élève nommé ${duplicate.firstName} ${duplicate.lastName} existe déjà dans cette classe. Voulez-vous continuer ?`;
				return true;
			}
		} catch {
			// Non-blocking: skip duplicate check on error
		}

		return false;
	}

	function confirmDuplicate() {
		duplicateConfirmed = true;
		duplicateWarning = null;
		handleCreateStudent();
	}

	function cancelDuplicate() {
		duplicateWarning = null;
	}

	async function handleCreateStudent() {
		if (!newFirstName.trim() || !newLastName.trim() || !newClassId) return;
		if (needsParentalConsent() && !newParentalConsent) return;

		if (await checkDuplicate()) return;

		try {
			isSubmitting = true;
			error = null;
			const created = await apiCreateStudent({
				firstName: newFirstName.trim(),
				lastName: newLastName.trim(),
				classId: newClassId,
				email: newEmail.trim() ? newEmail.trim().toLowerCase() : undefined,
				dateNaissance: newDateNaissance || undefined,
				studentNumber: newStudentNumber.trim() || undefined,
				parentalConsent: newParentalConsent || undefined
			});

			// Optimistic update: only add to list if matching current filters
			const matchesClassFilter = !filterClassId || created.classId === filterClassId;
			const matchesSearch =
				!searchTerm ||
				created.firstName.toLowerCase().includes(searchTerm.toLowerCase()) ||
				created.lastName.toLowerCase().includes(searchTerm.toLowerCase());

			if (matchesClassFilter && matchesSearch) {
				students = [created, ...students];
				totalItems += 1;
			}

			const studentName = `${created.firstName} ${created.lastName}`;
			if (newEmail.trim()) {
				successMessage = `${studentName} a été créé et une invitation a été envoyée.`;
			} else {
				successMessage = `${studentName} a été inscrit avec succès.`;
			}

			if (createAnother) {
				// Reset form for next creation
				newFirstName = '';
				newLastName = '';
				newEmail = '';
				newDateNaissance = '';
				newStudentNumber = '';
				duplicateWarning = null;
				duplicateConfirmed = false;
				// Keep classId and modal open
			} else {
				closeCreateModal();
			}
		} catch (e) {
			error = e instanceof Error ? e.message : 'Erreur lors de la création';
		} finally {
			isSubmitting = false;
		}
	}

	// --- Change class ---

	function openChangeClassModal(student: Student) {
		changeClassTarget = student;
		newClassForChange = '';
		showChangeClassModal = true;
		changeClassError = null;
	}

	function closeChangeClassModal() {
		showChangeClassModal = false;
		changeClassTarget = null;
	}

	async function handleChangeClass() {
		if (!changeClassTarget || !newClassForChange) return;

		try {
			isChangingClass = true;
			error = null;
			await apiChangeStudentClass(changeClassTarget.id, newClassForChange);

			// Optimistic update
			const targetClass = classes.find((c) => c.id === newClassForChange);
			if (filterClassId && newClassForChange !== filterClassId) {
				// Student no longer matches class filter — remove from list
				students = students.filter((s) => s.id !== changeClassTarget!.id);
				totalItems -= 1;
			} else {
				students = students.map((s) =>
					s.id === changeClassTarget!.id
						? {
								...s,
								classId: newClassForChange,
								className: targetClass?.name ?? null,
								classLevel: targetClass?.level ?? null
							}
						: s
				);
			}

			successMessage = `${changeClassTarget.firstName} ${changeClassTarget.lastName} a été transféré vers ${targetClass?.name ?? 'la nouvelle classe'}.`;
			closeChangeClassModal();
		} catch (e) {
			changeClassError = e instanceof Error ? e.message : 'Erreur lors du changement de classe';
		} finally {
			isChangingClass = false;
		}
	}

	// --- Helpers ---

	function getStatutLabel(statut: string): string {
		switch (statut) {
			case 'pending':
				return 'En attente';
			case 'active':
				return 'Actif';
			case 'inscrit':
				return 'Inscrit';
			case 'suspended':
				return 'Suspendu';
			default:
				return statut;
		}
	}

	function getStatutClass(statut: string): string {
		switch (statut) {
			case 'active':
				return 'status-active';
			case 'pending':
				return 'status-pending';
			case 'inscrit':
				return 'status-inscrit';
			case 'suspended':
				return 'status-blocked';
			default:
				return '';
		}
	}

	function isValidINE(value: string): boolean {
		return /^[A-Za-z0-9]{11}$/.test(value);
	}

	let ineError = $derived(
		newStudentNumber.trim() && !isValidINE(newStudentNumber.trim())
			? "L'INE doit contenir exactement 11 caractères alphanumériques"
			: null
	);

	let canSubmitCreate = $derived(
		newFirstName.trim() !== '' &&
			newLastName.trim() !== '' &&
			newClassId !== '' &&
			!isSubmitting &&
			(!newStudentNumber.trim() || isValidINE(newStudentNumber.trim())) &&
			(!needsParentalConsent() || newParentalConsent)
	);
</script>

<svelte:head>
	<title>Gestion des élèves - Classeo</title>
</svelte:head>

<div class="students-page">
	<header class="page-header">
		<div class="header-content">
			<h1>Gestion des élèves</h1>
			<p class="subtitle">Créez et gérez les élèves de votre établissement</p>
		</div>
		<div class="header-actions">
			<a href="/admin/import/students" class="btn-secondary">
				Importer (CSV)
			</a>
			<button class="btn-primary" onclick={openCreateModal}>
				<span class="btn-icon">+</span>
				Nouvel élève
			</button>
		</div>
	</header>

	{#if error}
		<div class="alert alert-error">
			{error}
			<button class="alert-close" onclick={() => (error = null)}>×</button>
		</div>
	{/if}

	{#if successMessage}
		<div class="alert alert-success">
			{successMessage}
			<button class="alert-close" onclick={() => (successMessage = null)}>×</button>
		</div>
	{/if}

	<!-- Filters -->
	<div class="filters-bar">
		<div class="filter-group">
			<label for="filter-class">Classe</label>
			<select id="filter-class" bind:value={filterClassId} onchange={handleFilterClass}>
				<option value="">Toutes les classes</option>
				{#each classesByLevel as group}
					<optgroup label={group.level}>
						{#each group.classes as cls}
							<option value={cls.id}>{cls.name}</option>
						{/each}
					</optgroup>
				{/each}
			</select>
		</div>
		<div class="filter-actions">
			<button class="btn-text btn-sm" onclick={resetFilters}>Réinitialiser</button>
		</div>
	</div>

	<SearchInput
		value={searchTerm}
		onSearch={handleSearch}
		placeholder="Rechercher par nom, prénom..."
	/>

	{#if isLoading}
		<div class="loading-state" aria-live="polite" role="status">
			<div class="spinner"></div>
			<p>Chargement des élèves...</p>
		</div>
	{:else if students.length === 0}
		<div class="empty-state">
			<span class="empty-icon">🎓</span>
			{#if searchTerm || filterClassId}
				<h2>Aucun résultat</h2>
				<p>Aucun élève ne correspond à vos critères de recherche</p>
				<button class="btn-secondary" onclick={resetFilters}>Réinitialiser les filtres</button>
			{:else}
				<h2>Aucun élève</h2>
				<p>Commencez par créer votre premier élève</p>
				<button class="btn-primary" onclick={openCreateModal}>Nouvel élève</button>
			{/if}
		</div>
	{:else}
		<div class="students-table-container">
			<table class="students-table">
				<thead>
					<tr>
						<th>Nom</th>
						<th>Classe</th>
						<th>Statut</th>
						<th>Actions</th>
					</tr>
				</thead>
				<tbody>
					{#each students as student (student.id)}
						<tr
							class="clickable-row"
							onclick={() => goto(`/admin/students/${student.id}`)}
							role="link"
							tabindex="0"
							onkeydown={(e) => { if (e.key === 'Enter') goto(`/admin/students/${student.id}`); }}
						>
							<td data-label="Nom" class="student-name-cell">
								<span class="student-fullname">{student.lastName} {student.firstName}</span>
							</td>
							<td data-label="Classe">
								{#if student.className}
									<span class="class-badge">{student.className}</span>
								{:else}
									<span class="no-class">Non affecté</span>
								{/if}
							</td>
							<td data-label="Statut">
								<span class="status-badge {getStatutClass(student.statut)}">
									{getStatutLabel(student.statut)}
								</span>
							</td>
							<td data-label="Actions" class="actions-cell">
								<button
									class="btn-secondary btn-sm"
									onclick={(e) => { e.stopPropagation(); openChangeClassModal(student); }}
								>
									Changer de classe
								</button>
							</td>
						</tr>
					{/each}
				</tbody>
			</table>
		</div>
		<Pagination {currentPage} {totalPages} onPageChange={handlePageChange} />
	{/if}
</div>

<!-- Create Student Modal -->
{#if showCreateModal}
	<!-- svelte-ignore a11y_no_static_element_interactions -->
	<div class="modal-overlay" onclick={closeCreateModal} role="presentation">
		<div
			class="modal"
			role="dialog"
			aria-modal="true"
			aria-labelledby="create-modal-title"
			tabindex="-1"
			onclick={(e) => e.stopPropagation()}
			onkeydown={(e) => { if (e.key === 'Escape') closeCreateModal(); }}
		>
			<header class="modal-header">
				<h2 id="create-modal-title">Nouvel élève</h2>
				<button class="modal-close" onclick={closeCreateModal} aria-label="Fermer">×</button>
			</header>

			<form
				class="modal-body"
				onsubmit={(e) => {
					e.preventDefault();
					handleCreateStudent();
				}}
			>
				<div class="form-row">
					<div class="form-group">
						<label for="student-firstname">Prénom *</label>
						<input
							type="text"
							id="student-firstname"
							bind:value={newFirstName}
							placeholder="ex: Marie"
							required
							maxlength="100"
						/>
					</div>
					<div class="form-group">
						<label for="student-lastname">Nom *</label>
						<input
							type="text"
							id="student-lastname"
							bind:value={newLastName}
							placeholder="ex: Dupont"
							required
							maxlength="100"
						/>
					</div>
				</div>

				<div class="form-group">
					<label for="student-class">Classe *</label>
					<select id="student-class" bind:value={newClassId} required>
						<option value="">-- Sélectionner une classe --</option>
						{#each classesByLevel as group}
							<optgroup label={group.level}>
								{#each group.classes as cls}
									<option value={cls.id}>{cls.name}</option>
								{/each}
							</optgroup>
						{/each}
					</select>
				</div>

				<div class="form-group">
					<label for="student-email">Email <span class="field-optional">(optionnel)</span></label>
					<input
						type="email"
						id="student-email"
						bind:value={newEmail}
						placeholder="ex: marie.dupont@email.com"
					/>
					<span class="field-hint">Si fourni, une invitation sera envoyée automatiquement.</span>
				</div>

				<div class="form-row">
					<div class="form-group">
						<label for="student-dob">Date de naissance <span class="field-optional">(optionnel)</span></label>
						<input
							type="date"
							id="student-dob"
							bind:value={newDateNaissance}
						/>
					</div>
					<div class="form-group">
						<label for="student-ine">INE <span class="field-optional">(optionnel)</span></label>
						<input
							type="text"
							id="student-ine"
							bind:value={newStudentNumber}
							placeholder="11 caractères"
							maxlength="11"
						/>
						{#if ineError}
							<span class="field-error">{ineError}</span>
						{/if}
					</div>
				</div>

				{#if needsParentalConsent()}
					<div class="consent-notice">
						<label class="consent-label">
							<input type="checkbox" bind:checked={newParentalConsent} />
							<span>Consentement parental obtenu</span>
						</label>
						<span class="field-hint">
							Obligatoire pour les élèves de moins de 15 ans (RGPD).
							Confirmez que l'établissement a recueilli le consentement parental.
						</span>
					</div>
				{/if}

				{#if duplicateWarning}
					<div class="duplicate-warning">
						<p>{duplicateWarning}</p>
						<div class="duplicate-actions">
							<button type="button" class="btn-secondary btn-sm" onclick={cancelDuplicate}>Annuler</button>
							<button type="button" class="btn-primary btn-sm" onclick={confirmDuplicate}>Continuer</button>
						</div>
					</div>
				{/if}

				<div class="modal-actions">
					<label class="create-another-label">
						<input type="checkbox" bind:checked={createAnother} />
						<span>Créer un autre élève</span>
					</label>
					<div class="modal-actions-buttons">
						<button type="button" class="btn-secondary" onclick={closeCreateModal} disabled={isSubmitting}>
							Annuler
						</button>
						<button
							type="submit"
							class="btn-primary"
							disabled={!canSubmitCreate}
						>
							{#if isSubmitting}
								Création...
							{:else}
								Créer l'élève
							{/if}
						</button>
					</div>
				</div>
			</form>
		</div>
	</div>
{/if}

<!-- Change Class Modal -->
{#if showChangeClassModal && changeClassTarget}
	<!-- svelte-ignore a11y_no_static_element_interactions -->
	<div class="modal-overlay" onclick={closeChangeClassModal} role="presentation">
		<div
			class="modal modal-confirm"
			role="alertdialog"
			aria-modal="true"
			aria-labelledby="change-class-title"
			aria-describedby="change-class-description"
			tabindex="-1"
			onclick={(e) => e.stopPropagation()}
			onkeydown={(e) => { if (e.key === 'Escape') closeChangeClassModal(); }}
		>
			<header class="modal-header">
				<h2 id="change-class-title">Changer de classe</h2>
				<button class="modal-close" onclick={closeChangeClassModal} aria-label="Fermer">×</button>
			</header>

			<div class="modal-body">
				<p id="change-class-description">
					Transférer <strong>{changeClassTarget.firstName} {changeClassTarget.lastName}</strong>
					{#if changeClassTarget.className}
						(actuellement en {changeClassTarget.className})
					{/if}
					vers une autre classe :
				</p>

				<div class="form-group">
					<label for="change-class-select">Nouvelle classe *</label>
					<select id="change-class-select" bind:value={newClassForChange}>
						<option value="">-- Sélectionner une classe --</option>
						{#each classesByLevel as group}
							<optgroup label={group.level}>
								{#each group.classes as cls}
									{#if cls.id !== changeClassTarget.classId}
										<option value={cls.id}>{cls.name}</option>
									{/if}
								{/each}
							</optgroup>
						{/each}
					</select>
				</div>

				{#if changeClassError}
					<div class="alert alert-error modal-error">
						{changeClassError}
						<button class="alert-close" onclick={() => (changeClassError = null)}>×</button>
					</div>
				{/if}

				{#if newClassForChange}
					{@const targetClass = classes.find((c) => c.id === newClassForChange)}
					<div class="change-confirm-info">
						Transférer <strong>{changeClassTarget.firstName} {changeClassTarget.lastName}</strong> vers <strong>{targetClass?.name}</strong> ?
					</div>
				{/if}

				<div class="modal-actions">
					<button type="button" class="btn-secondary" onclick={closeChangeClassModal} disabled={isChangingClass}>
						Annuler
					</button>
					<button
						type="button"
						class="btn-primary"
						onclick={handleChangeClass}
						disabled={isChangingClass || !newClassForChange}
					>
						{#if isChangingClass}
							Transfert...
						{:else}
							Confirmer le transfert
						{/if}
					</button>
				</div>
			</div>
		</div>
	</div>
{/if}

<style>
	.students-page {
		padding: 1.5rem;
		max-width: 1200px;
		margin: 0 auto;
	}

	.page-header {
		display: flex;
		justify-content: space-between;
		align-items: flex-start;
		gap: 1rem;
		margin-bottom: 1.5rem;
		flex-wrap: wrap;
	}

	.header-actions {
		display: flex;
		gap: 0.75rem;
		align-items: center;
	}

	.header-content h1 {
		margin: 0;
		font-size: 1.5rem;
		font-weight: 700;
		color: #1f2937;
	}

	.subtitle {
		margin: 0.25rem 0 0;
		color: #6b7280;
		font-size: 0.875rem;
	}

	/* Buttons */
	.btn-primary {
		display: inline-flex;
		align-items: center;
		gap: 0.5rem;
		padding: 0.75rem 1.25rem;
		background: var(--btn-primary-bg, #3b82f6);
		color: white;
		border: none;
		border-radius: 0.5rem;
		font-weight: 600;
		cursor: pointer;
		transition: background 0.2s;
	}

	.btn-primary:hover:not(:disabled) {
		background: var(--btn-primary-hover-bg, #2563eb);
	}

	.btn-primary:disabled {
		opacity: 0.6;
		cursor: not-allowed;
	}

	.btn-secondary {
		padding: 0.5rem 1rem;
		background: white;
		color: #374151;
		border: 1px solid #d1d5db;
		border-radius: 0.375rem;
		font-weight: 500;
		cursor: pointer;
		transition: all 0.2s;
	}

	.btn-secondary:hover:not(:disabled) {
		background: #f3f4f6;
	}

	.btn-secondary:disabled {
		opacity: 0.6;
		cursor: not-allowed;
	}

	.btn-text {
		padding: 0.5rem 1rem;
		background: none;
		color: #6b7280;
		border: none;
		border-radius: 0.375rem;
		font-weight: 500;
		cursor: pointer;
		transition: color 0.2s;
	}

	.btn-text:hover {
		color: #374151;
	}

	.btn-sm {
		padding: 0.375rem 0.75rem;
		font-size: 0.875rem;
	}

	.btn-icon {
		font-size: 1.25rem;
		line-height: 1;
	}

	/* Alerts */
	.alert {
		display: flex;
		align-items: center;
		gap: 0.75rem;
		padding: 1rem;
		border-radius: 0.5rem;
		margin-bottom: 1rem;
	}

	.alert-error {
		background: #fef2f2;
		border: 1px solid #fecaca;
		color: #dc2626;
	}

	.alert-success {
		background: #f0fdf4;
		border: 1px solid #bbf7d0;
		color: #16a34a;
	}

	.alert-close {
		margin-left: auto;
		padding: 0.25rem 0.5rem;
		background: none;
		border: none;
		font-size: 1.25rem;
		cursor: pointer;
		opacity: 0.6;
	}

	.alert-close:hover {
		opacity: 1;
	}

	/* Filters */
	.filters-bar {
		display: flex;
		flex-direction: column;
		align-items: stretch;
		gap: 1rem;
		margin-bottom: 1.5rem;
		padding: 1rem;
		background: white;
		border: 1px solid #e5e7eb;
		border-radius: 0.75rem;
		flex-wrap: wrap;
	}

	.filter-group {
		display: flex;
		flex-direction: column;
		gap: 0.25rem;
	}

	.filter-group label {
		font-size: 0.75rem;
		font-weight: 500;
		color: #6b7280;
		text-transform: uppercase;
		letter-spacing: 0.05em;
	}

	.filter-group select {
		padding: 0.5rem 0.75rem;
		border: 1px solid #d1d5db;
		border-radius: 0.375rem;
		font-size: 0.875rem;
		min-width: auto;
		width: 100%;
		background: white;
	}

	.filter-group select:focus {
		outline: none;
		border-color: #3b82f6;
		box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
	}

	.filter-actions {
		display: flex;
		gap: 0.5rem;
		align-items: center;
	}

	/* Loading & Empty */
	.loading-state,
	.empty-state {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		padding: 3rem;
		text-align: center;
		background: white;
		border-radius: 0.75rem;
		border: 2px dashed #e5e7eb;
	}

	.spinner {
		width: 2rem;
		height: 2rem;
		border: 3px solid #e5e7eb;
		border-top-color: #3b82f6;
		border-radius: 50%;
		animation: spin 0.8s linear infinite;
	}

	@keyframes spin {
		to {
			transform: rotate(360deg);
		}
	}

	.empty-icon {
		font-size: 3rem;
		margin-bottom: 1rem;
	}

	.empty-state h2 {
		margin: 0 0 0.5rem;
		font-size: 1.25rem;
		color: #1f2937;
	}

	.empty-state p {
		margin: 0 0 1.5rem;
		color: #6b7280;
	}

	/* Table */
	.students-table-container {
		background: white;
		border: 1px solid #e5e7eb;
		border-radius: 0.75rem;
		overflow-x: auto;
	}

	.students-table {
		width: 100%;
		border-collapse: collapse;
	}

	.students-table th {
		text-align: left;
		padding: 0.75rem 1rem;
		font-size: 0.75rem;
		font-weight: 600;
		color: #6b7280;
		text-transform: uppercase;
		letter-spacing: 0.05em;
		border-bottom: 1px solid #e5e7eb;
		background: #f9fafb;
	}

	.students-table td {
		padding: 0.75rem 1rem;
		font-size: 0.875rem;
		color: #374151;
		border-bottom: 1px solid #f3f4f6;
	}

	.students-table tr:last-child td {
		border-bottom: none;
	}

	.clickable-row {
		cursor: pointer;
	}

	.clickable-row:hover td {
		background: #f9fafb;
	}

	.student-name-cell {
		white-space: nowrap;
	}

	.student-fullname {
		font-weight: 500;
		color: #1f2937;
	}

	.class-badge {
		display: inline-block;
		padding: 0.125rem 0.5rem;
		background: #eff6ff;
		color: #3b82f6;
		border-radius: 9999px;
		font-size: 0.75rem;
		font-weight: 500;
	}

	.no-class {
		color: #9ca3af;
		font-style: italic;
		font-size: 0.8125rem;
	}

	.actions-cell {
		white-space: nowrap;
	}

	/* Badges */
	.status-badge {
		display: inline-block;
		padding: 0.125rem 0.5rem;
		border-radius: 9999px;
		font-size: 0.75rem;
		font-weight: 500;
	}

	.status-active {
		background: #f0fdf4;
		color: #16a34a;
	}

	.status-pending {
		background: #fffbeb;
		color: #d97706;
	}

	.status-inscrit {
		background: #eff6ff;
		color: #3b82f6;
	}

	.status-blocked {
		background: #fef2f2;
		color: #dc2626;
	}

	/* Modal */
	.modal-overlay {
		position: fixed;
		inset: 0;
		background: rgba(0, 0, 0, 0.5);
		display: flex;
		align-items: center;
		justify-content: center;
		padding: 1rem;
		z-index: 100;
	}

	.modal {
		background: white;
		border-radius: 0.75rem;
		width: 100%;
		max-width: 32rem;
		max-height: 90vh;
		overflow: auto;
		box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
	}

	.modal-header {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 1.25rem 1.5rem;
		border-bottom: 1px solid #e5e7eb;
	}

	.modal-header h2 {
		margin: 0;
		font-size: 1.125rem;
		font-weight: 600;
		color: #1f2937;
	}

	.modal-close {
		padding: 0.25rem 0.5rem;
		background: none;
		border: none;
		font-size: 1.5rem;
		line-height: 1;
		color: #6b7280;
		cursor: pointer;
	}

	.modal-close:hover {
		color: #1f2937;
	}

	.modal-body {
		padding: 1.5rem;
	}

	.form-row {
		display: grid;
		grid-template-columns: 1fr;
		gap: 1rem;
		align-items: end;
	}

	.form-group {
		margin-bottom: 1.25rem;
	}

	.form-group label {
		display: block;
		margin-bottom: 0.5rem;
		font-weight: 500;
		color: #374151;
	}

	.form-group input,
	.form-group select {
		width: 100%;
		padding: 0.75rem 1rem;
		border: 1px solid #d1d5db;
		border-radius: 0.375rem;
		font-size: 1rem;
		transition: border-color 0.2s;
		background: white;
	}

	.form-group input:focus,
	.form-group select:focus {
		outline: none;
		border-color: #3b82f6;
		box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
	}

	.field-optional {
		font-weight: 400;
		color: #9ca3af;
		font-size: 0.875rem;
	}

	.field-hint {
		display: block;
		margin-top: 0.25rem;
		font-size: 0.8125rem;
		color: #9ca3af;
	}

	.consent-notice {
		padding: 0.75rem;
		background: #fef3c7;
		border: 1px solid #fcd34d;
		border-radius: 0.5rem;
	}

	.consent-label {
		display: flex;
		align-items: center;
		gap: 0.5rem;
		font-weight: 500;
		color: #92400e;
		cursor: pointer;
	}

	.consent-label input[type='checkbox'] {
		width: 1rem;
		height: 1rem;
		accent-color: #f59e0b;
	}

	.consent-notice .field-hint {
		margin-left: 1.5rem;
		color: #92400e;
	}

	.field-error {
		display: block;
		margin-top: 0.25rem;
		font-size: 0.8125rem;
		color: #dc2626;
	}

	.duplicate-warning {
		padding: 0.75rem 1rem;
		background: #fffbeb;
		border: 1px solid #fde68a;
		border-radius: 0.375rem;
		font-size: 0.875rem;
		color: #92400e;
		margin-bottom: 1.25rem;
	}

	.duplicate-warning p {
		margin: 0 0 0.75rem;
	}

	.duplicate-actions {
		display: flex;
		gap: 0.5rem;
		justify-content: flex-end;
	}

	.modal-error {
		margin-bottom: 0;
	}

	.change-confirm-info {
		padding: 0.75rem 1rem;
		background: #eff6ff;
		border-radius: 0.375rem;
		font-size: 0.875rem;
		color: #3b82f6;
		margin-bottom: 1.25rem;
	}

	.modal-actions {
		display: flex;
		justify-content: space-between;
		align-items: center;
		gap: 0.75rem;
		padding-top: 1rem;
		border-top: 1px solid #e5e7eb;
	}

	.modal-actions-buttons {
		display: flex;
		gap: 0.75rem;
	}

	.create-another-label {
		display: flex;
		align-items: center;
		gap: 0.5rem;
		font-size: 0.875rem;
		color: #6b7280;
		cursor: pointer;
	}

	.create-another-label input[type='checkbox'] {
		width: 1rem;
		height: 1rem;
		accent-color: #3b82f6;
	}

	.modal-confirm .modal-actions {
		justify-content: flex-end;
	}

	@media (min-width: 768px) {
		.filters-bar {
			flex-direction: row;
			align-items: flex-end;
		}

		.filter-group select {
			min-width: 200px;
			width: auto;
		}

		.form-row {
			grid-template-columns: 1fr 1fr;
		}
	}

	@media (max-width: 767px) {
		.students-table-container {
			background: transparent;
			border: none;
		}

		.students-table thead {
			display: none;
		}

		.students-table tbody tr {
			display: block;
			background: white;
			border: 1px solid #e5e7eb;
			border-radius: 0.75rem;
			margin-bottom: 0.75rem;
			padding: 0.25rem 0;
		}

		.clickable-row:hover td {
			background: transparent;
		}

		.students-table td {
			display: flex;
			justify-content: space-between;
			align-items: baseline;
			padding: 0.5rem 1rem;
			border-bottom: none;
			text-align: right;
		}

		.students-table td::before {
			content: attr(data-label);
			font-weight: 600;
			font-size: 0.75rem;
			color: #6b7280;
			text-transform: uppercase;
			letter-spacing: 0.05em;
			text-align: left;
			margin-right: 1rem;
			flex-shrink: 0;
		}

		.student-name-cell {
			white-space: normal;
		}

		.actions-cell {
			justify-content: flex-end;
			flex-wrap: wrap;
			padding-top: 0.75rem;
			border-top: 1px solid #f3f4f6;
		}
	}
</style>
