<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 Pagination from '$lib/components/molecules/Pagination/Pagination.svelte';
	import SearchInput from '$lib/components/molecules/SearchInput/SearchInput.svelte';
	import { untrack } from 'svelte';

	// Types
	interface Subject {
		id: string;
		name: string;
		code: string;
		color: string | null;
		description: string | null;
		status: string;
		teacherCount: number | null;
		classCount: number | null;
		createdAt: string;
		updatedAt: string;
	}

	// Couleurs prédéfinies (suggestions UI)
	const SUGGESTED_COLORS = [
		{ label: 'Bleu (Mathématiques)', value: '#3B82F6' },
		{ label: 'Rouge (Français)', value: '#EF4444' },
		{ label: 'Orange (Histoire-Géo)', value: '#F59E0B' },
		{ label: 'Vert (Sciences)', value: '#10B981' },
		{ label: 'Indigo (Anglais)', value: '#6366F1' },
		{ label: 'Rose (EPS)', value: '#EC4899' },
		{ label: 'Violet (Arts)', value: '#8B5CF6' },
		{ label: 'Gris (Autre)', value: '#6B7280' }
	];

	// State
	let subjects = $state<Subject[]>([]);
	let isLoading = $state(true);
	let error = $state<string | null>(null);
	let showCreateModal = $state(false);
	let showDeleteModal = $state(false);
	let subjectToDelete = $state<Subject | null>(null);

	// 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));

	// Form state
	let newSubjectName = $state('');
	let newSubjectCode = $state('');
	let newSubjectColor = $state<string | null>(null);
	let isSubmitting = $state(false);
	let isDeleting = $state(false);

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

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

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

		try {
			isLoading = true;
			error = null;
			const apiUrl = getApiBaseUrl();
			const params = new URLSearchParams();
			params.set('page', String(currentPage));
			params.set('itemsPerPage', String(itemsPerPage));
			if (searchTerm) params.set('search', searchTerm);
			const url = `${apiUrl}/subjects?${params.toString()}`;
			const response = await authenticatedFetch(url, { signal: controller.signal });

			if (controller.signal.aborted) return;

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

			const data = await response.json();
			subjects = data['hydra:member'] ?? data['member'] ?? (Array.isArray(data) ? data : []);
			totalItems = data['hydra:totalItems'] ?? data['totalItems'] ?? subjects.length;
		} catch (e) {
			if (e instanceof DOMException && e.name === 'AbortError') return;
			error = e instanceof Error ? e.message : 'Erreur inconnue';
			subjects = [];
			totalItems = 0;
		} finally {
			if (!controller.signal.aborted) {
				isLoading = false;
			}
		}
	}

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

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

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

	async function handleCreateSubject() {
		if (!newSubjectName.trim() || !newSubjectCode.trim()) return;

		try {
			isSubmitting = true;
			const apiUrl = getApiBaseUrl();
			const response = await authenticatedFetch(`${apiUrl}/subjects`, {
				method: 'POST',
				headers: {
					'Content-Type': 'application/json'
				},
				body: JSON.stringify({
					name: newSubjectName.trim(),
					code: newSubjectCode.trim().toUpperCase(),
					color: newSubjectColor
				})
			});

			if (!response.ok) {
				let errorMessage = `Erreur lors de la création (${response.status})`;
				try {
					const errorData = await response.json();
					if (errorData['hydra:description']) {
						errorMessage = errorData['hydra:description'];
					} else if (errorData.message) {
						errorMessage = errorData.message;
					} else if (errorData.detail) {
						errorMessage = errorData.detail;
					}
				} catch {
					// JSON parsing failed, keep default message
				}
				throw new Error(errorMessage);
			}

			// Reload subjects and close modal
			await loadSubjects();
			closeModal();
		} catch (e) {
			error = e instanceof Error ? e.message : 'Erreur lors de la création';
		} finally {
			isSubmitting = false;
		}
	}

	function openDeleteModal(subject: Subject) {
		subjectToDelete = subject;
		showDeleteModal = true;
	}

	function closeDeleteModal() {
		showDeleteModal = false;
		subjectToDelete = null;
	}

	async function handleConfirmDelete() {
		if (!subjectToDelete) return;

		try {
			isDeleting = true;
			const apiUrl = getApiBaseUrl();
			const response = await authenticatedFetch(`${apiUrl}/subjects/${subjectToDelete.id}`, {
				method: 'DELETE'
			});

			if (!response.ok) {
				let errorMessage = `Erreur lors de la suppression (${response.status})`;
				try {
					const errorData = await response.json();
					if (errorData['hydra:description']) {
						errorMessage = errorData['hydra:description'];
					} else if (errorData.message) {
						errorMessage = errorData.message;
					} else if (errorData.detail) {
						errorMessage = errorData.detail;
					}
				} catch {
					// JSON parsing failed, keep default message
				}
				throw new Error(errorMessage);
			}

			closeDeleteModal();
			await loadSubjects();
		} catch (e) {
			error = e instanceof Error ? e.message : 'Erreur lors de la suppression';
		} finally {
			isDeleting = false;
		}
	}

	function openCreateModal() {
		showCreateModal = true;
		newSubjectName = '';
		newSubjectCode = '';
		newSubjectColor = null;
	}

	function closeModal() {
		showCreateModal = false;
	}

	function navigateToEdit(subjectId: string) {
		goto(`/admin/subjects/${subjectId}`);
	}

	function getColorStyle(color: string | null): string {
		if (!color) return '';
		return `background-color: ${color}; color: ${getContrastColor(color)}`;
	}

	function getContrastColor(hexColor: string): string {
		// Simple luminance check for contrast
		const r = parseInt(hexColor.slice(1, 3), 16);
		const g = parseInt(hexColor.slice(3, 5), 16);
		const b = parseInt(hexColor.slice(5, 7), 16);
		const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
		return luminance > 0.5 ? '#000000' : '#FFFFFF';
	}
