<script lang="ts">
	import { page } from '$app/stores';
	import { goto } from '$app/navigation';
	import { login, getJwtRoles, type LoginResult } from '$lib/auth';
	import TurnstileCaptcha from '$lib/components/TurnstileCaptcha.svelte';

	const justActivated = $derived($page.url.searchParams.get('activated') === 'true');

	// Form state
	let email = $state('');
	let password = $state('');
	let captchaToken = $state<string | null>(null);
	let isSubmitting = $state(false);
	let error = $state<{ type: string; message: string } | null>(null);

	// Rate limit / delay state
	let isRateLimited = $state(false);
	let isDelayed = $state(false);
	let retryAfterSeconds = $state(0);
	let delaySeconds = $state(0);
	let countdownInterval: ReturnType<typeof setInterval> | null = null;

	// CAPTCHA state
	let showCaptcha = $state(false);
	let captchaComponent: TurnstileCaptcha | undefined = $state();

	function startCountdown(seconds: number, isBlock: boolean = true) {
		if (isBlock) {
			retryAfterSeconds = seconds;
			isRateLimited = true;
		} else {
			delaySeconds = seconds;
			isDelayed = true;
		}

		if (countdownInterval) {
			clearInterval(countdownInterval);
		}

		countdownInterval = setInterval(() => {
			if (isBlock) {
				retryAfterSeconds--;
				if (retryAfterSeconds <= 0) {
					isRateLimited = false;
					if (countdownInterval) {
						clearInterval(countdownInterval);
						countdownInterval = null;
					}
				}
			} else {
				delaySeconds--;
				if (delaySeconds <= 0) {
					isDelayed = false;
					if (countdownInterval) {
						clearInterval(countdownInterval);
						countdownInterval = null;
					}
				}
			}
		}, 1000);
	}

	function formatCountdown(seconds: number): string {
		const minutes = Math.floor(seconds / 60);
		const secs = seconds % 60;
		return `${minutes}:${secs.toString().padStart(2, '0')}`;
	}

	function handleCaptchaSuccess(token: string) {
		captchaToken = token;
	}

	function handleCaptchaError(errorMsg: string) {
		error = {
			type: 'captcha_error',
			message: errorMsg
		};
	}

	function handleCaptchaExpired() {
		captchaToken = null;
		error = {
			type: 'captcha_expired',
			message: 'La vérification a expiré. Veuillez réessayer.'
		};
	}

	async function handleSubmit(event: SubmitEvent) {
		event.preventDefault();

		if (isRateLimited || isDelayed || isSubmitting) return;

		// Si CAPTCHA requis mais pas encore résolu
		if (showCaptcha && !captchaToken) {
			error = {
				type: 'captcha_required',
				message: 'Veuillez compléter la vérification de sécurité.'
			};
			return;
		}

		error = null;
		isSubmitting = true;

		try {
			const result: LoginResult = await login({
				email: email.trim(),
				password,
				captcha_token: captchaToken ?? undefined
			});

			if (result.success) {
				const roles = getJwtRoles();
				if (roles.includes('ROLE_SUPER_ADMIN')) {
					goto('/super-admin/dashboard');
				} else {
					goto('/dashboard');
				}
			} else if (result.error) {
				// Gérer les différents types d'erreur
				switch (result.error.type) {
					case 'rate_limited':
						if (result.error.retryAfter) {
							startCountdown(result.error.retryAfter);
						}
						break;

					case 'captcha_required':
						showCaptcha = true;
						break;

					case 'captcha_invalid':
						// Réinitialiser le CAPTCHA pour réessayer
						captchaToken = null;
						captchaComponent?.reset();
						break;

					case 'invalid_credentials':
						// Afficher CAPTCHA si requis pour la prochaine tentative
						if (result.error.captchaRequired) {
							showCaptcha = true;
						}
						// Réinitialiser le token si CAPTCHA déjà affiché
						if (showCaptcha) {
							captchaToken = null;
							captchaComponent?.reset();
						}
						// Appliquer le délai Fibonacci si présent
						if (result.error.delay && result.error.delay > 0) {
							startCountdown(result.error.delay, false);
						}
						break;
				}

				error = {
					type: result.error.type,
					message: result.error.message
				};
			}
		} finally {
			isSubmitting = false;
		}
	}
</script>

<svelte:head>
	<title>Connexion | Classeo</title>
	<link rel="preconnect" href="https://fonts.googleapis.com" />
	<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="anonymous" />
	<link
		href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
		rel="stylesheet"
	/>
</svelte:head>

