<script lang="ts">
	import { onMount } from 'svelte';
	import { getSupabase } from '$lib/supabase';
	import { currentUser } from '$lib/stores/auth';
	import { logout } from '$lib/auth';
	import Avatar from '$lib/components/Avatar.svelte';
	import ImageCropper from '$lib/components/ImageCropper.svelte';
	import { languageTag, setLanguageTag } from '$lib/paraglide/runtime';
	import * as m from '$lib/paraglide/messages';
	import {
		PUBLIC_KEYCLOAK_URL,
		PUBLIC_KEYCLOAK_REALM
	} from '$env/static/public';

	// Profile state loaded from public.users
	let displayNameInput = $state('');
	let language = $state<'en' | 'es'>('en');
	let avatarType = $state<'initials' | 'emoji' | 'upload'>('initials');
	let avatarEmoji = $state<string | null>(null);
	let avatarUrl = $state<string | null>(null);

	let saving = $state(false);
	let saved = $state(false);
	let debounceTimer: ReturnType<typeof setTimeout>;

	// Cropper
	let cropperFile = $state<File | null>(null);
	let uploading = $state(false);

	const EMOJI_GRID = [
		'😀','😎','🥳','🤓','👻','🐱','🐶','🦊',
		'🐸','🦁','🐻','🐼','🐨','🐯','🦄','🐧',
		'🦋','🌈','⭐','🌙','☀️','🌊','🌴','🌺',
		'🍕','🍦','🎸','🎯','🚀','⚽','🎮','🎨'
	];

	const keycloakAccountUrl = `${PUBLIC_KEYCLOAK_URL}/realms/${PUBLIC_KEYCLOAK_REALM}/account`;

	onMount(async () => {
		await loadProfile();
	});

	async function loadProfile() {
		if (!$currentUser) return;

		const { data } = await getSupabase()
			.from('users')
			.select('display_name, language, avatar_type, avatar_emoji, avatar_url')
			.eq('id', $currentUser.id)
			.single();

		if (data) {
			displayNameInput = data.display_name;
			language = data.language as 'en' | 'es';
			avatarType = data.avatar_type as 'initials' | 'emoji' | 'upload';
			avatarEmoji = data.avatar_emoji;
			avatarUrl = data.avatar_url;
		}
	}

	function scheduleNameSave() {
		clearTimeout(debounceTimer);
		debounceTimer = setTimeout(saveName, 700);
	}

	async function saveName() {
		if (!$currentUser) return;
		saving = true;
		await getSupabase()
			.from('users')
			.update({ display_name: displayNameInput.trim() })
			.eq('id', $currentUser.id);
		saving = false;
		saved = true;
		setTimeout(() => (saved = false), 2000);
	}

	async function selectEmojiAvatar(emoji: string) {
		avatarEmoji = emoji;
		avatarType = 'emoji';
		await getSupabase()
			.from('users')
			.update({ avatar_type: 'emoji', avatar_emoji: emoji })
			.eq('id', $currentUser!.id);
	}

	async function selectInitialsAvatar() {
		avatarType = 'initials';
		await getSupabase()
			.from('users')
			.update({ avatar_type: 'initials', avatar_emoji: null })
			.eq('id', $currentUser!.id);
	}

	function onFileInput(e: Event) {
		const input = e.currentTarget as HTMLInputElement;
		const file = input.files?.[0];
		if (file) cropperFile = file;
		input.value = '';
	}

	async function onCrop(blob: Blob) {
		cropperFile = null;
		if (!$currentUser) return;
		uploading = true;

		const path = `${$currentUser.id}/avatar.webp`;
		const { error: uploadError } = await getSupabase()
			.storage
			.from('avatars')
			.upload(path, blob, { upsert: true, contentType: 'image/webp' });

		if (uploadError) {
			uploading = false;
			return;
		}

		const { data: urlData } = await getSupabase()
			.storage
			.from('avatars')
			.createSignedUrl(path, 60 * 60 * 24 * 7); // 7 days

		const signedUrl = urlData?.signedUrl ?? null;

		await getSupabase()
			.from('users')
			.update({ avatar_type: 'upload', avatar_url: signedUrl })
			.eq('id', $currentUser.id);

		avatarType = 'upload';
		avatarUrl = signedUrl;
		uploading = false;
	}

	async function switchLanguage(lang: 'en' | 'es') {
		language = lang;
		setLanguageTag(lang);
		await getSupabase()
			.from('users')
			.update({ language: lang })
			.eq('id', $currentUser!.id);
	}
</script>

