<script lang="ts">
	import { goto } from '$app/navigation';
	import { page } from '$app/stores';
	import { onMount } from 'svelte';
	import { t } from '$lib/i18n';
	import { resolvedTheme, applyTheme } from '$lib/stores/theme';
	import { IconLoader } from '$lib/components/icons';
	import { setAuthToken, isAuthenticated } from '$lib/auth';

	let username = $state('');
	let password = $state('');
	let error = $state('');
	let loading = $state(false);
	let showPassword = $state(false);
	let authMode = $state('local');

	// Apply theme on login page too.
	$effect(() => {
		applyTheme($resolvedTheme);
	});

	onMount(async () => {
		// Check if OIDC is enabled.
		try {
			const res = await fetch('/api/auth/mode');
			if (res.ok) {
				const envelope = await res.json();
				authMode = envelope.data?.auth_mode ?? 'local';
			}
		} catch { /* default to local */ }

		const urlToken = $page.url.searchParams.get('token');
		if (urlToken) {
			// Validate the token against the backend before trusting it.
			try {
				const res = await fetch('/api/auth/me', {
					headers: { 'Authorization': `Bearer ${urlToken}` }
				});
				if (res.ok) {
					setAuthToken(urlToken);
					// Remove token from URL to prevent leakage via history/referrer.
					history.replaceState(null, '', '/login');
					goto('/');
					return;
				}
			} catch {
				// Token validation failed — fall through to login form.
			}
			// Remove invalid token from URL.
			history.replaceState(null, '', '/login');
		}
		if (isAuthenticated()) {
			goto('/');
		}
	});

	async function handleLogin() {
		error = '';
		loading = true;
		try {
			const res = await fetch('/api/auth/login', {
				method: 'POST',
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify({ username, password })
			});
			const envelope = await res.json();
			if (!envelope.success) {
				error = envelope.error ?? $t('login.loginFailed');
				return;
			}
			setAuthToken(envelope.data.token);
			goto('/');
		} catch (err: unknown) {
			error = err instanceof Error ? err.message : $t('login.networkError');
		} finally {
			loading = false;
		}
	}

	function handleOIDCLogin() {
		window.location.href = '/api/auth/oidc/login';
	}
</script>

