<script lang="ts">
	import { getApiBaseUrl } from '$lib/api/config';
	import { authenticatedFetch } from '$lib/auth';

	// Types
	interface Period {
		sequence: number;
		label: string;
		startDate: string;
		endDate: string;
		isCurrent: boolean;
		daysRemaining: number;
		isPast: boolean;
	}

	interface PeriodsConfig {
		type: string;
		periods: Period[];
		currentPeriod: Period | null;
	}

	// State
	let config = $state<PeriodsConfig | null>(null);
	let isLoading = $state(true);
	let error = $state<string | null>(null);
	let isSubmitting = $state(false);
	let showConfigureModal = $state(false);
	let showEditModal = $state(false);
	let showImpactWarning = $state(false);

	// Configure form state
	let selectedType = $state<string>('trimester');

	// Edit form state
	let editingPeriod = $state<Period | null>(null);
	let editStartDate = $state('');
	let editEndDate = $state('');

	// Academic year selector
	type YearKey = 'previous' | 'current' | 'next';
	const yearOptions: { key: YearKey; offset: number }[] = [
		{ key: 'previous', offset: -1 },
		{ key: 'current', offset: 0 },
		{ key: 'next', offset: 1 }
	];
	let selectedYear = $state<YearKey>('current');
	let academicYearId = $derived(selectedYear);

	function baseStartYear(): number {
		const now = new Date();
		return now.getMonth() >= 8 ? now.getFullYear() : now.getFullYear() - 1;
	}

	function schoolYearLabel(offset: number): string {
		const sy = baseStartYear() + offset;
		return `${sy}-${sy + 1}`;
	}

	let startYear = $derived(
		baseStartYear() + ({ previous: -1, current: 0, next: 1 })[selectedYear]
	);

	// Derived
	let hasConfig = $derived(config !== null && config.periods.length > 0);

	// Close modals on Escape key
	$effect(() => {
		if (!showConfigureModal && !showEditModal) return;
		const onKeydown = (e: globalThis.KeyboardEvent) => {
			if (e.key === 'Escape') {
				showConfigureModal = false;
				if (showEditModal) closeEditModal();
			}
		};
		document.addEventListener('keydown', onKeydown);
		return () => document.removeEventListener('keydown', onKeydown);
	});

	// Reload when year changes
	$effect(() => {
		void selectedYear; // Track dependency to re-run on change
		loadPeriods();
	});

	async function loadPeriods() {
		try {
			isLoading = true;
			error = null;
			const apiUrl = getApiBaseUrl();
			const response = await authenticatedFetch(
				`${apiUrl}/academic-years/${academicYearId}/periods`
			);

			if (response.status === 404 || response.status === 204) {
				config = null;
				return;
			}

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

			const data = await response.json();
			config = data;
		} catch (e) {
			error = e instanceof Error ? e.message : 'Erreur inconnue';
			config = null;
		} finally {
			isLoading = false;
		}
	}

	async function handleConfigure() {
		try {
			isSubmitting = true;
			error = null;
			const apiUrl = getApiBaseUrl();
			const response = await authenticatedFetch(
				`${apiUrl}/academic-years/${academicYearId}/periods`,
				{
					method: 'PUT',
					headers: { 'Content-Type': 'application/json' },
					body: JSON.stringify({
						periodType: selectedType,
						startYear
					})
				}
			);

			if (!response.ok) {
				const errorData = await response.json();
				throw new Error(
					errorData['hydra:description'] || errorData.message || 'Erreur lors de la configuration'
				);
			}

			await loadPeriods();
			showConfigureModal = false;
		} catch (e) {
			error = e instanceof Error ? e.message : 'Erreur inconnue';
		} finally {
			isSubmitting = false;
		}
	}

	function openEditModal(period: Period) {
		editingPeriod = period;
		editStartDate = period.startDate;
		editEndDate = period.endDate;
		showImpactWarning = false;
		showEditModal = true;
	}

	function closeEditModal() {
		showEditModal = false;
		editingPeriod = null;
	}

	async function handleUpdatePeriod(confirmImpact = false) {
		if (!editingPeriod) return;

		try {
			isSubmitting = true;
			error = null;
			const apiUrl = getApiBaseUrl();
			const response = await authenticatedFetch(
				`${apiUrl}/academic-years/${academicYearId}/periods/${editingPeriod.sequence}`,
				{
					method: 'PATCH',
					headers: { 'Content-Type': 'application/merge-patch+json' },
					body: JSON.stringify({
						startDate: editStartDate,
						endDate: editEndDate,
						confirmImpact
					})
				}
			);

			if (response.status === 409) {
				// Période avec notes : afficher l'avertissement
				showImpactWarning = true;
				return;
			}

			if (!response.ok) {
				const errorData = await response.json();
				throw new Error(
					errorData['hydra:description'] || errorData.message || 'Erreur lors de la modification'
				);
			}

			await loadPeriods();
			closeEditModal();
		} catch (e) {
			error = e instanceof Error ? e.message : 'Erreur inconnue';
		} finally {
			isSubmitting = false;
		}
	}

	function formatDate(dateString: string): string {
		const [y, m, d] = dateString.split('-');
		return new Date(Number(y), Number(m) - 1, Number(d)).toLocaleDateString('fr-FR', {
			day: 'numeric',
			month: 'long',
			year: 'numeric'
		});
	}

	function lastDayOfFeb(year: number): number {
		return new Date(year, 2, 0).getDate();
	}

	function typeLabel(type: string): string {
		return type === 'trimester' ? 'Trimestres' : 'Semestres';
	}