<div class="flex flex-1 flex-col overflow-hidden">
	<header class="px-8 pb-4 pt-8">
		<p class="mb-1 text-[13px] font-semibold uppercase tracking-[0.05em] text-text-secondary">
			{m.nav_settings()}
		</p>
		<h1 class="text-[20px] font-semibold tracking-[-0.01em] text-slate-900 dark:text-slate-50">
			{m.settings_title()}
		</h1>
	</header>

	<div class="flex-1 overflow-y-auto px-8 py-6">
		<div class="mx-auto max-w-md space-y-8">

			<!-- Avatar preview -->
			<div class="flex justify-center">
				<Avatar
					name={displayNameInput || $currentUser?.email || ''}
					type={avatarType}
					emoji={avatarEmoji}
					src={avatarUrl}
					size={80}
				/>
			</div>

			<!-- Display name -->
			<section>
				<label for="display-name" class="mb-1 block text-[13px] font-semibold uppercase tracking-[0.05em] text-text-secondary">
					{m.settings_display_name()}
				</label>
				<div class="relative">
					<input id="display-name"
						type="text"
						bind:value={displayNameInput}
						oninput={scheduleNameSave}
						maxlength="60"
						class="w-full rounded-lg border border-slate-300 bg-surface px-3 py-2 text-sm
							focus:border-slate-500 focus:outline-none dark:border-slate-600 dark:bg-slate-800"
					/>
					{#if saving}
						<span class="absolute right-3 top-2 text-xs text-text-secondary">{m.settings_saving()}</span>
					{:else if saved}
						<span class="absolute right-3 top-2 text-xs text-emerald-600">✓</span>
					{/if}
				</div>
			</section>

			<!-- Avatar -->
			<section>
				<p class="mb-3 text-[13px] font-semibold uppercase tracking-[0.05em] text-text-secondary">
					{m.settings_avatar()}
				</p>

				<!-- Mode tabs -->
				<div class="mb-4 flex gap-2">
					{#each [['initials', m.settings_avatar_initials()], ['emoji', m.settings_avatar_emoji()], ['upload', m.settings_avatar_upload()]] as [mode, label]}
						<button
							onclick={() => mode === 'initials' ? selectInitialsAvatar() : avatarType = mode as typeof avatarType}
							class="rounded-md px-3 py-1.5 text-xs font-medium transition-colors
								{avatarType === mode
								? 'bg-slate-900 text-white dark:bg-slate-50 dark:text-slate-900'
								: 'border border-slate-300 text-slate-600 hover:bg-slate-50 dark:border-slate-600 dark:text-slate-400'}"
						>
							{label}
						</button>
					{/each}
				</div>

				{#if avatarType === 'emoji'}
					<div class="grid grid-cols-8 gap-1">
						{#each EMOJI_GRID as e}
							<button
								onclick={() => selectEmojiAvatar(e)}
								class="flex h-9 w-9 items-center justify-center rounded-md text-xl
									{avatarEmoji === e ? 'bg-slate-900 dark:bg-slate-100' : 'hover:bg-slate-100 dark:hover:bg-slate-700'}"
								aria-label={e}
							>{e}</button>
						{/each}
					</div>
				{:else if avatarType === 'upload'}
					<label
						class="flex cursor-pointer items-center gap-2 rounded-lg border border-dashed
							border-slate-300 px-4 py-3 text-sm text-slate-600 hover:border-slate-500
							dark:border-slate-600 dark:text-slate-400"
					>
						<span>{uploading ? m.loading() : m.settings_avatar_upload_btn()}</span>
						<input type="file" accept="image/*" class="hidden" onchange={onFileInput} />
					</label>
				{/if}
			</section>

			<!-- Language -->
			<section>
				<p class="mb-3 text-[13px] font-semibold uppercase tracking-[0.05em] text-text-secondary">
					{m.settings_language()}
				</p>
				<div class="flex gap-2">
					{#each [['en', 'English'], ['es', 'Español']] as [code, label]}
						<button
							onclick={() => switchLanguage(code as 'en' | 'es')}
							class="rounded-md px-4 py-2 text-sm font-medium transition-colors
								{language === code
								? 'bg-slate-900 text-white dark:bg-slate-50 dark:text-slate-900'
								: 'border border-slate-300 text-slate-600 hover:bg-slate-50 dark:border-slate-600 dark:text-slate-400'}"
						>
							{label}
						</button>
					{/each}
				</div>
			</section>

			<!-- Account — spacing creates the separation, not a border line -->
			<section class="pt-8">
				<p class="mb-3 text-[13px] font-semibold uppercase tracking-[0.05em] text-text-secondary">
					{m.settings_account()}
				</p>
				<a
					href={keycloakAccountUrl}
					target="_blank"
					rel="noopener noreferrer"
					class="mb-3 flex items-center gap-2 text-sm text-slate-600 underline dark:text-slate-400"
				>
					{m.settings_keycloak_link()} ↗
				</a>
				<button
					onclick={logout}
					class="rounded-md bg-destructive px-4 py-2 text-sm font-semibold text-white hover:opacity-90"
				>
					{m.settings_logout()}
				</button>
			</section>
		</div>
	</div>
</div>

{#if cropperFile}
	<ImageCropper
		file={cropperFile}
		{onCrop}
		onCancel={() => (cropperFile = null)}
	/>
{/if}
