<script lang="ts">
	import { page } from '$app/stores';
	import { goto } from '$app/navigation';
	import { createQuery, createMutation } from '@tanstack/svelte-query';
	import { getApiBaseUrl } from '$lib/api/config';
	import type {
		ActivationTokenInfo,
		ActivateAccountInput,
		ActivationErrorResponse
	} from '$lib/types/activation';

	const token = $derived($page.params.token ?? '');
	const apiBaseUrl = getApiBaseUrl();

	// État du formulaire
	let password = $state('');
	let passwordConfirmation = $state('');
	let showPassword = $state(false);
	let formError = $state('');
	let fieldErrors = $state<Record<string, string>>({});

	// Critères de validation du mot de passe
	const hasMinLength = $derived(password.length >= 8);
	const hasUppercase = $derived(/[A-Z]/.test(password));
	const hasLowercase = $derived(/[a-z]/.test(password));
	const hasDigit = $derived(/[0-9]/.test(password));
	const hasSpecial = $derived(/[^A-Za-z0-9]/.test(password));
	const passwordsMatch = $derived(password === passwordConfirmation && password.length > 0);
	const isPasswordValid = $derived(
		hasMinLength && hasUppercase && hasLowercase && hasDigit && hasSpecial && passwordsMatch
	);

	// Query pour récupérer les infos du token
	// svelte-ignore state_referenced_locally
	// The token comes from URL params and won't change during component lifecycle
	const tokenInfoQuery = createQuery<ActivationTokenInfo>({
		queryKey: ['activationToken', token] as const,
		queryFn: async () => {
			const currentToken = $page.params.token ?? '';
			const response = await globalThis.fetch(`${apiBaseUrl}/activation-tokens/${currentToken}`, {
				headers: { Accept: 'application/json' }
			});

			if (!response.ok) {
				const errorData = (await response.json()) as ActivationErrorResponse;
				throw new Error(errorData.detail || 'Token invalide');
			}

			return response.json() as Promise<ActivationTokenInfo>;
		},
		retry: false
	});

	// Mutation pour activer le compte
	const activateMutation = createMutation({
		mutationFn: async (data: ActivateAccountInput) => {
			const response = await globalThis.fetch(`${apiBaseUrl}/activate`, {
				method: 'POST',
				headers: {
					'Content-Type': 'application/json',
					Accept: 'application/json'
				},
				body: JSON.stringify(data)
			});

			if (!response.ok) {
				const errorData = (await response.json()) as ActivationErrorResponse;
				throw errorData;
			}

			return response.json();
		},
		onSuccess: () => {
			goto('/login?activated=true');
		},
		onError: (error: ActivationErrorResponse) => {
			formError = '';
			fieldErrors = {};

			if (error.violations) {
				for (const violation of error.violations) {
					fieldErrors[violation.propertyPath] = violation.message;
				}
			} else {
				formError = error.detail || "Une erreur est survenue lors de l'activation.";
			}
		}
	});

	function handleSubmit(event: Event) {
		event.preventDefault();

		if (!isPasswordValid) {
			formError = 'Veuillez corriger les erreurs avant de continuer.';
			return;
		}

		formError = '';
		fieldErrors = {};

		$activateMutation.mutate({
			tokenValue: token,
			password: password
		});
	}
</script>