</script>

<svelte:head>
	<title>Périodes scolaires - Classeo</title>
</svelte:head>

<div class="periods-page">
	<header class="page-header">
		<div class="header-content">
			<h1>Périodes scolaires</h1>
			<p class="subtitle">Configurez le découpage de l'année en trimestres ou semestres</p>
		</div>
		<div class="header-actions">
			<div class="year-selector" role="tablist" aria-label="Année scolaire">
				{#each yearOptions as { key, offset } (key)}
					<button
						role="tab"
						class="year-tab"
						class:year-tab-active={selectedYear === key}
						aria-selected={selectedYear === key}
						onclick={() => (selectedYear = key as YearKey)}
					>
						{schoolYearLabel(offset)}
					</button>
				{/each}
			</div>
		</div>
	</header>

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

	{#if isLoading}
		<div class="loading-state">
			<div class="spinner"></div>
			<p>Chargement des périodes...</p>
		</div>
	{:else if !hasConfig}
		<div class="empty-state">
			<span class="empty-icon">&#128197;</span>
			<h2>Aucune période configurée</h2>
			<p>Choisissez entre trimestres (3 périodes) ou semestres (2 périodes)</p>
			<button class="btn-primary" onclick={() => (showConfigureModal = true)}>
				Configurer les périodes
			</button>
		</div>
	{:else if config}
		<!-- Current period banner -->
		{#if config.currentPeriod}
			<div class="current-period-banner">
				<div class="banner-content">
					<span class="banner-label">Période actuelle</span>
					<span class="banner-period">{config.currentPeriod.label}</span>
				</div>
				<div class="banner-countdown">
					<span class="countdown-number">{config.currentPeriod.daysRemaining}</span>
					<span class="countdown-label">jours restants</span>
				</div>
			</div>
		{/if}

		<!-- Period type info -->
		<div class="config-info">
			<span class="config-badge">{typeLabel(config.type)}</span>
		</div>

		<!-- Periods list -->
		<div class="periods-list">
			{#each config.periods as period (period.sequence)}
				<div class="period-card" class:period-current={period.isCurrent} class:period-past={period.isPast}>
					<div class="period-header">
						<h3 class="period-label">{period.label}</h3>
						{#if period.isCurrent}
							<span class="badge badge-current">En cours</span>
						{:else if period.isPast}
							<span class="badge badge-past">Terminée</span>
						{:else}
							<span class="badge badge-future">A venir</span>
						{/if}
					</div>

					<div class="period-dates">
						<div class="date-item">
							<span class="date-label">Début</span>
							<span class="date-value">{formatDate(period.startDate)}</span>
						</div>
						<div class="date-item">
							<span class="date-label">Fin</span>
							<span class="date-value">{formatDate(period.endDate)}</span>
						</div>
					</div>

					{#if period.isCurrent}
						<div class="period-progress">
							<div class="progress-info">
								<span>{period.daysRemaining} jours restants</span>
							</div>
						</div>
					{/if}

					<div class="period-actions">
						<button class="btn-secondary btn-sm" onclick={() => openEditModal(period)}>
							Modifier les dates
						</button>
					</div>
				</div>
			{/each}
		</div>
	{/if}
</div>

<!-- Configure Modal -->
{#if showConfigureModal}
	<!-- svelte-ignore a11y_no_static_element_interactions -->
	<div class="modal-overlay" onclick={() => (showConfigureModal = false)} role="presentation">
		<div
			class="modal"
			role="dialog"
			aria-modal="true"
			aria-labelledby="configure-title"
			tabindex="-1"
			onclick={(e) => e.stopPropagation()}
			onkeydown={(e) => { if (e.key === 'Escape') showConfigureModal = false; }}
		>
			<header class="modal-header">
				<h2 id="configure-title">Configurer les périodes</h2>
				<button
					class="modal-close"
					onclick={() => (showConfigureModal = false)}
					aria-label="Fermer">x</button
				>
			</header>

			<form
				class="modal-body"
				onsubmit={(e) => {
					e.preventDefault();
					handleConfigure();
				}}
			>
				<div class="form-group">
					<label for="period-type">Mode de découpage *</label>
					<select id="period-type" bind:value={selectedType}>
						<option value="trimester">Trimestres (3 périodes)</option>
						<option value="semester">Semestres (2 périodes)</option>
					</select>
				</div>

				<p class="form-help" style="margin-bottom: 1rem;">
					Année scolaire : <strong>{startYear}-{startYear + 1}</strong>
				</p>

				<div class="type-preview">
					{#if selectedType === 'trimester'}
						<p>
							<strong>T1 :</strong> 1er sept. {startYear} - 30 nov. {startYear}
						</p>
						<p>
							<strong>T2 :</strong> 1er déc. {startYear} - {lastDayOfFeb(startYear + 1)} fév. {startYear + 1}
						</p>
						<p>
							<strong>T3 :</strong> 1er mars {startYear + 1} - 30 juin {startYear + 1}
						</p>
					{:else}
						<p>
							<strong>S1 :</strong> 1er sept. {startYear} - 31 jan. {startYear + 1}
						</p>
						<p>
							<strong>S2 :</strong> 1er fév. {startYear + 1} - 30 juin {startYear + 1}
						</p>
					{/if}
				</div>

				<div class="modal-actions">
					<button
						type="button"
						class="btn-secondary"
						onclick={() => (showConfigureModal = false)}
						disabled={isSubmitting}
					>
						Annuler
					</button>
					<button type="submit" class="btn-primary" disabled={isSubmitting}>
						{#if isSubmitting}
							Configuration...
						{:else}
							Configurer
						{/if}
					</button>
				</div>
			</form>
		</div>
	</div>
{/if}

<!-- Edit Period Modal -->
{#if showEditModal && editingPeriod}
	<!-- svelte-ignore a11y_no_static_element_interactions -->
	<div class="modal-overlay" onclick={closeEditModal} role="presentation">
		<div
			class="modal"
			role="dialog"
			aria-modal="true"
			aria-labelledby="edit-title"
			tabindex="-1"
			onclick={(e) => e.stopPropagation()}
			onkeydown={(e) => { if (e.key === 'Escape') closeEditModal(); }}
		>
			<header class="modal-header">
				<h2 id="edit-title">Modifier {editingPeriod.label}</h2>
				<button class="modal-close" onclick={closeEditModal} aria-label="Fermer">x</button>
			</header>

			<form
				class="modal-body"
				onsubmit={(e) => {
					e.preventDefault();
					handleUpdatePeriod();
				}}
			>
				{#if showImpactWarning}
					<div class="alert alert-warning">
						<strong>Attention :</strong> Cette période contient des notes. La modification des dates
						peut impacter les bulletins existants.
					</div>
				{/if}

				<div class="form-group">
					<label for="edit-start-date">Date de début</label>
					<input type="date" id="edit-start-date" bind:value={editStartDate} required />
				</div>

				<div class="form-group">
					<label for="edit-end-date">Date de fin</label>
					<input type="date" id="edit-end-date" bind:value={editEndDate} required />
				</div>

				<div class="modal-actions">
					<button
						type="button"
						class="btn-secondary"
						onclick={closeEditModal}
						disabled={isSubmitting}
					>
						Annuler
					</button>
					{#if showImpactWarning}
						<button
							type="button"
							class="btn-danger"
							onclick={() => handleUpdatePeriod(true)}
							disabled={isSubmitting}
						>
							{#if isSubmitting}
								Modification...
							{:else}
								Confirmer la modification
							{/if}
						</button>
					{:else}
						<button type="submit" class="btn-primary" disabled={isSubmitting}>
							{#if isSubmitting}
								Modification...
							{:else}
								Enregistrer
							{/if}
						</button>
					{/if}
				</div>
			</form>
		</div>
	</div>
{/if}

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

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

	.year-selector {
		display: flex;
		background: #f3f4f6;
		border-radius: 0.5rem;
		padding: 0.25rem;
	}

	.year-tab {
		padding: 0.5rem 1rem;
		border: none;
		background: transparent;
		border-radius: 0.375rem;
		font-size: 0.875rem;
		font-weight: 500;
		color: #6b7280;
		cursor: pointer;
		transition: all 0.2s;
	}

	.year-tab-active {
		background: white;
		color: #1f2937;
		box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
	}

	.year-tab:hover:not(.year-tab-active) {
		color: #374151;
	}

	/* Current period banner */
	.current-period-banner {
		display: flex;
		justify-content: space-between;
		align-items: center;
		padding: 1.25rem 1.5rem;
		background: linear-gradient(135deg, #3b82f6, #2563eb);
		border-radius: 0.75rem;
		color: white;
		margin-bottom: 1.5rem;
	}

	.banner-label {
		font-size: 0.875rem;
		opacity: 0.9;
	}

	.banner-period {
		display: block;
		font-size: 1.5rem;
		font-weight: 700;
		margin-top: 0.25rem;
	}

	.banner-countdown {
		text-align: right;
	}

	.countdown-number {
		display: block;
		font-size: 2rem;
		font-weight: 700;
	}

	.countdown-label {
		font-size: 0.75rem;
		opacity: 0.9;
	}

	/* Config info */
	.config-info {
		margin-bottom: 1rem;
	}

	.config-badge {
		display: inline-block;
		padding: 0.375rem 0.75rem;
		background: #eff6ff;
		color: #3b82f6;
		border-radius: 1rem;
		font-size: 0.875rem;
		font-weight: 500;
	}

	/* Periods list */
	.periods-list {
		display: grid;
		gap: 1rem;
	}

	.period-card {
		padding: 1.5rem;
		background: white;
		border: 1px solid #e5e7eb;
		border-radius: 0.75rem;
		transition: box-shadow 0.2s;
	}

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

	.period-current {
		border-color: #3b82f6;
		border-width: 2px;
	}

	.period-past {
		opacity: 0.7;
	}

	.period-header {
		display: flex;
		align-items: center;
		gap: 0.75rem;
		margin-bottom: 1rem;
	}

	.period-label {
		margin: 0;
		font-size: 1.25rem;
		font-weight: 600;
		color: #1f2937;
	}

	.badge {
		padding: 0.25rem 0.5rem;
		border-radius: 0.25rem;
		font-size: 0.75rem;
		font-weight: 500;
	}

	.badge-current {
		background: #dbeafe;
		color: #1d4ed8;
	}

	.badge-past {
		background: #f3f4f6;
		color: #6b7280;
	}

	.badge-future {
		background: #f0fdf4;
		color: #16a34a;
	}

	.period-dates {
		display: flex;
		gap: 2rem;
		margin-bottom: 1rem;
	}

	.date-item {
		display: flex;
		flex-direction: column;
		gap: 0.25rem;
	}

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

	.date-value {
		font-size: 0.9375rem;
		color: #1f2937;
		font-weight: 500;
	}

	.period-progress {
		margin-bottom: 1rem;
	}

	.progress-info {
		font-size: 0.875rem;
		color: #3b82f6;
		font-weight: 500;
	}

	.period-actions {
		margin-top: 0.5rem;
	}

	/* Type preview */
	.type-preview {
		padding: 1rem;
		background: #f9fafb;
		border-radius: 0.5rem;
		margin-bottom: 1rem;
	}

	.type-preview p {
		margin: 0.25rem 0;
		font-size: 0.875rem;
		color: #4b5563;
	}

	.form-help {
		margin: 0.25rem 0 0;
		font-size: 0.8125rem;
		color: #6b7280;
	}

	/* Alert warning */
	.alert-warning {
		padding: 1rem;
		background: #fffbeb;
		border: 1px solid #fcd34d;
		border-radius: 0.5rem;
		color: #92400e;
		margin-bottom: 1rem;
	}

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

	.btn-primary:hover:not(:disabled) {
		background: #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: #dc2626;
		color: white;
		border: none;
		border-radius: 0.375rem;
		font-weight: 500;
		cursor: pointer;
	}

	.btn-danger:hover:not(:disabled) {
		background: #b91c1c;
	}

	.btn-sm {
		padding: 0.375rem 0.75rem;
		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;
		width: 1.5rem;
		height: 1.5rem;
		display: flex;
		align-items: center;
		justify-content: center;
		background: #dc2626;
		color: white;
		border-radius: 50%;
		font-size: 0.75rem;
		font-weight: 700;
	}

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

	/* 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,
	.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;
	}

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

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