<!--
	Anki-Import-UI: Datei wählen → Preview → Importieren → Done.

	STRATEGIE-B-AUSNAHME: portiert aus
	mana-monorepo/apps/cards/apps/web/src/lib/components/AnkiImport.svelte.
	Original-Layout angepasst auf das oklch-Theme im neuen Repo
	(var(--color-*)) und auf den server-authoritative Import-Pfad
	ohne Media-Upload-Stage. Cloze-Skipped-Anzeige ergänzt — der neue
	Importer reicht Cloze direkt durch.
-->
<script lang="ts">
	import { parseApkg, type ParsedAnki } from '$lib/anki/parse.ts';
	import { importParsedAnki, type ImportResult, type ImportProgress } from '$lib/anki/import.ts';
	import { t, tn } from '$lib/i18n/index.svelte.ts';

	let fileInput = $state<HTMLInputElement | null>(null);
	let stage = $state<'idle' | 'parsing' | 'preview' | 'importing' | 'done' | 'error'>('idle');
	let parsed = $state<ParsedAnki | null>(null);
	let result = $state<ImportResult | null>(null);
	let error = $state<string | null>(null);
	let fileName = $state<string>('');
	let progress = $state<ImportProgress>({ stage: 'decks', current: 0, total: 0 });

	const typeBreakdown = $derived.by(() => {
		if (!parsed) return { basic: 0, basicReverse: 0, cloze: 0 };
		const counts = { basic: 0, basicReverse: 0, cloze: 0 };
		for (const c of parsed.cards) {
			if (c.type === 'basic') counts.basic++;
			else if (c.type === 'basic-reverse') counts.basicReverse++;
			else if (c.type === 'cloze') counts.cloze++;
		}
		return counts;
	});

	async function handleFile(file: File) {
		error = null;
		fileName = file.name;
		stage = 'parsing';
		try {
			parsed = await parseApkg(file);
			stage = 'preview';
		} catch (e: unknown) {
			error = e instanceof Error ? e.message : t('import.error_label', { msg: '?' });
			stage = 'error';
		}
	}

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

	function onDrop(e: DragEvent) {
		e.preventDefault();
		const f = e.dataTransfer?.files?.[0];
		if (f) handleFile(f);
	}

	async function confirmImport() {
		if (!parsed) return;
		stage = 'importing';
		progress = { stage: 'decks', current: 0, total: parsed.decks.length };
		try {
			result = await importParsedAnki(parsed, {
				onProgress: (p) => {
					progress = p;
				},
			});
			stage = 'done';
		} catch (e: unknown) {
			error = e instanceof Error ? e.message : t('import.error_label', { msg: '?' });
			stage = 'error';
		}
	}

	function reset() {
		stage = 'idle';
		parsed = null;
		result = null;
		error = null;
		fileName = '';
	}
</script>