<svelte:head>
	<title>Activation de compte | 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="activation-page">
	<div class="activation-container">
		<!-- Logo -->
		<div class="logo">
			<span class="logo-icon">📚</span>
			<span class="logo-text">Classeo</span>
		</div>

		{#if $tokenInfoQuery.isPending}
			<!-- Loading state -->
			<div class="card">
				<div class="loading-state">
					<div class="spinner"></div>
					<p>Vérification du lien d'activation...</p>
				</div>
			</div>
		{:else if $tokenInfoQuery.isError}
			<!-- Error state -->
			<div class="card">
				<div class="error-state">
					<div class="error-icon">✕</div>
					<h2>Lien invalide</h2>
					<p>Ce lien d'activation est invalide ou a expiré.</p>
					<p class="hint">Veuillez contacter votre établissement pour obtenir un nouveau lien.</p>
				</div>
			</div>
		{:else if $tokenInfoQuery.data}
			{@const tokenInfo = $tokenInfoQuery.data}

			{#if tokenInfo.isExpired}
				<!-- Token expired -->
				<div class="card">
					<div class="error-state warning">
						<div class="error-icon">⏱</div>
						<h2>Lien expiré</h2>
						<p>Votre lien d'activation a expiré (validité : 7 jours).</p>
						<p class="hint">
							Veuillez contacter <strong>{tokenInfo.schoolName}</strong> pour obtenir un nouveau lien.
						</p>
					</div>
				</div>
			{:else}
				<!-- Activation form -->
				<div class="card">
					<h1>Activation de votre compte</h1>

					<!-- Info établissement -->
					<div class="school-info">
						<div class="school-icon">🏫</div>
						<div class="school-details">
							<span class="school-name">{tokenInfo.schoolName}</span>
							<span class="account-type">{tokenInfo.role}</span>
						</div>
					</div>

					<div class="email-badge">
						{tokenInfo.email}
					</div>

					<form onsubmit={handleSubmit}>
						{#if formError}
							<div class="form-error">
								<span class="error-badge">!</span>
								{formError}
							</div>
						{/if}

						<!-- Mot de passe -->
						<div class="form-group">
							<label for="password">Créer votre mot de passe</label>
							<div class="input-wrapper">
								<input
									id="password"
									type={showPassword ? 'text' : 'password'}
									bind:value={password}
									required
									placeholder="Entrez votre mot de passe"
									class:has-error={fieldErrors['password']}
								/>
								<button type="button" class="toggle-password" onclick={() => (showPassword = !showPassword)}>
									{showPassword ? '🙈' : '👁'}
								</button>
							</div>
							{#if fieldErrors['password']}
								<span class="field-error">{fieldErrors['password']}</span>
							{/if}
						</div>

						<!-- Critères de validation -->
						<div class="password-requirements">
							<span class="requirements-title">Votre mot de passe doit contenir :</span>
							<ul>
								<li class:valid={hasMinLength}>
									<span class="check">{hasMinLength ? '✓' : '○'}</span>
									Au moins 8 caractères
								</li>
								<li class:valid={hasUppercase}>
									<span class="check">{hasUppercase ? '✓' : '○'}</span>
									Une majuscule
								</li>
								<li class:valid={hasLowercase}>
									<span class="check">{hasLowercase ? '✓' : '○'}</span>
									Une minuscule
								</li>
								<li class:valid={hasDigit}>
									<span class="check">{hasDigit ? '✓' : '○'}</span>
									Un chiffre
								</li>
								<li class:valid={hasSpecial}>
									<span class="check">{hasSpecial ? '✓' : '○'}</span>
									Un caractère spécial
								</li>
							</ul>
						</div>

						<!-- Confirmation mot de passe -->
						<div class="form-group">
							<label for="passwordConfirmation">Confirmer le mot de passe</label>
							<div class="input-wrapper">
								<input
									id="passwordConfirmation"
									type={showPassword ? 'text' : 'password'}
									bind:value={passwordConfirmation}
									required
									placeholder="Confirmez votre mot de passe"
									class:has-error={passwordConfirmation.length > 0 && !passwordsMatch}
								/>
							</div>
							{#if passwordConfirmation.length > 0 && !passwordsMatch}
								<span class="field-error">Les mots de passe ne correspondent pas.</span>
							{/if}
						</div>

						<!-- Bouton submit -->
						<button type="submit" class="submit-button" disabled={!isPasswordValid || $activateMutation.isPending}>
							{#if $activateMutation.isPending}
								<span class="button-spinner"></span>
								Activation en cours...
							{:else}
								Activer mon compte
							{/if}
						</button>
					</form>
				</div>
			{/if}
		{/if}

		<!-- Footer -->
		<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);
	}

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

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

	/* School Info */
	.school-info {
		display: flex;
		align-items: center;
		gap: 16px;
		padding: 16px;
		background: linear-gradient(135deg, hsl(199, 89%, 96%) 0%, hsl(199, 89%, 98%) 100%);
		border-radius: var(--radius-md);
		margin-bottom: 16px;
	}

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

	.school-details {
		display: flex;
		flex-direction: column;
		gap: 4px;
	}

	.school-name {
		font-size: 16px;
		font-weight: 600;
		color: var(--text-primary);
	}

	.account-type {
		font-size: 14px;
		color: var(--accent-primary);
		font-weight: 500;
	}

	.email-badge {
		display: inline-block;
		width: 100%;
		text-align: center;
		padding: 10px 16px;
		background: var(--surface-primary);
		border: 1px solid var(--border-subtle);
		border-radius: var(--radius-sm);
		font-size: 14px;
		color: var(--text-secondary);
		margin-bottom: 24px;
	}

	/* 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;
		padding-right: 48px;
		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.has-error {
		border-color: var(--color-alert);
	}

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

	.toggle-password {
		position: absolute;
		right: 12px;
		top: 50%;
		transform: translateY(-50%);
		background: none;
		border: none;
		font-size: 18px;
		cursor: pointer;
		padding: 4px;
		opacity: 0.6;
		transition: opacity 0.2s;
	}

	.toggle-password:hover {
		opacity: 1;
	}

	.field-error {
		font-size: 13px;
		color: var(--color-alert);
	}

	/* Password Requirements */
	.password-requirements {
		padding: 16px;
		background: var(--surface-primary);
		border-radius: var(--radius-sm);
	}

	.requirements-title {
		font-size: 13px;
		font-weight: 500;
		color: var(--text-secondary);
		display: block;
		margin-bottom: 12px;
	}

	.password-requirements ul {
		list-style: none;
		padding: 0;
		margin: 0;
		display: flex;
		flex-direction: column;
		gap: 8px;
	}

	.password-requirements li {
		display: flex;
		align-items: center;
		gap: 10px;
		font-size: 14px;
		color: var(--text-muted);
		transition: color 0.2s;
	}

	.password-requirements li.valid {
		color: var(--color-calm);
	}

	.password-requirements li .check {
		font-size: 14px;
		width: 18px;
		height: 18px;
		display: flex;
		align-items: center;
		justify-content: center;
		border-radius: 50%;
		background: var(--border-subtle);
		color: var(--text-muted);
		font-weight: 600;
		transition: background 0.2s, color 0.2s;
	}

	.password-requirements li.valid .check {
		background: var(--color-calm);
		color: white;
	}

	/* 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 {
		opacity: 0.5;
		cursor: not-allowed;
	}

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

	/* Loading State */
	.loading-state {
		display: flex;
		flex-direction: column;
		align-items: center;
		gap: 16px;
		padding: 24px;
	}

	.loading-state p {
		color: var(--text-secondary);
		font-size: 15px;
	}

	.spinner {
		width: 40px;
		height: 40px;
		border: 3px solid var(--border-subtle);
		border-top-color: var(--accent-primary);
		border-radius: 50%;
		animation: spin 0.8s linear infinite;
	}

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

	/* Error State */
	.error-state {
		text-align: center;
		padding: 16px;
	}

	.error-state .error-icon {
		width: 56px;
		height: 56px;
		margin: 0 auto 20px;
		background: hsl(0, 72%, 95%);
		color: var(--color-alert);
		border-radius: 50%;
		display: flex;
		align-items: center;
		justify-content: center;
		font-size: 24px;
		font-weight: 700;
	}

	.error-state.warning .error-icon {
		background: hsl(38, 92%, 95%);
		color: var(--color-attention);
	}

	.error-state h2 {
		font-size: 20px;
		font-weight: 600;
		color: var(--text-primary);
		margin-bottom: 12px;
	}

	.error-state p {
		font-size: 15px;
		color: var(--text-secondary);
		margin-bottom: 8px;
	}

	.error-state .hint {
		font-size: 14px;
		color: var(--text-muted);
	}

	/* Form Error */
	.form-error {
		display: flex;
		align-items: center;
		gap: 10px;
		padding: 12px 16px;
		background: hsl(0, 72%, 97%);
		border: 1px solid hsl(0, 72%, 90%);
		border-radius: var(--radius-sm);
		font-size: 14px;
		color: var(--color-alert);
	}

	.error-badge {
		width: 20px;
		height: 20px;
		background: var(--color-alert);
		color: white;
		border-radius: 50%;
		display: flex;
		align-items: center;
		justify-content: center;
		font-size: 12px;
		font-weight: 700;
		flex-shrink: 0;
	}

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