<div class="login-page">
	<div class="login-container">
		<!-- Logo -->
		<div class="logo">
			<span class="logo-icon">📚</span>
			<span class="logo-text">Classeo</span>
		</div>

		<div class="card">
			{#if justActivated}
				<div class="success-banner">
					<span class="success-icon">✓</span>
					<span>Votre compte a été activé avec succès !</span>
				</div>
			{/if}

			<h1>Connexion</h1>

			{#if error}
				<div class="error-banner" class:rate-limited={isRateLimited} class:account-suspended={error.type === 'account_suspended'}>
					{#if isRateLimited}
						<span class="error-icon">🔒</span>
						<div class="error-content">
							<span class="error-message">{error.message}</span>
							<span class="countdown">
								Réessayez dans <strong>{formatCountdown(retryAfterSeconds)}</strong>
							</span>
						</div>
					{:else if error.type === 'account_suspended'}
						<span class="error-icon">🚫</span>
						<div class="error-content">
							<span class="error-message">{error.message}</span>
						</div>
					{:else}
						<span class="error-icon">⚠</span>
						<span class="error-message">{error.message}</span>
					{/if}
				</div>
			{/if}

			<form onsubmit={handleSubmit}>
				<div class="form-group">
					<label for="email">Adresse email</label>
					<div class="input-wrapper">
						<!-- svelte-ignore a11y_autofocus -->
						<input
							id="email"
							type="email"
							required
							placeholder="votre@email.com"
							bind:value={email}
							disabled={isSubmitting || isRateLimited || isDelayed}
							autocomplete="email"
							autofocus
						/>
					</div>
				</div>

				<div class="form-group">
					<label for="password">Mot de passe</label>
					<div class="input-wrapper">
						<input
							id="password"
							type="password"
							required
							placeholder="Votre mot de passe"
							bind:value={password}
							disabled={isSubmitting || isRateLimited || isDelayed}
							autocomplete="current-password"
						/>
					</div>
				</div>

				{#if showCaptcha}
					<div class="captcha-section">
						<p class="captcha-label">Vérification de sécurité</p>
						<TurnstileCaptcha
							bind:this={captchaComponent}
							onSuccess={handleCaptchaSuccess}
							onError={handleCaptchaError}
							onExpired={handleCaptchaExpired}
						/>
					</div>
				{/if}

				<button
					type="submit"
					class="submit-button"
					disabled={isSubmitting || isRateLimited || isDelayed || !email || !password || (showCaptcha && !captchaToken)}
				>
					{#if isSubmitting}
						<span class="spinner"></span>
						Connexion en cours...
					{:else if isRateLimited}
						Compte bloqué ({formatCountdown(retryAfterSeconds)})
					{:else if isDelayed}
						Patientez {delaySeconds}s...
					{:else}
						Se connecter
					{/if}
				</button>
			</form>

			<div class="links">
				<a href="/mot-de-passe-oublie" class="forgot-password">Mot de passe oublié ?</a>
			</div>
		</div>

		<p class="footer">Un problème ? Contactez votre établissement.</p>
	</div>
</div>

<style>
	/* Design Tokens - Calm Productivity */
	:root {
		--color-calm: hsl(142, 76%, 36%);
		--color-attention: hsl(38, 92%, 50%);
		--color-alert: hsl(0, 72%, 51%);
		--surface-primary: hsl(210, 20%, 98%);
		--surface-elevated: hsl(0, 0%, 100%);
		--text-primary: hsl(222, 47%, 11%);
		--text-secondary: hsl(215, 16%, 47%);
		--text-muted: hsl(215, 13%, 65%);
		--accent-primary: hsl(199, 89%, 48%);
		--border-subtle: hsl(214, 32%, 91%);
		--radius-sm: 8px;
		--radius-md: 12px;
		--radius-lg: 16px;
		--shadow-card: 0 1px 3px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.06);
		--shadow-elevated: 0 4px 6px rgba(0, 0, 0, 0.07), 0 2px 4px rgba(0, 0, 0, 0.06);
	}

	.login-page {
		min-height: 100vh;
		background: var(--surface-primary);
		display: flex;
		align-items: center;
		justify-content: center;
		padding: 24px;
		font-family: 'Inter', ui-sans-serif, system-ui, sans-serif;
	}

	.login-container {
		width: 100%;
		max-width: 420px;
	}

	/* Logo */
	.logo {
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 12px;
		margin-bottom: 32px;
	}

	.logo-icon {
		font-size: 32px;
	}

	.logo-text {
		font-size: 28px;
		font-weight: 700;
		color: var(--text-primary);
	}

	/* Card */
	.card {
		background: var(--surface-elevated);
		border-radius: var(--radius-lg);
		box-shadow: var(--shadow-elevated);
		padding: 32px;
	}

	.card h1 {
		font-size: 22px;
		font-weight: 600;
		color: var(--text-primary);
		margin-bottom: 24px;
		text-align: center;
	}

	/* Success Banner */
	.success-banner {
		display: flex;
		align-items: center;
		gap: 12px;
		padding: 14px 16px;
		background: linear-gradient(135deg, hsl(142, 76%, 95%) 0%, hsl(142, 76%, 97%) 100%);
		border: 1px solid hsl(142, 76%, 85%);
		border-radius: var(--radius-md);
		margin-bottom: 24px;
		font-size: 14px;
		font-weight: 500;
		color: var(--color-calm);
	}

	.success-icon {
		width: 24px;
		height: 24px;
		background: var(--color-calm);
		color: white;
		border-radius: 50%;
		display: flex;
		align-items: center;
		justify-content: center;
		font-size: 14px;
		font-weight: 700;
		flex-shrink: 0;
	}

	/* Error Banner */
	.error-banner {
		display: flex;
		align-items: flex-start;
		gap: 12px;
		padding: 14px 16px;
		background: linear-gradient(135deg, hsl(0, 76%, 95%) 0%, hsl(0, 76%, 97%) 100%);
		border: 1px solid hsl(0, 76%, 85%);
		border-radius: var(--radius-md);
		margin-bottom: 24px;
		font-size: 14px;
		color: var(--color-alert);
	}

	.error-banner.rate-limited {
		background: linear-gradient(135deg, hsl(38, 92%, 95%) 0%, hsl(38, 92%, 97%) 100%);
		border-color: hsl(38, 92%, 75%);
		color: hsl(38, 92%, 30%);
	}

	.error-banner.account-suspended {
		background: linear-gradient(135deg, hsl(220, 30%, 95%) 0%, hsl(220, 30%, 97%) 100%);
		border-color: hsl(220, 30%, 80%);
		color: hsl(220, 30%, 30%);
	}

	.error-icon {
		flex-shrink: 0;
		font-size: 18px;
	}

	.error-content {
		display: flex;
		flex-direction: column;
		gap: 4px;
	}

	.error-message {
		font-weight: 500;
	}

	.countdown {
		font-size: 13px;
		opacity: 0.9;
	}

	.countdown strong {
		font-variant-numeric: tabular-nums;
	}

	/* Form */
	form {
		display: flex;
		flex-direction: column;
		gap: 20px;
	}

	.form-group {
		display: flex;
		flex-direction: column;
		gap: 8px;
	}

	.form-group label {
		font-size: 14px;
		font-weight: 500;
		color: var(--text-primary);
	}

	.input-wrapper {
		position: relative;
	}

	.input-wrapper input {
		width: 100%;
		padding: 12px 16px;
		font-size: 15px;
		border: 1px solid var(--border-subtle);
		border-radius: var(--radius-sm);
		background: var(--surface-elevated);
		color: var(--text-primary);
		transition:
			border-color 0.2s,
			box-shadow 0.2s;
	}

	.input-wrapper input:focus {
		outline: none;
		border-color: var(--accent-primary);
		box-shadow: 0 0 0 3px hsla(199, 89%, 48%, 0.15);
	}

	.input-wrapper input::placeholder {
		color: var(--text-muted);
	}

	.input-wrapper input:disabled {
		background: var(--surface-primary);
		color: var(--text-muted);
		cursor: not-allowed;
	}

	/* CAPTCHA Section */
	.captcha-section {
		display: flex;
		flex-direction: column;
		align-items: center;
		padding: 16px;
		background: var(--surface-primary);
		border-radius: var(--radius-md);
		border: 1px solid var(--border-subtle);
	}

	.captcha-label {
		font-size: 14px;
		font-weight: 500;
		color: var(--text-secondary);
		margin-bottom: 8px;
	}

	/* Submit Button */
	.submit-button {
		width: 100%;
		padding: 14px 24px;
		font-size: 15px;
		font-weight: 600;
		color: white;
		background: var(--accent-primary);
		border: none;
		border-radius: var(--radius-sm);
		cursor: pointer;
		transition:
			background 0.2s,
			transform 0.1s,
			box-shadow 0.2s;
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 8px;
	}

	.submit-button:hover:not(:disabled) {
		background: hsl(199, 89%, 42%);
		box-shadow: var(--shadow-card);
	}

	.submit-button:active:not(:disabled) {
		transform: scale(0.98);
	}

	.submit-button:disabled {
		background: var(--text-muted);
		cursor: not-allowed;
	}

	/* Spinner */
	.spinner {
		width: 18px;
		height: 18px;
		border: 2px solid rgba(255, 255, 255, 0.3);
		border-top-color: white;
		border-radius: 50%;
		animation: spin 0.8s linear infinite;
	}

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

	/* Links */
	.links {
		text-align: center;
		margin-top: 20px;
		padding-top: 20px;
		border-top: 1px solid var(--border-subtle);
	}

	.forgot-password {
		font-size: 14px;
		color: var(--accent-primary);
		text-decoration: none;
	}

	.forgot-password:hover {
		text-decoration: underline;
	}

	/* Footer */
	.footer {
		text-align: center;
		font-size: 14px;
		color: var(--text-muted);
		margin-top: 24px;
	}
</style>