</script>

<svelte:head>
	<title>Gestion des matières - Classeo</title>
</svelte:head>

<div class="subjects-page">
	<header class="page-header">
		<div class="header-content">
			<h1>Gestion des matières</h1>
			<p class="subtitle">Créez et gérez les matières enseignées dans votre établissement</p>
		</div>
		<button class="btn-primary" onclick={openCreateModal}>
			<span class="btn-icon">+</span>
			Nouvelle matière
		</button>
	</header>

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

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

	{#if isLoading}
		<div class="loading-state" aria-live="polite" role="status">
			<div class="spinner"></div>
			<p>Chargement des matières...</p>
		</div>
	{:else if subjects.length === 0}
		<div class="empty-state">
			<span class="empty-icon">📚</span>
			{#if searchTerm}
				<h2>Aucun résultat</h2>
				<p>Aucune matière ne correspond à votre recherche</p>
				<button class="btn-secondary" onclick={() => handleSearch('')}>Effacer la recherche</button>
			{:else}
				<h2>Aucune matière</h2>
				<p>Commencez par créer votre première matière</p>
				<button class="btn-primary" onclick={openCreateModal}>Créer une matière</button>
			{/if}
		</div>
	{:else}
		<div class="subjects-grid">
			{#each subjects as subject (subject.id)}
				<div class="subject-card">
					<div class="subject-header">
						{#if subject.color}
							<span class="subject-color-badge" style={getColorStyle(subject.color)}>
								{subject.code}
							</span>
						{:else}
							<span class="subject-code">{subject.code}</span>
						{/if}
						<h3 class="subject-name">{subject.name}</h3>
					</div>

					<div class="subject-stats">
						<span class="stat-item" title="Enseignants affectés">
							<span class="stat-icon">👨‍🏫</span>
							{subject.teacherCount ?? 0}
						</span>
						<span class="stat-item" title="Classes associées">
							<span class="stat-icon">🏫</span>
							{subject.classCount ?? 0}
						</span>
						<span class="stat-item status-{subject.status}">
							{subject.status === 'active' ? 'Active' : 'Archivée'}
						</span>
					</div>

					<div class="subject-actions">
						<button class="btn-secondary btn-sm" onclick={() => navigateToEdit(subject.id)}>
							Modifier
						</button>
						<button class="btn-danger btn-sm" onclick={() => openDeleteModal(subject)}>
							Supprimer
						</button>
					</div>
				</div>
			{/each}
		</div>
		<Pagination {currentPage} {totalPages} onPageChange={handlePageChange} />
	{/if}
</div>

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

			<form
				class="modal-body"
				onsubmit={(e) => {
					e.preventDefault();
					handleCreateSubject();
				}}
			>
				<div class="form-group">
					<label for="subject-name">Nom de la matière *</label>
					<input
						type="text"
						id="subject-name"
						bind:value={newSubjectName}
						placeholder="ex: Mathématiques"
						required
						minlength="2"
						maxlength="100"
					/>
				</div>

				<div class="form-group">
					<label for="subject-code">Code court *</label>
					<input
						type="text"
						id="subject-code"
						bind:value={newSubjectCode}
						placeholder="ex: MATH"
						required
						minlength="2"
						maxlength="10"
					/>
					<small class="form-hint">2 à 10 caractères (lettres et chiffres uniquement)</small>
				</div>

				<div class="form-group">
					<label for="subject-color">Couleur</label>
					<div class="color-picker-group">
						<div class="color-swatches">
							{#each SUGGESTED_COLORS as colorOption}
								<button
									type="button"
									class="color-swatch"
									class:selected={newSubjectColor === colorOption.value}
									style="background-color: {colorOption.value}"
									onclick={() => (newSubjectColor = colorOption.value)}
									title={colorOption.label}
								></button>
							{/each}
							<button
								type="button"
								class="color-swatch color-none"
								class:selected={newSubjectColor === null}
								onclick={() => (newSubjectColor = null)}
								title="Aucune couleur"
							>
								∅
							</button>
						</div>
						<input
							type="color"
							id="subject-color"
							value={newSubjectColor ?? '#6B7280'}
							onchange={(e) => (newSubjectColor = e.currentTarget.value)}
						/>
					</div>
				</div>

				<div class="modal-actions">
					<button type="button" class="btn-secondary" onclick={closeModal} disabled={isSubmitting}>
						Annuler
					</button>
					<button
						type="submit"
						class="btn-primary"
						disabled={isSubmitting || !newSubjectName.trim() || !newSubjectCode.trim()}
					>
						{#if isSubmitting}
							Création...
						{:else}
							Créer la matière
						{/if}
					</button>
				</div>
			</form>
		</div>
	</div>
{/if}

<!-- Delete Confirmation Modal -->
{#if showDeleteModal && subjectToDelete}
	<!-- svelte-ignore a11y_no_static_element_interactions -->
	<div class="modal-overlay" onclick={closeDeleteModal} role="presentation">
		<div
			class="modal modal-confirm"
			role="alertdialog"
			aria-modal="true"
			aria-labelledby="delete-modal-title"
			aria-describedby="delete-modal-description"
			tabindex="-1"
			onclick={(e) => e.stopPropagation()}
			onkeydown={(e) => { if (e.key === 'Escape') closeDeleteModal(); }}
		>
			<header class="modal-header modal-header-danger">
				<h2 id="delete-modal-title">Supprimer la matière</h2>
				<button class="modal-close" onclick={closeDeleteModal} aria-label="Fermer">×</button>
			</header>

			<div class="modal-body">
				<p id="delete-modal-description">
					Êtes-vous sûr de vouloir supprimer la matière <strong>{subjectToDelete.name}</strong> ({subjectToDelete.code})
					?
				</p>
				<p class="delete-warning">Cette action est irréversible.</p>
			</div>

			<div class="modal-actions">
				<button
					type="button"
					class="btn-secondary"
					onclick={closeDeleteModal}
					disabled={isDeleting}
				>
					Annuler
				</button>
				<button type="button" class="btn-danger" onclick={handleConfirmDelete} disabled={isDeleting}>
					{#if isDeleting}
						Suppression...
					{:else}
						Supprimer
					{/if}
				</button>
			</div>
		</div>
	</div>
{/if}

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

	.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-danger {
		padding: 0.5rem 1rem;
		background: #fef2f2;
		color: #dc2626;
		border: 1px solid #fecaca;
		border-radius: 0.375rem;
		font-weight: 500;
		cursor: pointer;
		transition: all 0.2s;
	}

	.btn-danger:hover {
		background: #fee2e2;
	}

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

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

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

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

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

	.subjects-grid {
		display: grid;
		grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
		gap: 1rem;
	}

	.subject-card {
		display: flex;
		flex-direction: column;
		gap: 1rem;
		padding: 1.25rem;
		background: white;
		border: 1px solid #e5e7eb;
		border-radius: 0.75rem;
		transition: box-shadow 0.2s;
	}

	.subject-card:hover {
		box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
	}

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

	.subject-name {
		margin: 0;
		font-size: 1.125rem;
		font-weight: 600;
		color: #1f2937;
	}

	.subject-code {
		padding: 0.25rem 0.5rem;
		background: #f3f4f6;
		color: #374151;
		border-radius: 0.25rem;
		font-size: 0.75rem;
		font-weight: 600;
		font-family: monospace;
	}

	.subject-color-badge {
		padding: 0.25rem 0.5rem;
		border-radius: 0.25rem;
		font-size: 0.75rem;
		font-weight: 600;
		font-family: monospace;
	}

	.subject-stats {
		display: flex;
		gap: 1rem;
		flex-wrap: wrap;
	}

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

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

	.status-active {
		color: #059669;
	}

	.status-archived {
		color: #6b7280;
	}

	.subject-actions {
		display: flex;
		gap: 0.5rem;
		margin-top: auto;
	}

	/* 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: 28rem;
		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-group {
		margin-bottom: 1.25rem;
	}

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

	.form-group input[type='text'] {
		width: 100%;
		padding: 0.75rem 1rem;
		border: 1px solid #d1d5db;
		border-radius: 0.375rem;
		font-size: 1rem;
		transition: border-color 0.2s;
	}

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

	.form-hint {
		display: block;
		margin-top: 0.25rem;
		font-size: 0.75rem;
		color: #6b7280;
	}

	.color-picker-group {
		display: flex;
		align-items: center;
		gap: 1rem;
	}

	.color-swatches {
		display: flex;
		gap: 0.5rem;
		flex-wrap: wrap;
	}

	.color-swatch {
		width: 2rem;
		height: 2rem;
		border: 2px solid transparent;
		border-radius: 0.375rem;
		cursor: pointer;
		transition: all 0.2s;
	}

	.color-swatch:hover {
		transform: scale(1.1);
	}

	.color-swatch.selected {
		border-color: #1f2937;
		box-shadow: 0 0 0 2px white, 0 0 0 4px #3b82f6;
	}

	.color-none {
		background: #f3f4f6;
		color: #6b7280;
		font-size: 0.875rem;
		font-weight: bold;
	}

	input[type='color'] {
		width: 3rem;
		height: 2rem;
		padding: 0;
		border: 1px solid #d1d5db;
		border-radius: 0.375rem;
		cursor: pointer;
	}

	.modal-actions {
		display: flex;
		justify-content: flex-end;
		gap: 0.75rem;
		padding-top: 1rem;
		border-top: 1px solid #e5e7eb;
	}

	/* Delete confirmation modal */
	.modal-confirm {
		max-width: 24rem;
	}

	.modal-confirm .modal-actions {
		padding: 1rem 1.5rem;
		border-top: 1px solid #e5e7eb;
	}

	.modal-header-danger {
		background: #fef2f2;
		border-bottom-color: #fecaca;
	}

	.modal-header-danger h2 {
		color: #dc2626;
	}

	.delete-warning {
		margin: 0.75rem 0 0;
		font-size: 0.875rem;
		color: #6b7280;
	}
</style>
