<script lang="ts">
import { onMount } from 'svelte';
import DocumentTopBar from '$lib/components/DocumentTopBar.svelte';
import DocumentViewer from '$lib/components/DocumentViewer.svelte';
import TranscriptionEditView from '$lib/components/TranscriptionEditView.svelte';
import type { TranscriptionBlockData } from '$lib/types';

let { data } = $props();

const doc = $derived(data.document);
const canWrite = $derived(data.canWrite ?? false);
const currentUserId = $derived((data.user?.id as string | undefined) ?? null);

// ── File loading ──────────────────────────────────────────────────────────────

let fileUrl = $state('');
let isLoading = $state(false);
let fileError = $state('');

$effect(() => {
	if (doc?.id && doc?.filePath) {
		loadFile(doc.id);
	}
});

async function loadFile(id: string) {
	isLoading = true;
	fileError = '';
	fileUrl = '';

	try {
		const response = await fetch(`/api/documents/${id}/file`);

		if (!response.ok) {
			if (response.status === 401) throw new Error('Nicht eingeloggt');
			throw new Error('Fehler beim Laden der Datei');
		}

		const blob = await response.blob();
		fileUrl = URL.createObjectURL(blob);
	} catch (e) {
		console.error(e);
		fileError = 'Vorschau konnte nicht geladen werden.';
	} finally {
		isLoading = false;
	}
}

// ── Mode state ───────────────────────────────────────────────────────────────

let transcribeMode = $state(false);
let activeAnnotationId = $state<string | null>(null);

// ── Transcription blocks ─────────────────────────────────────────────────────

let transcriptionBlocks = $state<TranscriptionBlockData[]>([]);

const blockNumbers = $derived(
	Object.fromEntries(
		[...transcriptionBlocks]
			.sort((a, b) => a.sortOrder - b.sortOrder)
			.map((b, i) => [b.annotationId, i + 1])
	)
);

async function loadTranscriptionBlocks() {
	if (!doc?.id) return;
	try {
		const res = await fetch(`/api/documents/${doc.id}/transcription-blocks`);
		if (res.ok) {
			transcriptionBlocks = await res.json();
		}
	} catch (e) {
		console.error('Failed to load transcription blocks:', e);
	}
}

async function saveBlock(blockId: string, text: string) {
	const res = await fetch(`/api/documents/${doc.id}/transcription-blocks/${blockId}`, {
		method: 'PUT',
		headers: { 'Content-Type': 'application/json' },
		body: JSON.stringify({ text })
	});
	if (!res.ok) throw new Error('Save failed');
	const updated = await res.json();
	transcriptionBlocks = transcriptionBlocks.map((b) => (b.id === blockId ? updated : b));
}

async function deleteBlock(blockId: string) {
	const res = await fetch(`/api/documents/${doc.id}/transcription-blocks/${blockId}`, {
		method: 'DELETE'
	});
	if (!res.ok) throw new Error('Delete failed');
	transcriptionBlocks = transcriptionBlocks.filter((b) => b.id !== blockId);
}

async function createBlockFromDraw(rect: {
	x: number;
	y: number;
	width: number;
	height: number;
	pageNumber: number;
}) {
	try {
		const res = await fetch(`/api/documents/${doc.id}/transcription-blocks`, {
			method: 'POST',
			headers: { 'Content-Type': 'application/json' },
			body: JSON.stringify({
				pageNumber: rect.pageNumber,
				x: rect.x,
				y: rect.y,
				width: rect.width,
				height: rect.height,
				text: '',
				label: null
			})
		});
		if (res.ok) {
			const created = (await res.json()) as TranscriptionBlockData;
			transcriptionBlocks = [...transcriptionBlocks, created];
			activeAnnotationId = created.annotationId;
		}
	} catch (e) {
		console.error('Failed to create transcription block:', e);
	}
}

function handleBlockFocus(blockId: string) {
	const block = transcriptionBlocks.find((b) => b.id === blockId);
	if (block) {
		activeAnnotationId = block.annotationId;
	}
}

async function handleAnnotationClick(annotationId: string) {
	activeAnnotationId = annotationId;

	if (!transcribeMode) {
		transcribeMode = true;
		await loadTranscriptionBlocks();
	}

	// Wait for DOM to render the blocks, then scroll to the matching one
	requestAnimationFrame(() => {
		const block = transcriptionBlocks.find((b) => b.annotationId === annotationId);
		if (block) {
			const el = document.querySelector(`[data-block-id="${block.id}"]`);
			el?.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
		}
	});
}

// Load blocks when transcribe mode is entered
$effect(() => {
	if (transcribeMode) {
		loadTranscriptionBlocks();
	}
});

// ── Navigation / init ─────────────────────────────────────────────────────────

let navHeight = $state(0);

onMount(() => {
	navHeight = document.querySelector('header')?.getBoundingClientRect().height ?? 0;

	if (doc?.id) {
		localStorage.setItem(
			'familienarchiv.lastVisited',
			JSON.stringify({ id: doc.id, title: doc.title ?? '' })
		);
	}

	function onKeyDown(e: KeyboardEvent) {
		if (e.key === 'Escape' && transcribeMode) {
			transcribeMode = false;
		}
	}
	document.addEventListener('keydown', onKeyDown);
	return () => document.removeEventListener('keydown', onKeyDown);
});
</script>

<svelte:head>
	<title>{doc.title || doc.originalFilename || 'Dokument'}</title>
</svelte:head>

<div
	class="fixed right-0 bottom-0 left-0 z-40 flex flex-col overflow-hidden bg-surface"
	style="top: {navHeight}px"
	data-hydrated
>
	<DocumentTopBar
		doc={doc}
		canWrite={canWrite}
		fileUrl={fileUrl}
		bind:transcribeMode={transcribeMode}
	/>

	<div class="relative flex-1 overflow-hidden {transcribeMode ? 'flex flex-col md:flex-row' : ''}">
		<div
			class={transcribeMode ? 'relative min-h-[40vh] flex-1 overflow-hidden md:min-h-0' : 'absolute inset-0'}
		>
			<DocumentViewer
				doc={doc}
				fileUrl={fileUrl}
				isLoading={isLoading}
				error={fileError}
				transcribeMode={transcribeMode}
				blockNumbers={blockNumbers}
				bind:activeAnnotationId={activeAnnotationId}
				onAnnotationClick={handleAnnotationClick}
				onTranscriptionDraw={createBlockFromDraw}
			/>
		</div>

		{#if transcribeMode}
			<div
				class="shrink-0 border-t border-line md:w-[400px] md:border-t-0 md:border-l lg:w-[480px]"
			>
				<TranscriptionEditView
					documentId={doc.id}
					blocks={transcriptionBlocks}
					canComment={canWrite}
					currentUserId={currentUserId}
					activeAnnotationId={activeAnnotationId}
					onBlockFocus={handleBlockFocus}
					onSaveBlock={saveBlock}
					onDeleteBlock={deleteBlock}
				/>
			</div>
		{/if}
	</div>
</div>