<div class="login-shell">
	<!-- Drifting forge-ember backdrop (pure CSS, decorative only) -->
	<div class="fx-layer" aria-hidden="true">
		<div class="fx-glow"></div>
		<div class="fx-grid"></div>
		<div class="fx-embers">
			{#each Array(24) as _, i (i)}
				<span class="ember" style="--i: {i}"></span>
			{/each}
		</div>
		<div class="fx-vignette"></div>
	</div>

	<div class="login-card-wrap">
		<div class="rounded-2xl border border-[var(--border-primary)] bg-[var(--surface-card)] p-8 shadow-[var(--shadow-lg)] login-card">
			<!-- Logo -->
			<div class="mb-6 text-center">
				<div class="mx-auto flex h-12 w-12 items-center justify-center rounded-xl bg-[var(--color-brand-600)] shadow-md">
					<svg class="h-6 w-6 text-white" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
						<path stroke-linecap="round" stroke-linejoin="round" d="M21 7.5l-2.25-1.313M21 7.5v2.25m0-2.25l-2.25 1.313M3 7.5l2.25-1.313M3 7.5l2.25 1.313M3 7.5v2.25m9 3l2.25-1.313M12 12.75l-2.25-1.313M12 12.75V15m0 6.75l2.25-1.313M12 21.75V19.5m0 2.25l-2.25-1.313m0-16.875L12 2.25l2.25 1.313M21 14.25v2.25l-2.25 1.313m-13.5 0L3 16.5v-2.25" />
					</svg>
				</div>
				<h1 class="mt-4 text-xl font-bold text-[var(--text-primary)]">{$t('login.title')}</h1>
				<p class="mt-1 text-sm text-[var(--text-secondary)]">{$t('login.subtitle')}</p>
			</div>

			{#if error}
				<div class="mb-4 rounded-lg bg-[var(--color-danger-light)] p-3 text-sm text-[var(--color-danger)]">
					{error}
				</div>
			{/if}

			<form onsubmit={(e) => { e.preventDefault(); handleLogin(); }} class="space-y-4">
				<div class="flex flex-col gap-1.5">
					<label for="username" class="text-sm font-medium text-[var(--text-primary)]">{$t('login.username')}</label>
					<input
						id="username"
						type="text"
						bind:value={username}
						required
						autocomplete="username"
						class="w-full rounded-lg border border-[var(--border-input)] bg-[var(--surface-input)] px-3 py-2.5 text-sm text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:border-[var(--color-brand-500)] focus:outline-none focus:ring-2 focus:ring-[var(--color-brand-500)]"
					/>
				</div>

				<div class="flex flex-col gap-1.5">
					<label for="password" class="text-sm font-medium text-[var(--text-primary)]">{$t('login.password')}</label>
					<div class="relative">
						<input
							id="password"
							type={showPassword ? 'text' : 'password'}
							bind:value={password}
							required
							autocomplete="current-password"
							class="w-full rounded-lg border border-[var(--border-input)] bg-[var(--surface-input)] px-3 py-2.5 pr-14 text-sm text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:border-[var(--color-brand-500)] focus:outline-none focus:ring-2 focus:ring-[var(--color-brand-500)]"
						/>
						<button
							type="button"
							class="absolute right-3 top-1/2 -translate-y-1/2 text-xs font-medium text-[var(--text-tertiary)] hover:text-[var(--text-secondary)] transition-colors"
							onclick={() => { showPassword = !showPassword; }}
						>
							{showPassword ? 'Hide' : 'Show'}
						</button>
					</div>
				</div>

				<button
					type="submit"
					disabled={loading}
					class="w-full inline-flex items-center justify-center gap-2 rounded-lg bg-[var(--color-brand-600)] px-4 py-2.5 text-sm font-medium text-white shadow-sm transition-all duration-150 hover:bg-[var(--color-brand-700)] focus:outline-none focus:ring-2 focus:ring-[var(--color-brand-500)] focus:ring-offset-2 disabled:opacity-50 active:animate-press"
				>
					{#if loading}
						<IconLoader size={16} />
						{$t('login.signingIn')}
					{:else}
						{$t('login.signIn')}
					{/if}
				</button>
			</form>

			{#if authMode === 'oidc'}
			<div class="mt-5">
				<div class="relative">
					<div class="absolute inset-0 flex items-center">
						<div class="w-full border-t border-[var(--border-primary)]"></div>
					</div>
					<div class="relative flex justify-center text-xs">
						<span class="bg-[var(--surface-card)] px-3 text-[var(--text-tertiary)]">{$t('login.or')}</span>
					</div>
				</div>

				<button
					onclick={handleOIDCLogin}
					class="mt-4 w-full rounded-lg border border-[var(--border-primary)] bg-[var(--surface-card)] px-4 py-2.5 text-sm font-medium text-[var(--text-secondary)] shadow-sm transition-all duration-150 hover:bg-[var(--surface-card-hover)] focus:outline-none focus:ring-2 focus:ring-[var(--color-brand-500)] focus:ring-offset-2"
				>
					{$t('login.ssoButton')}
				</button>
			</div>
			{/if}
		</div>
	</div>
</div>

<style>
	.login-shell {
		position: relative;
		display: flex;
		align-items: center;
		justify-content: center;
		min-height: 100vh;
		padding: 1rem;
		background: var(--surface-page);
		overflow: hidden;
		isolation: isolate;
	}

	/* ── FX layer sits behind the card ──────────────────────────── */
	.fx-layer {
		position: absolute;
		inset: 0;
		pointer-events: none;
		z-index: 0;
	}

	.login-card-wrap {
		position: relative;
		z-index: 1;
		width: 100%;
		max-width: 24rem;
	}
	.login-card {
		backdrop-filter: saturate(1.2);
		animation: card-rise 600ms cubic-bezier(0.22, 1, 0.36, 1) both;
	}
	@keyframes card-rise {
		from { opacity: 0; transform: translateY(12px) scale(0.985); }
		to { opacity: 1; transform: translateY(0) scale(1); }
	}

	/* ── Slowly rotating "forge glow" behind the card ──────────── */
	.fx-glow {
		position: absolute;
		top: 50%; left: 50%;
		width: 130vmin; height: 130vmin;
		transform: translate(-50%, -50%);
		background:
			conic-gradient(
				from 0deg at 50% 50%,
				transparent 0deg,
				color-mix(in srgb, var(--color-brand-500) 22%, transparent) 40deg,
				color-mix(in srgb, var(--color-brand-600) 28%, transparent) 80deg,
				transparent 140deg,
				transparent 220deg,
				color-mix(in srgb, var(--color-brand-400) 18%, transparent) 280deg,
				transparent 360deg
			);
		-webkit-mask-image: radial-gradient(circle at center, #000 0%, #000 28%, transparent 70%);
		mask-image: radial-gradient(circle at center, #000 0%, #000 28%, transparent 70%);
		filter: blur(40px);
		opacity: 0.9;
		animation: glow-spin 40s linear infinite;
	}
	@keyframes glow-spin {
		to { transform: translate(-50%, -50%) rotate(360deg); }
	}

	/* ── Dot-grid texture (matches the main app backdrop) ─────── */
	.fx-grid {
		position: absolute;
		inset: 0;
		background-image: radial-gradient(var(--border-primary) 1px, transparent 1px);
		background-size: 26px 26px;
		-webkit-mask-image: radial-gradient(ellipse at center, #000 0%, transparent 75%);
		mask-image: radial-gradient(ellipse at center, #000 0%, transparent 75%);
		opacity: 0.55;
	}

	/* ── Drifting embers — small dots rising from below ───────── */
	.fx-embers {
		position: absolute;
		inset: 0;
		overflow: hidden;
	}
	.fx-embers .ember {
		position: absolute;
		bottom: -16px;
		width: 4px; height: 4px;
		border-radius: 50%;
		background: var(--color-brand-500);
		box-shadow:
			0 0 6px color-mix(in srgb, var(--color-brand-500) 80%, transparent),
			0 0 14px color-mix(in srgb, var(--color-brand-400) 60%, transparent);
		opacity: 0;
		/* Each ember is placed in its own horizontal lane via --i.
		   Delay / duration / scale are varied below with nth-child for a natural feel. */
		left: calc((var(--i) * 4.1%) + 2%);
		animation: ember-rise 11s linear infinite;
		animation-delay: calc(var(--i) * -0.9s);
	}
	/* Duration variety (5 buckets) */
	.fx-embers .ember:nth-child(5n)   { animation-duration:  9s; }
	.fx-embers .ember:nth-child(5n+1) { animation-duration: 11s; }
	.fx-embers .ember:nth-child(5n+2) { animation-duration: 13s; }
	.fx-embers .ember:nth-child(5n+3) { animation-duration: 15s; }
	.fx-embers .ember:nth-child(5n+4) { animation-duration: 17s; }
	/* Size variety (3 buckets) */
	.fx-embers .ember:nth-child(3n)   { transform: scale(0.7); }
	.fx-embers .ember:nth-child(3n+1) { transform: scale(1);   width: 5px; height: 5px; }
	.fx-embers .ember:nth-child(3n+2) { transform: scale(0.5); }
	/* Horizontal drift variety (2 buckets) */
	.fx-embers .ember:nth-child(even) { --drift: 22px; }
	.fx-embers .ember:nth-child(odd)  { --drift: -18px; }

	@keyframes ember-rise {
		0% {
			opacity: 0;
			transform: translate3d(0, 0, 0);
		}
		10% { opacity: 0.9; }
		50% {
			transform: translate3d(calc(var(--drift, 0px) * 0.5), -55vh, 0);
		}
		90% { opacity: 0.4; }
		100% {
			opacity: 0;
			transform: translate3d(var(--drift, 0px), -110vh, 0);
		}
	}

	/* ── Soft vignette keeps the center where the eye lands ───── */
	.fx-vignette {
		position: absolute;
		inset: 0;
		background: radial-gradient(
			ellipse at center,
			transparent 0%,
			transparent 40%,
			color-mix(in srgb, var(--surface-page) 55%, transparent) 80%,
			var(--surface-page) 100%
		);
	}

	/* ── Dark mode: richer glow, cooler cast ──────────────────── */
	:global([data-theme='dark']) .fx-glow { opacity: 0.7; filter: blur(56px); }
	:global([data-theme='dark']) .fx-grid { opacity: 0.35; }
	:global([data-theme='dark']) .fx-embers .ember {
		background: var(--color-brand-400);
		box-shadow:
			0 0 8px color-mix(in srgb, var(--color-brand-400) 90%, transparent),
			0 0 18px color-mix(in srgb, var(--color-brand-500) 60%, transparent);
	}

	@media (prefers-reduced-motion: reduce) {
		.login-card,
		.fx-glow,
		.fx-embers .ember {
			animation: none !important;
		}
		.fx-embers .ember { opacity: 0.35; }
	}
</style>
