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

	type RuleDefinition = {
		type: string;
		params: Record<string, unknown>;
	};

	type HomeworkRulesConfig = {
		id: string;
		rules: RuleDefinition[];
		enforcementMode: string;
		enabled: boolean;
		createdAt: string;
		updatedAt: string;
	};

	type HistoryEntry = {
		previousRules: string | null;
		newRules: string;
		enforcementMode: string;
		enabled: boolean;
		changedBy: string;
		changedAt: string;
	};

	// State
	let config = $state<HomeworkRulesConfig | null>(null);
	let isLoading = $state(true);
	let error = $state<string | null>(null);
	let successMessage = $state<string | null>(null);
	let isSubmitting = $state(false);

	// Form state
	let enforcementMode = $state<string>('soft');
	let enabled = $state(true);
	let minimumDelayDays = $state<number>(3);
	let minimumDelayEnabled = $state(false);
	let noMondayAfterEnabled = $state(false);
	let noMondayAfterDay = $state<string>('friday');
	let noMondayAfterTime = $state<string>('12:00');

	// History
	let history = $state<HistoryEntry[]>([]);
	let showHistory = $state(false);

	// Derived
	let hasChanges = $derived.by(() => {
		if (!config) return false;

		const currentRules = buildRules();
		const configRulesJson = JSON.stringify(config.rules);
		const newRulesJson = JSON.stringify(currentRules);

		return (
			configRulesJson !== newRulesJson ||
			enforcementMode !== config.enforcementMode ||
			enabled !== config.enabled
		);
	});

	let modeLabel = $derived(
		enforcementMode === 'soft'
			? 'Avertissement'
			: enforcementMode === 'hard'
				? 'Blocage'
				: 'Désactivé'
	);

	onMount(() => {
		loadConfig();
	});

	function buildRules(): RuleDefinition[] {
		const rules: RuleDefinition[] = [];

		if (minimumDelayEnabled) {
			rules.push({
				type: 'minimum_delay',
				params: { days: minimumDelayDays }
			});
		}

		if (noMondayAfterEnabled) {
			rules.push({
				type: 'no_monday_after',
				params: { day: noMondayAfterDay, time: noMondayAfterTime }
			});
		}

		return rules;
	}

	function syncFormFromConfig(data: HomeworkRulesConfig) {
		enforcementMode = data.enforcementMode;
		enabled = data.enabled;

		minimumDelayEnabled = false;
		noMondayAfterEnabled = false;

		for (const rule of data.rules) {
			if (rule.type === 'minimum_delay') {
				minimumDelayEnabled = true;
				minimumDelayDays = (rule.params['days'] as number) ?? 3;
			}
			if (rule.type === 'no_monday_after') {
				noMondayAfterEnabled = true;
				noMondayAfterDay = (rule.params['day'] as string) ?? 'friday';
				noMondayAfterTime = (rule.params['time'] as string) ?? '12:00';
			}
		}
	}

	async function loadConfig() {
		try {
			isLoading = true;
			error = null;
			const apiUrl = getApiBaseUrl();
			const response = await authenticatedFetch(`${apiUrl}/settings/homework-rules`);

			if (!response.ok) {
				throw new Error('Erreur lors du chargement de la configuration.');
			}

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

	async function handleSave() {
		if (!hasChanges) return;

		try {
			isSubmitting = true;
			error = null;
			successMessage = null;

			const apiUrl = getApiBaseUrl();
			const response = await authenticatedFetch(`${apiUrl}/settings/homework-rules`, {
				method: 'PUT',
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify({
					rules: buildRules(),
					enforcementMode,
					enabled
				})
			});

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

			const data: HomeworkRulesConfig = await response.json();
			config = data;
			syncFormFromConfig(data);
			successMessage = 'Règles de devoirs mises à jour avec succès.';
			window.setTimeout(() => (successMessage = null), 4000);
		} catch (e) {
			error = e instanceof Error ? e.message : 'Erreur inconnue';
		} finally {
			isSubmitting = false;
		}
	}

	function handleCancel() {
		if (config) {
			syncFormFromConfig(config);
		}
		error = null;
		successMessage = null;
	}

	function handleModeChange(newMode: string) {
		enforcementMode = newMode;
		if (newMode === 'disabled') {
			enabled = false;
		} else {
			enabled = true;
		}
	}

	async function loadHistory() {
		try {
			const apiUrl = getApiBaseUrl();
			const response = await authenticatedFetch(`${apiUrl}/settings/homework-rules/history`);

			if (!response.ok) {
				throw new Error('Erreur lors du chargement de l\'historique.');
			}

			const data = await response.json();
			history = (data['hydra:member'] ?? data['member'] ?? data) as HistoryEntry[];
			showHistory = true;
		} catch (e) {
			error = e instanceof Error ? e.message : 'Erreur inconnue';
		}
	}

	function formatDate(dateStr: string): string {
		const d = new Date(dateStr);
		return d.toLocaleDateString('fr-FR', {
			day: '2-digit',
			month: '2-digit',
			year: 'numeric',
			hour: '2-digit',
			minute: '2-digit'
		});
	}
</script>

<svelte:head>
	<title>Règles de devoirs - Administration</title>
</svelte:head>

<div class="page-header">
	<h1>Règles de devoirs</h1>
	<p class="page-description">
		Configurez les règles de timing pour protéger les élèves et familles des devoirs de dernière
		minute.
	</p>
</div>

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

{#if successMessage}
	<div class="alert alert-success" role="status">
		<span>{successMessage}</span>
		<button class="alert-close" onclick={() => (successMessage = null)}>&times;</button>
	</div>
{/if}

{#if isLoading}
	<div class="loading-state">
		<div class="spinner"></div>
		<p>Chargement de la configuration...</p>
	</div>
{:else if config}
	<!-- Mode d'application -->
	<section class="card">
		<h2>Mode d'application</h2>
		<p class="section-description">
			Choisissez comment les règles sont appliquées lorsqu'un enseignant crée un devoir.
		</p>

		<div class="mode-selector" role="radiogroup" aria-label="Mode d'application">
			<button
				class="mode-option"
				class:selected={enforcementMode === 'soft'}
				role="radio"
				aria-checked={enforcementMode === 'soft'}
				onclick={() => handleModeChange('soft')}
				disabled={isSubmitting}
			>
				<span class="mode-icon">&#9888;</span>
				<span class="mode-label">Avertissement</span>
				<span class="mode-description"
					>L'enseignant voit un avertissement mais peut créer le devoir.</span
				>
			</button>

			<button
				class="mode-option"
				class:selected={enforcementMode === 'hard'}
				role="radio"
				aria-checked={enforcementMode === 'hard'}
				onclick={() => handleModeChange('hard')}
				disabled={isSubmitting}
			>
				<span class="mode-icon">&#128683;</span>
				<span class="mode-label">Blocage</span>
				<span class="mode-description"
					>L'enseignant ne peut pas créer le devoir si la règle est enfreinte.</span
				>
			</button>

			<button
				class="mode-option"
				class:selected={enforcementMode === 'disabled'}
				role="radio"
				aria-checked={enforcementMode === 'disabled'}
				onclick={() => handleModeChange('disabled')}
				disabled={isSubmitting}
			>
				<span class="mode-icon">&#10060;</span>
				<span class="mode-label">Désactivé</span>
				<span class="mode-description"
					>Aucune vérification. Les enseignants créent les devoirs librement.</span
				>
			</button>
		</div>
	</section>

	<!-- Règles -->
	{#if enforcementMode !== 'disabled'}
		<section class="card">
			<h2>Règles actives</h2>
			<p class="section-description">Définissez les règles de timing des devoirs.</p>

			<!-- Délai minimum -->
			<div class="rule-block">
				<label class="rule-toggle">
					<input
						type="checkbox"
						bind:checked={minimumDelayEnabled}
						disabled={isSubmitting}
					/>
					<span class="rule-name">Délai minimum avant échéance</span>
				</label>

				{#if minimumDelayEnabled}
					<div class="rule-params">
						<label class="param-label">
							Nombre de jours minimum :
							<input
								type="number"
								bind:value={minimumDelayDays}
								min="1"
								max="30"
								disabled={isSubmitting}
								class="param-input"
							/>
						</label>
						<p class="rule-example">
							Exemple : avec {minimumDelayDays} jours, un devoir pour vendredi ne peut pas être
							créé après {minimumDelayDays === 3 ? 'mardi' : `J-${minimumDelayDays}`}.
						</p>
					</div>
				{/if}
			</div>

			<!-- Pas de devoir pour lundi -->
			<div class="rule-block">
				<label class="rule-toggle">
					<input
						type="checkbox"
						bind:checked={noMondayAfterEnabled}
						disabled={isSubmitting}
					/>
					<span class="rule-name">Pas de devoir pour lundi donné trop tard</span>
				</label>

				{#if noMondayAfterEnabled}
					<div class="rule-params">
						<label class="param-label">
							Jour limite :
							<select bind:value={noMondayAfterDay} disabled={isSubmitting} class="param-select">
								<option value="thursday">Jeudi</option>
								<option value="friday">Vendredi</option>
							</select>
						</label>
						<label class="param-label">
							Heure limite :
							<input
								type="time"
								bind:value={noMondayAfterTime}
								disabled={isSubmitting}
								class="param-input"
							/>
						</label>
						<p class="rule-example">
							Exemple : un devoir pour lundi ne peut pas être créé après {noMondayAfterDay === 'friday' ? 'vendredi' : 'jeudi'}
							{noMondayAfterTime}.
						</p>
					</div>
				{/if}
			</div>
		</section>
	{/if}

	<!-- Preview impact -->
	<section class="card">
		<h2>Résumé</h2>
		<div class="preview">
			<p>
				<strong>Mode :</strong>
				{modeLabel}
			</p>
			{#if enforcementMode !== 'disabled'}
				<p>
					<strong>Règles :</strong>
					{#if !minimumDelayEnabled && !noMondayAfterEnabled}
						Aucune règle configurée
					{:else}
						{#if minimumDelayEnabled}
							Délai minimum de {minimumDelayDays} jours.
						{/if}
						{#if noMondayAfterEnabled}
							Pas de devoir pour lundi après {noMondayAfterDay === 'friday' ? 'vendredi' : 'jeudi'}
							{noMondayAfterTime}.
						{/if}
					{/if}
				</p>
			{:else}
				<p class="preview-disabled">Les enseignants peuvent créer des devoirs librement.</p>
			{/if}
		</div>
	</section>

	<!-- Actions -->
	<div class="form-actions">
		<button class="btn-secondary" onclick={loadHistory} disabled={isSubmitting}>
			Voir l'historique
		</button>
		<div class="action-group">
			<button class="btn-secondary" onclick={handleCancel} disabled={isSubmitting || !hasChanges}>
				Annuler
			</button>
			<button class="btn-primary" onclick={handleSave} disabled={isSubmitting || !hasChanges}>
				{#if isSubmitting}
					Enregistrement...
				{:else}
					Enregistrer
				{/if}
			</button>
		</div>
	</div>

	<!-- History modal -->
	{#if showHistory}
		<div
			class="modal-overlay"
			onclick={() => (showHistory = false)}
			onkeydown={(e) => e.key === 'Escape' && (showHistory = false)}
			role="presentation"
		>
			<!-- svelte-ignore a11y_click_events_have_key_events a11y_no_static_element_interactions a11y_no_noninteractive_element_interactions -->
			<div
				class="modal-content"
				onclick={(e) => e.stopPropagation()}
				role="dialog"
				aria-modal="true"
				aria-label="Historique des changements"
				tabindex="-1"
			>
				<div class="modal-header">
					<h2>Historique des changements</h2>
					<button class="modal-close" onclick={() => (showHistory = false)}>&times;</button>
				</div>

				{#if history.length === 0}
					<p class="empty-history">Aucun changement enregistré.</p>
				{:else}
					<div class="history-list">
						{#each history as entry}
							<div class="history-entry">
								<div class="history-date">{formatDate(entry.changedAt)}</div>
								<div class="history-details">
									<span class="history-mode">{entry.enforcementMode}</span>
									{#if !entry.enabled}
										<span class="history-badge disabled">Désactivé</span>
									{/if}
								</div>
							</div>
						{/each}
					</div>
				{/if}
			</div>
		</div>
	{/if}
{/if}

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

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

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

	/* Alerts */
	.alert {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 0.75rem;
		padding: 0.875rem 1rem;
		border-radius: 0.5rem;
		margin-bottom: 1rem;
		font-size: 0.875rem;
	}

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

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

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

	/* Loading */
	.loading-state {
		display: flex;
		flex-direction: column;
		align-items: 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: #8b5cf6;
		border-radius: 50%;
		animation: spin 0.8s linear infinite;
	}

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

	/* Cards */
	.card {
		background: white;
		border: 1px solid #e5e7eb;
		border-radius: 0.75rem;
		padding: 1.5rem;
		margin-bottom: 1rem;
	}

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

	.section-description {
		color: #6b7280;
		font-size: 0.875rem;
		margin: 0 0 1.25rem;
	}

	/* Mode selector */
	.mode-selector {
		display: grid;
		grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
		gap: 0.75rem;
	}

	.mode-option {
		display: flex;
		flex-direction: column;
		align-items: center;
		gap: 0.5rem;
		padding: 1.25rem;
		border: 2px solid #e5e7eb;
		border-radius: 0.75rem;
		background: white;
		cursor: pointer;
		transition: all 0.2s;
		text-align: center;
	}

	.mode-option:hover:not(:disabled) {
		border-color: #a5b4fc;
		background: #f5f3ff;
	}

	.mode-option.selected {
		border-color: #6366f1;
		background: #eef2ff;
	}

	.mode-option:disabled {
		opacity: 0.6;
		cursor: not-allowed;
	}

	.mode-icon {
		font-size: 1.5rem;
	}

	.mode-label {
		font-weight: 600;
		font-size: 0.9375rem;
		color: #1f2937;
	}

	.mode-description {
		font-size: 0.8125rem;
		color: #6b7280;
		line-height: 1.4;
	}

	/* Rules */
	.rule-block {
		padding: 1rem 0;
		border-bottom: 1px solid #f3f4f6;
	}

	.rule-block:last-child {
		border-bottom: none;
		padding-bottom: 0;
	}

	.rule-toggle {
		display: flex;
		align-items: center;
		gap: 0.75rem;
		cursor: pointer;
		font-weight: 500;
		color: #1f2937;
	}

	.rule-toggle input[type='checkbox'] {
		width: 1.125rem;
		height: 1.125rem;
		accent-color: #6366f1;
	}

	.rule-name {
		font-size: 0.9375rem;
	}

	.rule-params {
		margin-top: 0.75rem;
		margin-left: 1.875rem;
		display: flex;
		flex-direction: column;
		gap: 0.5rem;
	}

	.param-label {
		display: flex;
		align-items: center;
		gap: 0.5rem;
		font-size: 0.875rem;
		color: #4b5563;
	}

	.param-input {
		padding: 0.375rem 0.5rem;
		border: 1px solid #d1d5db;
		border-radius: 0.375rem;
		font-size: 0.875rem;
		width: 80px;
	}

	.param-select {
		padding: 0.375rem 0.5rem;
		border: 1px solid #d1d5db;
		border-radius: 0.375rem;
		font-size: 0.875rem;
	}

	.rule-example {
		font-size: 0.8125rem;
		color: #9ca3af;
		font-style: italic;
		margin: 0;
	}

	/* Preview */
	.preview {
		display: flex;
		flex-direction: column;
		gap: 0.25rem;
		font-size: 0.875rem;
		color: #4b5563;
	}

	.preview p {
		margin: 0;
	}

	.preview-disabled {
		color: #9ca3af;
		font-style: italic;
	}

	/* Actions */
	.form-actions {
		display: flex;
		justify-content: space-between;
		align-items: center;
		margin-top: 1rem;
	}

	.action-group {
		display: flex;
		gap: 0.75rem;
	}

	.btn-primary {
		padding: 0.5rem 1.25rem;
		background: #6366f1;
		color: white;
		border: none;
		border-radius: 0.5rem;
		font-size: 0.875rem;
		font-weight: 500;
		cursor: pointer;
		transition: background 0.2s;
	}

	.btn-primary:hover:not(:disabled) {
		background: #4f46e5;
	}

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

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

	.btn-secondary:hover:not(:disabled) {
		background: #f9fafb;
		border-color: #9ca3af;
	}

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

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

	.modal-content {
		background: white;
		border-radius: 0.75rem;
		padding: 1.5rem;
		width: 100%;
		max-width: 560px;
		max-height: 80vh;
		overflow-y: auto;
	}

	.modal-header {
		display: flex;
		justify-content: space-between;
		align-items: center;
		margin-bottom: 1rem;
	}

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

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

	.empty-history {
		color: #9ca3af;
		text-align: center;
		padding: 2rem;
	}

	.history-list {
		display: flex;
		flex-direction: column;
		gap: 0.5rem;
	}

	.history-entry {
		padding: 0.75rem;
		border: 1px solid #f3f4f6;
		border-radius: 0.5rem;
	}

	.history-date {
		font-size: 0.8125rem;
		color: #6b7280;
		margin-bottom: 0.25rem;
	}

	.history-details {
		display: flex;
		gap: 0.5rem;
		align-items: center;
		font-size: 0.875rem;
	}

	.history-mode {
		font-weight: 500;
		color: #1f2937;
		text-transform: capitalize;
	}

	.history-badge.disabled {
		font-size: 0.75rem;
		background: #fef2f2;
		color: #dc2626;
		padding: 0.125rem 0.5rem;
		border-radius: 9999px;
	}
</style>
