<script lang="ts">
	import { goto } from '$app/navigation';
	import { page } from '$app/state';
	import { getApiBaseUrl } from '$lib/api/config';
	import { authenticatedFetch } from '$lib/auth';
	import { untrack } from 'svelte';

	interface HomeworkException {
		id: string;
		homeworkId: string;
		homeworkTitle: string;
		ruleType: string;
		justification: string;
		teacherId: string;
		teacherName: string;
		createdAt: string;
	}

	let exceptions = $state<HomeworkException[]>([]);
	let isLoading = $state(true);
	let error = $state<string | null>(null);

	let filterTeacherId = $state(page.url.searchParams.get('teacherId') ?? '');
	let filterRuleType = $state(page.url.searchParams.get('ruleType') ?? '');
	let filterStartDate = $state(page.url.searchParams.get('startDate') ?? '');
	let filterEndDate = $state(page.url.searchParams.get('endDate') ?? '');

	$effect(() => {
		untrack(() => loadExceptions());
	});

	function extractCollection<T>(data: Record<string, unknown>): T[] {
		const members = data['hydra:member'] ?? data['member'];
		if (Array.isArray(members)) return members as T[];
		if (Array.isArray(data)) return data as T[];
		return [];
	}

	async function loadExceptions() {
		try {
			isLoading = true;
			error = null;
			const apiUrl = getApiBaseUrl();
			const params = new URLSearchParams();
			if (filterStartDate) params.set('startDate', filterStartDate);
			if (filterEndDate) params.set('endDate', filterEndDate);
			if (filterTeacherId) params.set('teacherId', filterTeacherId);
			if (filterRuleType) params.set('ruleType', filterRuleType);

			const response = await authenticatedFetch(`${apiUrl}/admin/homework-exceptions?${params.toString()}`);

			if (!response.ok) {
				throw new Error('Erreur lors du chargement des exceptions');
			}

			const data = await response.json();
			exceptions = extractCollection<HomeworkException>(data);
		} catch (e) {
			error = e instanceof Error ? e.message : 'Erreur inconnue';
		} finally {
			isLoading = false;
		}
	}

	function updateUrl() {
		const params = new URLSearchParams();
		if (filterStartDate) params.set('startDate', filterStartDate);
		if (filterEndDate) params.set('endDate', filterEndDate);
		if (filterTeacherId) params.set('teacherId', filterTeacherId);
		if (filterRuleType) params.set('ruleType', filterRuleType);
		const query = params.toString();
		goto(`?${query}`, { replaceState: true, noScroll: true, keepFocus: true });
	}

	function handleFilter() {
		updateUrl();
		loadExceptions();
	}

	function handleClearFilters() {
		filterStartDate = '';
		filterEndDate = '';
		filterTeacherId = '';
		filterRuleType = '';
		updateUrl();
		loadExceptions();
	}

	function formatDate(dateStr: string): string {
		return new Date(dateStr).toLocaleDateString('fr-FR', {
			day: 'numeric',
			month: 'long',
			year: 'numeric',
			hour: '2-digit',
			minute: '2-digit',
		});
	}

	function formatRuleType(ruleType: string): string {
		const labels: Record<string, string> = {
			minimum_delay: 'Délai minimum',
			no_monday_after: 'Pas de lundi après',
		};
		return ruleType
			.split(',')
			.map((t) => labels[t] ?? t)
			.join(', ');
	}

	// Derive unique teachers from loaded exceptions for the filter dropdown
	let uniqueTeachers = $derived.by(() => {
		const seen = new Map<string, string>();
		for (const ex of exceptions) {
			if (!seen.has(ex.teacherId)) {
				seen.set(ex.teacherId, ex.teacherName);
			}
		}
		return [...seen.entries()].map(([id, name]) => ({ id, name }));
	});

	let hasFilters = $derived(
		filterStartDate !== '' || filterEndDate !== '' || filterTeacherId !== '' || filterRuleType !== '',
	);
</script>

<svelte:head>
	<title>Exceptions aux règles de devoirs - Classeo</title>
</svelte:head>

