<script lang="ts">
	import { liveQuery } from 'dexie';
	import { db } from '$lib/db/schema';
	import { getOrCreateJournalTopic, createHistoryEntry, updateHistoryEntry, softDeleteHistoryEntry, createTopic, JOURNAL_TOPIC_ID } from '$lib/db/repositories';
	import { today } from '$lib/db/helpers';
	import { mention } from '$lib/actions/mention';
	import MarkdownEditor from './MarkdownEditor.svelte';
	import RenderedMarkdown from './RenderedMarkdown.svelte';
	import DateNavigator from './DateNavigator.svelte';
	import ConfirmDialog from './ConfirmDialog.svelte';
	import WiedervorlageSection from './WiedervorlageSection.svelte';
	import LinkTitle from './LinkTitle.svelte';
	import { get } from 'svelte/store';
	import { currentScope, scopeSettings } from '$lib/stores/scopeContext';
	import { normalizeTitleAndBody, extractTitleAndBody } from '$lib/utils/titleUtils';
	import { useUnsavedGuard } from '$lib/utils/unsavedGuard.svelte';
	import EventCard from './EventCard.svelte';
	import { eventsForDate } from '$lib/stores/agenda';
	import { createEvent, updateEventNotes, upsertContext } from '$lib/db/repositories';
	import { fetchCalendarEvents, type CalendarEvent } from '$lib/utils/calendarApi';
	import { extractMentionName, quoteMention } from '$lib/actions/mentionCore';
	import type { PersonMeta } from '@ka-note/shared';

	interface Props {
		contextId: string;
		journalScope?: 'business' | 'private';
		initialDate?: string;
	}
	let { contextId, journalScope = 'business', initialDate }: Props = $props();

	$effect(() => { currentScope.set(journalScope); });

	const isDailyLog = $derived(contextId === 'daily-log');

	// --- Daily-log journal mode ---
	let entryText = $state('');
	let entryEditor: MarkdownEditor;
	let selectedDate = $state(initialDate ?? today());
	let selectedLinkedContextId = $state('');
	let wiedervorlageChecked = $state(true);
	let meetingPickerOpen = $state(false);

	useUnsavedGuard(() => entryText.trim() !== '' || editingId !== null);

	// All meeting contexts for the link dropdown
	const meetingContexts = liveQuery(() =>
		db.contexts
			.filter(c => !c.deletedAt && c.type === 'meeting' && c.id !== 'daily-log')
			.sortBy('sortOrder')
	);

	// All journal entries (daily-log mode)
	const journalEntries = liveQuery(async () => {
		if (!isDailyLog) return [];
		const topic = await db.topics.get(JOURNAL_TOPIC_ID);
		if (!topic) return [];
		return db.historyEntries
			.where('topicId').equals(JOURNAL_TOPIC_ID)
			.filter(h => !h.deletedAt)
			.toArray();
	});

	// Filter journal entries by selected date and scope
	const filteredEntries = $derived(
		($journalEntries ?? [])
			.filter(e => e.date === selectedDate && (journalScope === 'private' ? !!e.isPrivate : !e.isPrivate))
			.sort((a, b) => b.sortOrder - a.sortOrder)
	);

	// Context name lookup for linked entries
	const contextNameMap = $derived(() => {
		const map = new Map<string, string>();
		for (const ctx of $meetingContexts ?? []) {
			map.set(ctx.id, ctx.name);
		}
		return map;
	});

	async function resolveUrlTitle(url: string): Promise<string | null> {
		try {
			const res = await fetch(`/api/fetch-title?url=${encodeURIComponent(url)}`);
			const data = await res.json() as { title?: string };
			return data.title || null;
		} catch {
			return null;
		}
	}


	async function handleAddEntry() {
		const raw = entryText.trim();
		if (!raw) return;
		const { maxTitleLength } = get(scopeSettings);
		const extracted = extractTitleAndBody(raw, maxTitleLength);
		let title = extracted.title;
		let body = extracted.body;

		// If title is a URL, try to fetch its page title
		if (/^https?:\/\//i.test(title)) {
			const fetched = await resolveUrlTitle(title);
			if (fetched) {
				body = body ? `[${title}](${title})\n${body}` : `[${title}](${title})`;
				title = fetched;
			}
		}

		const isPrivate = journalScope === 'private';
		if (selectedLinkedContextId) {
			const topic = await createTopic(selectedLinkedContextId, title, isPrivate);
			if (body) {
				await createHistoryEntry(topic.id, selectedDate, body, null, false, isPrivate);
			}
		} else {
			const text = body ? `${title}\n\n${body}` : title;
			await getOrCreateJournalTopic();
			await createHistoryEntry(JOURNAL_TOPIC_ID, selectedDate, text, null, wiedervorlageChecked, isPrivate);
		}

		entryText = '';
		entryEditor?.clear();
		selectedLinkedContextId = '';
		meetingPickerOpen = false;
		wiedervorlageChecked = true;
	}

	let confirmDeleteId = $state<string | null>(null);

	// --- Edit mode ---
	let editingId = $state<string | null>(null);
	let editTitle = $state('');
	let editBody = $state('');
	let editIsPrivate = $state(false);
	let editDate = $state('');

	function startEdit(entry: { id: string; text: string; date: string; isPrivate?: boolean }) {
		const lines = entry.text.split('\n');
		editingId = entry.id;
		editTitle = lines[0].replace(/^#{1,6}\s+/, '');
		editBody = lines.slice(1).join('\n').trim();
		editIsPrivate = !!entry.isPrivate;
		editDate = entry.date;
	}

	function cancelEdit() {
		editingId = null;
	}

	async function saveEdit() {
		if (!editingId || !editTitle.trim()) return;
		const text = editBody.trim() ? `${editTitle.trim()}\n${editBody.trim()}` : editTitle.trim();
		await updateHistoryEntry(editingId, text, editIsPrivate, editDate || undefined);
		editingId = null;
	}

	async function handleDelete(id: string) {
		confirmDeleteId = id;
	}

	async function confirmDelete() {
		if (confirmDeleteId) await softDeleteHistoryEntry(confirmDeleteId);
		confirmDeleteId = null;
	}

	function formatTime(entry: { sortOrder: number; updatedAt: string }): string {
		try {
			// sortOrder >= 1e12 means it was set as Date.now() (ms timestamp) → use as creation time
			const ts = entry.sortOrder >= 1_000_000_000_000
				? new Date(entry.sortOrder)
				: new Date(entry.updatedAt);
			return ts.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' });
		} catch {
			return '';
		}
	}

	// --- Meeting journal mode ---
	const meetingEntries = liveQuery(async () => {
		if (isDailyLog) return [];
		const topics = await db.topics
			.where('contextId').equals(contextId)
			.filter(t => !t.deletedAt)
			.toArray();
		const topicMap = new Map(topics.map(t => [t.id, t.title]));
		const history = await db.historyEntries
			.where('topicId').anyOf(topics.map(t => t.id))
			.filter(h => !h.deletedAt)
			.toArray();

		// Also fetch journal entries linked to this context
		const linked = await db.historyEntries
			.where('linkedContextId').equals(contextId)
			.filter(h => !h.deletedAt)
			.toArray();

		const all = [
			...history.map(h => ({ ...h, topicTitle: topicMap.get(h.topicId) ?? '', isLinked: false })),
			...linked.map(h => ({ ...h, topicTitle: 'Journal', isLinked: true }))
		];
		return all.sort((a, b) => b.date.localeCompare(a.date));
	});

	const meetingByDate = $derived(() => {
		const groups = new Map<string, typeof $meetingEntries>();
		for (const entry of $meetingEntries ?? []) {
			const existing = groups.get(entry.date) ?? [];
			existing.push(entry);
			groups.set(entry.date, existing);
		}
		return [...groups.entries()].sort(([a], [b]) => b.localeCompare(a));
	});

	// --- Events (one-off meetings) ---
	let showNewEventForm = $state(false);
	let newEventTitle = $state('');
	let newEventTime = $state('');
	let newEventParticipants = $state('');
	let pendingBodyPreview = $state('');

	// Calendar picker
	let calendarPickerOpen = $state(false);
	let calendarLoading = $state(false);
	let calendarError = $state<string | null>(null);
	let calendarEvents = $state<CalendarEvent[]>([]);

	// Unknown-persons dialog (shown after calendar import)
	interface UnknownAttendee { name: string; email: string; selected: boolean; }
	let unknownDialogOpen = $state(false);
	let unknownAttendees = $state<UnknownAttendee[]>([]);

	async function openCalendarPicker() {
		if (!showNewEventForm) openNewEventForm();
		calendarLoading = true;
		calendarError = null;
		calendarPickerOpen = true;
		calendarEvents = [];
		try {
			calendarEvents = await fetchCalendarEvents(selectedDate);
		} catch {
			calendarError = 'Kalender nicht verfügbar';
		} finally {
			calendarLoading = false;
		}
	}

	async function selectCalendarEvent(ev: CalendarEvent) {
		newEventTitle = ev.subject;
		newEventTime = ev.start;
		pendingBodyPreview = ev.body;
		calendarPickerOpen = false;

		const persons = await db.contexts
			.filter(c => !c.deletedAt && c.type === 'person')
			.toArray();

		const mentions: string[] = [];
		const unknowns: UnknownAttendee[] = [];

		for (const att of ev.attendees) {
			const match = persons.find(
				p => (p.meta as PersonMeta | null)?.email?.toLowerCase() === att.email.toLowerCase()
			);
			if (match) {
				mentions.push(quoteMention('@', extractMentionName(match)));
			} else {
				const cleaned = att.name.replace(/\s*\(.*?\)\s*$/, '').trim();
				mentions.push(quoteMention('@', cleaned));
				if (att.email) unknowns.push({ name: cleaned, email: att.email, selected: true });
			}
		}

		newEventParticipants = mentions.join(' ');

		if (unknowns.length > 0) {
			unknownAttendees = unknowns;
			unknownDialogOpen = true;
		}
	}

	async function confirmUnknownPersons() {
		for (const u of unknownAttendees.filter(u => u.selected)) {
			const slug = u.name.toLowerCase().replace(/\s+/g, '-');
			await upsertContext({
				id: `u-${slug}`,
				name: `Person ${u.name}`,
				type: 'person',
				sortOrder: 99,
				meta: { fullName: u.name, email: u.email, phone: '', duSince: '' } satisfies PersonMeta,
			});
		}
		unknownDialogOpen = false;
	}

	const dateEvents = $derived(eventsForDate(selectedDate));

	function openNewEventForm() {
		const now = new Date();
		newEventTime = `${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;
		newEventTitle = '';
		newEventParticipants = '';
		showNewEventForm = true;
	}

	function parseEventParticipants(raw: string): string[] {
		const results: string[] = [];
		const re = /@"([^"]+)"|@([\w\-\u00C0-\u024F]+)/g;
		let m: RegExpExecArray | null;
		while ((m = re.exec(raw)) !== null) {
			results.push((m[1] ?? m[2]).trim());
		}
		return results.filter(Boolean);
	}

	async function handleCreateEvent() {
		const title = newEventTitle.trim();
		if (!title) return;
		const participants = parseEventParticipants(newEventParticipants);
		const event = await createEvent(selectedDate, newEventTime || '00:00', title, participants);
		if (pendingBodyPreview.trim()) {
			await updateEventNotes(event.id, pendingBodyPreview.trim());
		}
		newEventTitle = '';
		newEventTime = '';
		newEventParticipants = '';
		pendingBodyPreview = '';
		showNewEventForm = false;
	}

	// Birthday banner — filtered by scope
	const allPersons = liveQuery(() =>
		db.contexts.filter(c => !c.deletedAt && c.type === 'person').toArray()
	);
	const BUSINESS_SUBTYPES = new Set(['employee', 'colleague']);
	const PRIVATE_SUBTYPES = new Set(['family', 'acquaintance']);
	const birthdayPersons = $derived(
		($allPersons ?? []).filter(p => {
			const meta = p.meta as { birthday?: string; personSubType?: string } | null;
			const bd = meta?.birthday;
			if (!bd || bd.slice(5) !== selectedDate.slice(5)) return false;
			const sub = meta?.personSubType;
			if (journalScope === 'private') return !!sub && PRIVATE_SUBTYPES.has(sub);
			// business: employee/colleague/contact/undefined
			return !sub || !PRIVATE_SUBTYPES.has(sub);
		})
	);
</script>

{#if isDailyLog}
	<!-- Daily-log: chronological entry log with date navigation -->
	<DateNavigator {selectedDate} onchange={(d) => selectedDate = d} />

	{#if birthdayPersons.length > 0}
		<div class="mb-4 flex flex-wrap items-center gap-2 rounded-lg border border-[#d4a017] bg-[#2a1f00] px-4 py-3">
			<span class="text-lg">🎂</span>
			<span class="text-sm font-bold text-[#d4a017]">Geburtstag heute:</span>
			{#each birthdayPersons as p}
				<span class="rounded-full bg-[#d4a017]/20 px-2 py-0.5 text-sm text-[#f0c040]">{p.name}</span>
			{/each}
		</div>
	{/if}

	<div class="mb-8 flex flex-col gap-2.5 rounded-lg border border-border bg-sidebar p-4" class:hidden={editingId !== null}>
		<MarkdownEditor
			bind:this={entryEditor}
			placeholder="Was ist passiert? (1. Zeile = Titel)"
			minHeight="60px"
			wikiScope={journalScope === 'private'}
			onchange={(md) => entryText = md}
			onsave={handleAddEntry}
		/>
		<div class="flex items-center gap-2">
			<button
				class="rounded px-4 py-2 font-bold text-white hover:brightness-110"
				style="background-color: {journalScope === 'private' ? $scopeSettings.privateColor : $scopeSettings.businessColor}"
				onclick={handleAddEntry}
			>
				+ {selectedLinkedContextId ? 'Thema hinzufügen' : 'Notiz hinzufügen'}
			</button>
			{#if !selectedLinkedContextId}
				<button
					type="button"
					class="rounded border p-1.5 text-base leading-none transition-colors {wiedervorlageChecked ? 'border-amber-500 bg-amber-500/20 text-amber-400' : 'border-[#444] text-muted hover:border-[#666] hover:text-white'}"
					onclick={() => wiedervorlageChecked = !wiedervorlageChecked}
					title="Wiedervorlage"
				>{wiedervorlageChecked ? '⏰' : '○'}</button>
			{/if}
			<!-- Meeting picker button -->
			<div class="relative {journalScope === 'private' ? 'hidden' : ''}">
				<button
					type="button"
					class="flex items-center gap-1 rounded border px-2 py-1.5 text-sm transition-colors {selectedLinkedContextId ? 'border-accent bg-accent/20 text-accent' : 'border-[#444] bg-bg text-muted hover:text-white'}"
					onclick={() => meetingPickerOpen = !meetingPickerOpen}
					title="Jour-fix verknüpfen"
				>
					<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
						<rect x="3" y="4" width="18" height="18" rx="2" ry="2"/>
						<line x1="16" y1="2" x2="16" y2="6"/>
						<line x1="8" y1="2" x2="8" y2="6"/>
						<line x1="3" y1="10" x2="21" y2="10"/>
					</svg>
				</button>
				{#if meetingPickerOpen}
					<div class="absolute left-0 top-full z-50 mt-1 min-w-48 rounded border border-[#444] bg-[#1e1e1e] py-1 shadow-lg">
						<button
							class="w-full px-3 py-1.5 text-left text-sm text-muted hover:bg-[#2a2a2a] {!selectedLinkedContextId ? 'text-white' : ''}"
							onclick={() => { selectedLinkedContextId = ''; meetingPickerOpen = false; }}
						>— kein Jour-fix —</button>
						{#each $meetingContexts ?? [] as ctx}
							<button
								class="w-full px-3 py-1.5 text-left text-sm hover:bg-[#2a2a2a] {selectedLinkedContextId === ctx.id ? 'text-accent' : 'text-white'}"
								onclick={() => { selectedLinkedContextId = ctx.id; meetingPickerOpen = false; }}
							>{ctx.name}</button>
						{/each}
					</div>
				{/if}
			</div>
		</div>
	</div>

	<WiedervorlageSection date={selectedDate} {journalScope} />

	<!-- Events (one-off meetings) for selected date -->
	{#if journalScope === 'business'}
		<div class="mb-6">
			<div class="mb-2 flex items-center justify-between">
				<span class="text-sm font-semibold text-muted">Meetings</span>
				<button
					class="rounded px-2 py-1 text-sm text-muted hover:bg-[#2a2a2a] hover:text-white"
					onclick={openNewEventForm}
				>+ Meeting</button>
			</div>
			{#if showNewEventForm}
				<div class="mb-3 flex flex-col gap-2 rounded border border-[#333] bg-card-bg p-3">
					<input
						class="w-full rounded border border-[#444] bg-bg px-2 py-1 text-sm text-white placeholder-[#666]"
						type="text"
						bind:value={newEventTitle}
						placeholder="Titel *"
					/>
					<div class="flex gap-2">
						<input
							class="w-28 rounded border border-[#444] bg-bg px-2 py-1 text-sm text-white"
							type="time"
							bind:value={newEventTime}
						/>
						<div class="relative flex-1">
						<input
							class="w-full rounded border border-[#444] bg-bg px-2 py-1 text-sm text-white placeholder-[#666]"
							type="text"
							bind:value={newEventParticipants}
							placeholder="Teilnehmer (@Name, ...)"
							use:mention
						/>
					</div>
					</div>
					<div class="flex gap-2">
						<button
							class="rounded bg-accent px-3 py-1 text-sm font-bold text-white hover:brightness-110 disabled:opacity-50"
							onclick={handleCreateEvent}
							disabled={!newEventTitle.trim()}
						>Erstellen</button>
						<button
							class="rounded bg-[#444] px-3 py-1 text-sm text-white hover:bg-[#555]"
							onclick={() => (showNewEventForm = false)}
						>Abbrechen</button>
						<button
							type="button"
							class="ml-auto rounded border border-[#444] px-3 py-1 text-sm text-muted hover:border-[#666] hover:text-white"
							onclick={openCalendarPicker}
						>Aus Kalender</button>
					</div>
				</div>
				{#if calendarPickerOpen}
					<div class="mb-3 rounded border border-[#444] bg-[#1e1e1e] shadow-lg">
						{#if calendarLoading}
							<div class="px-3 py-2 text-sm text-muted">Lade...</div>
						{:else if calendarError}
							<div class="px-3 py-2 text-sm text-red-400">{calendarError}</div>
						{:else if calendarEvents.length === 0}
							<div class="px-3 py-2 text-sm text-muted">Keine Termine für diesen Tag</div>
						{:else}
							{#each calendarEvents as ev (ev.id)}
								<button
									class="w-full px-3 py-2 text-left text-sm hover:bg-[#2a2a2a]"
									onclick={() => selectCalendarEvent(ev)}
								>
									<span class="font-mono text-[#aaa]">{ev.start}</span>
									<span class="ml-2 text-white">{ev.subject}</span>
									{#if ev.attendees.length > 0}
										<span class="ml-2 text-xs text-muted">{ev.attendees.map(a => a.name).join(', ')}</span>
									{/if}
								</button>
							{/each}
						{/if}
						<button
							class="w-full border-t border-[#333] px-3 py-1.5 text-left text-xs text-muted hover:bg-[#2a2a2a]"
							onclick={() => (calendarPickerOpen = false)}
						>Schließen</button>
					</div>
				{/if}
			{/if}

			{#if unknownDialogOpen}
				<div class="mb-3 rounded border border-[#555] bg-[#1e1e1e] p-3 shadow-lg">
					<p class="mb-2 text-sm text-[#ccc]">Unbekannte Teilnehmer anlegen?</p>
					<div class="mb-3 flex flex-col gap-1.5">
						{#each unknownAttendees as u}
							<label class="flex cursor-pointer items-center gap-2 text-sm">
								<input type="checkbox" bind:checked={u.selected} class="accent-accent" />
								<span class="text-white">{u.name}</span>
								<span class="text-xs text-muted">{u.email}</span>
							</label>
						{/each}
					</div>
					<div class="flex gap-2">
						<button
							class="rounded bg-accent px-3 py-1 text-sm font-bold text-white hover:brightness-110"
							onclick={confirmUnknownPersons}
						>Anlegen</button>
						<button
							class="rounded bg-[#444] px-3 py-1 text-sm text-white hover:bg-[#555]"
							onclick={() => (unknownDialogOpen = false)}
						>Überspringen</button>
					</div>
				</div>
			{/if}

			{#each $dateEvents ?? [] as event (event.id)}
				<div class="mb-2">
					<EventCard {event} />
				</div>
			{/each}
		</div>
	{/if}

	{#if filteredEntries.length > 0}
		<div class="mb-8 border-l-2 border-[#555] pl-5">
			<div class="mb-4 text-xl font-bold text-accent">{selectedDate}</div>
			{#each filteredEntries as entry (entry.id)}
				{#if editingId === entry.id}
					<!-- svelte-ignore a11y_no_static_element_interactions -->
					<div class="mb-3 flex flex-col gap-2 rounded border border-accent bg-card-bg p-2.5" onkeydown={(e) => { if (e.key === 'Escape') cancelEdit(); }}>
						<div class="flex items-center gap-2 flex-wrap">
							<button
								class="rounded bg-accent px-3 py-1 text-sm font-bold text-white hover:brightness-110"
								onclick={saveEdit}
							>Speichern</button>
							<button
								class="rounded bg-[#444] px-3 py-1 text-sm text-white hover:bg-[#555]"
								onclick={cancelEdit}
							>Abbrechen</button>
							<input
								type="date"
								class="rounded border border-[#444] bg-bg px-2 py-1 text-sm text-white"
								bind:value={editDate}
								title="Datum des Eintrags"
							/>
							<div class="ml-auto flex gap-1 rounded-full bg-[#333] p-0.5">
								<button
									class="rounded-full px-2.5 py-1 text-xs font-bold transition-all {!editIsPrivate ? 'bg-accent text-white shadow' : 'text-[#aaa] hover:text-white'}"
									onclick={() => editIsPrivate = false}
								>Firma</button>
								<button
									class="rounded-full px-2.5 py-1 text-xs font-bold transition-all {editIsPrivate ? 'text-white shadow' : 'text-[#aaa] hover:text-white'}"
									style={editIsPrivate ? `background-color: ${$scopeSettings.privateColor}` : ''}
									onclick={() => editIsPrivate = true}
								>Privat</button>
							</div>
						</div>
												<input
							type="text"
							class="rounded border border-[#444] bg-bg px-2.5 py-1.5 font-mono text-white"
							bind:value={editTitle}
							use:mention
							onkeydown={(e) => { if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) { e.preventDefault(); saveEdit(); } }}
						/>
						<MarkdownEditor
							content={editBody}
							placeholder="Details"
							minHeight="60px"
							wikiScope={journalScope === 'private'}
							onchange={(md) => editBody = md}
							onsave={saveEdit}
						/>
						<div class="flex items-center gap-2 flex-wrap">
							<button
								class="rounded bg-accent px-3 py-1 text-sm font-bold text-white hover:brightness-110"
								onclick={saveEdit}
							>Speichern</button>
							<button
								class="rounded bg-[#444] px-3 py-1 text-sm text-white hover:bg-[#555]"
								onclick={cancelEdit}
							>Abbrechen</button>
							<input
								type="date"
								class="rounded border border-[#444] bg-bg px-2 py-1 text-sm text-white"
								bind:value={editDate}
								title="Datum des Eintrags"
							/>
							<div class="ml-auto flex gap-1 rounded-full bg-[#333] p-0.5">
								<button
									class="rounded-full px-2.5 py-1 text-xs font-bold transition-all {!editIsPrivate ? 'bg-accent text-white shadow' : 'text-[#aaa] hover:text-white'}"
									onclick={() => editIsPrivate = false}
								>Firma</button>
								<button
									class="rounded-full px-2.5 py-1 text-xs font-bold transition-all {editIsPrivate ? 'text-white shadow' : 'text-[#aaa] hover:text-white'}"
									style={editIsPrivate ? `background-color: ${$scopeSettings.privateColor}` : ''}
									onclick={() => editIsPrivate = true}
								>Privat</button>
							</div>
						</div>
					</div>
				{:else}
					{@const lines = entry.text.split('\n')}
					{@const title = lines[0].replace(/^#{1,6}\s+/, '')}
					{@const body = lines.slice(1).join('\n').trim()}
					<!-- svelte-ignore a11y_no_static_element_interactions -->
					<div class="group mb-3 flex items-start gap-2 rounded bg-card-bg p-2.5" ondblclick={() => startEdit(entry)}>
						<span class="mt-0.5 text-xs text-muted whitespace-nowrap">{formatTime(entry)}</span>
						<div class="flex-1">
							<div class="flex flex-wrap items-center gap-1.5 font-bold">
								<LinkTitle text={title} />
								{#if entry.wiedervorlageDate && !entry.wiedervorlageResolvedAt}
									<span class="text-base leading-none text-amber-400" title="In Wiedervorlage bis {entry.wiedervorlageDate}">⏰</span>
								{/if}
								{#if entry.linkedContextId}
									<span class="inline-block rounded bg-accent/20 px-1.5 py-0.5 text-xs font-normal text-accent">
										{contextNameMap().get(entry.linkedContextId) ?? entry.linkedContextId}
									</span>
								{/if}
							</div>
							{#if body}
								<RenderedMarkdown text={body} class="mt-1 text-sm text-[#ccc]" />
							{/if}
						</div>
						<button
							class="mt-0.5 text-xs text-[#666] opacity-0 transition-opacity group-hover:opacity-100 hover:text-[#ccc]"
							onclick={() => startEdit(entry)}
							title="Bearbeiten"
						>&#9998;</button>
						<button
							class="mt-0.5 text-xs text-[#666] opacity-0 transition-opacity group-hover:opacity-100 hover:text-red-400"
							onclick={() => handleDelete(entry.id)}
							title="Löschen"
						>&times;</button>
					</div>
				{/if}
			{/each}
		</div>
	{:else}
		<div class="text-center text-muted">Keine Einträge für {selectedDate}.</div>
	{/if}
{:else}
	<!-- Meeting contexts: topic history + linked journal entries -->
	{#each meetingByDate() as [date, items]}
		<div class="mb-8 border-l-2 border-[#555] pl-5">
			<div class="mb-4 text-xl font-bold text-accent">{date}</div>
			{#each items as entry}
				<div class="mb-4 rounded bg-card-bg p-2.5">
					<span class="mb-1 block text-xs uppercase tracking-wider text-muted">
						{entry.topicTitle}
						{#if entry.isLinked}
							<span class="ml-1 rounded bg-accent/20 px-1 py-0.5 normal-case text-accent">Journal</span>
						{/if}
					</span>
					<RenderedMarkdown text={entry.text} />
				</div>
			{/each}
		</div>
	{:else}
		<div class="text-center text-muted">Keine Einträge.</div>
	{/each}
{/if}

{#if confirmDeleteId}
	<ConfirmDialog
		message="Eintrag wirklich löschen?"
		onconfirm={confirmDelete}
		oncancel={() => confirmDeleteId = null}
	/>
{/if}