<div class="rounded-xl border border-[hsl(var(--color-border))] bg-[hsl(var(--color-card))] p-4">
	<div class="mb-2 text-sm font-medium">{t('import.anki_label')}</div>

	{#if stage === 'idle'}
		<!-- svelte-ignore a11y_no_static_element_interactions -->
		<!-- svelte-ignore a11y_click_events_have_key_events -->
		<div
			class="cursor-pointer rounded-lg border-2 border-dashed border-[hsl(var(--color-border))] px-4 py-6 text-center text-sm text-[hsl(var(--color-muted-foreground))] transition-colors hover:border-[hsl(var(--color-primary))] hover:text-[hsl(var(--color-foreground))]"
			ondragover={(e) => e.preventDefault()}
			ondrop={onDrop}
			onclick={() => fileInput?.click()}
			role="button"
			tabindex="0"
			onkeydown={(e) => {
				if (e.key === 'Enter' || e.key === ' ') {
					e.preventDefault();
					fileInput?.click();
				}
			}}
		>
			<div class="mb-1">{t('import.dropzone')}</div>
			<div class="text-xs">{t('import.dropzone_hint')}</div>
		</div>
		<input
			bind:this={fileInput}
			type="file"
			accept=".apkg,.colpkg"
			class="hidden"
			onchange={onPick}
		/>
	{:else if stage === 'parsing'}
		<div class="py-6 text-center text-sm text-[hsl(var(--color-muted-foreground))]" aria-live="polite">
			{t('import.parsing', { file: fileName })}
		</div>
	{:else if stage === 'preview' && parsed}
		<div class="space-y-2 text-sm">
			<div>
				<span class="text-[hsl(var(--color-muted-foreground))]">{t('import.preview_found')}</span>
				<code class="rounded bg-[hsl(var(--color-border))]/40 px-1 text-xs">{fileName}</code>:
			</div>
			<ul class="ml-4 list-disc">
				<li>{tn('import.preview_decks', parsed.decks.length)}</li>
				<li>
					{tn('import.preview_cards', parsed.cards.length)}
					{#if parsed.cards.length > 0}
						<span class="text-[hsl(var(--color-muted-foreground))]">
							{t('import.preview_breakdown', {
								basic: typeBreakdown.basic,
								basic_reverse: typeBreakdown.basicReverse,
								cloze: typeBreakdown.cloze,
							})}
						</span>
					{/if}
				</li>
				{#if parsed.mediaByFilename.size > 0}
					<li class="text-[hsl(var(--color-muted-foreground))]">
						{t('import.preview_media', { n: parsed.mediaByFilename.size })}
					</li>
				{/if}
				{#if parsed.skipped > 0}
					<li>{t('import.preview_skipped', { n: parsed.skipped })}</li>
				{/if}
			</ul>
			{#if parsed.warnings.length > 0}
				<details class="text-xs text-[hsl(var(--color-muted-foreground))]">
					<summary class="cursor-pointer">{t('import.preview_warnings', { n: parsed.warnings.length })}</summary>
					<ul class="mt-1 list-disc pl-4">
						{#each parsed.warnings.slice(0, 10) as w (w)}<li>{w}</li>{/each}
					</ul>
				</details>
			{/if}
			<div class="flex justify-end gap-2 pt-2">
				<button
					class="rounded px-3 py-1.5 text-sm text-[hsl(var(--color-muted-foreground))] hover:text-[hsl(var(--color-foreground))]"
					onclick={reset}
				>
					{t('import.cancel')}
				</button>
				<button
					class="rounded bg-[hsl(var(--color-primary))] px-4 py-1.5 text-sm text-[hsl(var(--color-primary-foreground))] hover:opacity-90"
					onclick={confirmImport}
				>
					{t('import.import_now')}
				</button>
			</div>
		</div>
	{:else if stage === 'importing'}
		<div class="py-6 text-center text-sm text-[hsl(var(--color-muted-foreground))]" aria-live="polite">
			{#if progress.stage === 'media'}
				{t('import.stage_media', { current: progress.current, total: progress.total })}
			{:else if progress.stage === 'decks'}
				{t('import.stage_decks', { current: progress.current, total: progress.total })}
			{:else if progress.stage === 'cards'}
				{t('import.stage_cards', { current: progress.current, total: progress.total })}
			{:else}
				{t('import.stage_done')}
			{/if}
			<div
				class="mx-auto mt-3 h-1 w-48 overflow-hidden rounded-full bg-[hsl(var(--color-border))]/40"
				role="progressbar"
				aria-valuemin="0"
				aria-valuemax={progress.total}
				aria-valuenow={progress.current}
			>
				<div
					class="h-full bg-[hsl(var(--color-primary))] transition-all"
					style="width: {progress.total === 0 ? 0 : (progress.current / progress.total) * 100}%"
				></div>
			</div>
		</div>
	{:else if stage === 'done' && result}
		<div class="space-y-2 text-sm">
			<div class="text-[hsl(var(--color-success))]">
				{result.decksCreated === 1
					? t('import.done_summary_one', { cards: result.cardsCreated })
					: t('import.done_summary', { cards: result.cardsCreated, decks: result.decksCreated })}
			</div>
			{#if result.cardsSkippedDuplicate > 0}
				<div class="text-[hsl(var(--color-muted-foreground))]">
					{t('import.done_dupes', { n: result.cardsSkippedDuplicate })}
				</div>
			{/if}
			{#if result.mediaUploaded > 0 || result.mediaFailed > 0}
				<div class="text-[hsl(var(--color-muted-foreground))]">
					{t('import.done_media', {
						uploaded: result.mediaUploaded,
						failed: result.mediaFailed,
					})}
				</div>
			{/if}
			{#if result.failed > 0}
				<details class="text-[hsl(var(--color-error))]">
					<summary class="cursor-pointer">{t('import.done_failures', { n: result.failed })}</summary>
					<ul class="mt-1 list-disc pl-4 text-xs">
						{#each result.failures.slice(0, 20) as msg (msg)}<li>{msg}</li>{/each}
					</ul>
				</details>
			{/if}
			<button
				class="rounded px-3 py-1.5 text-sm text-[hsl(var(--color-muted-foreground))] hover:text-[hsl(var(--color-foreground))]"
				onclick={reset}
			>
				{t('import.done_more')}
			</button>
		</div>
	{:else if stage === 'error'}
		<div class="space-y-2 text-sm" role="alert">
			<div class="text-[hsl(var(--color-error))]">{t('import.error_label', { msg: error ?? '?' })}</div>
			<button
				class="rounded px-3 py-1.5 text-sm text-[hsl(var(--color-muted-foreground))] hover:text-[hsl(var(--color-foreground))]"
				onclick={reset}
			>
				{t('import.retry')}
			</button>
		</div>
	{/if}
</div>