<div class="exceptions-page">
	<header class="page-header">
		<div class="header-content">
			<h1>Exceptions aux règles de devoirs</h1>
			<p class="subtitle">Rapport des contournements de règles par les enseignants</p>
		</div>
	</header>

	{#if error}
		<div class="alert alert-error">
			<span class="alert-icon">&#9888;</span>
			{error}
			<button class="alert-close" onclick={() => (error = null)}>&times;</button>
		</div>
	{/if}

	<div class="filters-section">
		<div class="filters-row">
			<div class="filter-group">
				<label for="filter-start">Du</label>
				<input
					type="date"
					id="filter-start"
					bind:value={filterStartDate}
					onchange={handleFilter}
				/>
			</div>
			<div class="filter-group">
				<label for="filter-end">Au</label>
				<input
					type="date"
					id="filter-end"
					bind:value={filterEndDate}
					onchange={handleFilter}
				/>
			</div>
			<div class="filter-group">
				<label for="filter-teacher">Enseignant</label>
				<select id="filter-teacher" bind:value={filterTeacherId} onchange={handleFilter}>
					<option value="">Tous les enseignants</option>
					{#each uniqueTeachers as teacher (teacher.id)}
						<option value={teacher.id}>{teacher.name}</option>
					{/each}
				</select>
			</div>
			<div class="filter-group">
				<label for="filter-rule">Règle</label>
				<select id="filter-rule" bind:value={filterRuleType} onchange={handleFilter}>
					<option value="">Toutes les règles</option>
					<option value="minimum_delay">Délai minimum</option>
					<option value="no_monday_after">Pas de lundi après</option>
				</select>
			</div>
			{#if hasFilters}
				<button class="btn-clear" onclick={handleClearFilters}>Effacer les filtres</button>
			{/if}
		</div>
	</div>

	{#if isLoading}
		<div class="loading-state" aria-live="polite" role="status">
			<div class="spinner"></div>
			<p>Chargement des exceptions...</p>
		</div>
	{:else if exceptions.length === 0}
		<div class="empty-state">
			<span class="empty-icon">&#9989;</span>
			<h2>Aucune exception</h2>
			<p>
				{#if hasFilters}
					Aucune exception ne correspond à vos critères de recherche.
				{:else}
					Aucun enseignant n'a demandé d'exception aux règles de devoirs.
				{/if}
			</p>
		</div>
	{:else}
		<div class="results-summary">
			{exceptions.length} exception{exceptions.length > 1 ? 's' : ''} trouvée{exceptions.length > 1 ? 's' : ''}
		</div>
		<div class="exceptions-list">
			{#each exceptions as ex (ex.id)}
				<div class="exception-card">
					<div class="exception-header">
						<h3 class="exception-homework">{ex.homeworkTitle}</h3>
						<span class="exception-rule">{formatRuleType(ex.ruleType)}</span>
					</div>
					<div class="exception-meta">
						<span class="meta-item" title="Enseignant">
							<span class="meta-icon">&#128100;</span>
							{ex.teacherName}
						</span>
						<span class="meta-item" title="Date de l'exception">
							<span class="meta-icon">&#128197;</span>
							{formatDate(ex.createdAt)}
						</span>
					</div>
					<div class="exception-justification">
						<span class="justification-label">Justification :</span>
						<p class="justification-text">{ex.justification}</p>
					</div>
				</div>
			{/each}
		</div>
	{/if}
</div>

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

	.page-header {
		margin-bottom: 1.5rem;
	}

	.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;
	}

	.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-icon {
		flex-shrink: 0;
	}

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

	.filters-section {
		background: white;
		border: 1px solid #e5e7eb;
		border-radius: 0.75rem;
		padding: 1rem 1.5rem;
		margin-bottom: 1.5rem;
	}

	.filters-row {
		display: flex;
		gap: 1rem;
		align-items: flex-end;
		flex-wrap: wrap;
	}

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

	.filter-group label {
		font-size: 0.75rem;
		font-weight: 600;
		color: #6b7280;
		text-transform: uppercase;
	}

	.filter-group input,
	.filter-group select {
		padding: 0.5rem 0.75rem;
		border: 1px solid #d1d5db;
		border-radius: 0.375rem;
		font-size: 0.875rem;
	}

	.btn-clear {
		padding: 0.5rem 1rem;
		background: #f3f4f6;
		color: #374151;
		border: 1px solid #d1d5db;
		border-radius: 0.375rem;
		font-size: 0.875rem;
		cursor: pointer;
	}

	.btn-clear:hover {
		background: #e5e7eb;
	}

	.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;
		color: #6b7280;
	}

	.results-summary {
		margin-bottom: 1rem;
		font-size: 0.875rem;
		color: #6b7280;
	}

	.exceptions-list {
		display: flex;
		flex-direction: column;
		gap: 1rem;
	}

	.exception-card {
		padding: 1.25rem;
		background: white;
		border: 1px solid #e5e7eb;
		border-radius: 0.75rem;
		border-left: 4px solid #f59e0b;
	}

	.exception-header {
		display: flex;
		justify-content: space-between;
		align-items: flex-start;
		gap: 0.75rem;
		margin-bottom: 0.75rem;
	}

	.exception-homework {
		margin: 0;
		font-size: 1rem;
		font-weight: 600;
		color: #1f2937;
	}

	.exception-rule {
		flex-shrink: 0;
		padding: 0.125rem 0.5rem;
		background: #fffbeb;
		color: #92400e;
		border: 1px solid #fde68a;
		border-radius: 9999px;
		font-size: 0.75rem;
		font-weight: 600;
	}

	.exception-meta {
		display: flex;
		gap: 1.25rem;
		flex-wrap: wrap;
		margin-bottom: 0.75rem;
	}

	.meta-item {
		display: flex;
		align-items: center;
		gap: 0.25rem;
		font-size: 0.875rem;
		color: #6b7280;
	}

	.meta-icon {
		font-size: 0.875rem;
	}

	.exception-justification {
		background: #f9fafb;
		border-radius: 0.375rem;
		padding: 0.75rem 1rem;
	}

	.justification-label {
		font-size: 0.75rem;
		font-weight: 600;
		color: #6b7280;
		text-transform: uppercase;
	}

	.justification-text {
		margin: 0.25rem 0 0;
		font-size: 0.875rem;
		color: #374151;
		line-height: 1.5;
	}
</style>
